SQLite4
Check-in [e5d82c92f0]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove the no longer required FuncDestructor object.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e5d82c92f092f99f8968ddd77c198b0cbb298ef7
User & Date: dan 2013-06-13 16:32:32
Context
2013-06-13
20:20
Remove the encoding argument from sqlite4_create_collation(). Pass sqlite4_value objects to the collation sequence callbacks instead. check-in: 7f314c9a71 user: dan tags: trunk
16:32
Remove the no longer required FuncDestructor object. check-in: e5d82c92f0 user: dan tags: trunk
15:24
Remove the 'encoding' argument from sqlite4_create_function(). check-in: f88d080127 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

   322    322     }
   323    323     db->nSavepoint = 0;
   324    324     db->nStatement = 0;
   325    325   }
   326    326   
   327    327   /*
   328    328   ** Invoke the destructor function associated with FuncDef p, if any. Except,
   329         -** if this is not the last copy of the function, do not invoke it. Multiple
   330         -** copies of a single function are created when create_function() is called
   331         -** with SQLITE4_ANY as the encoding.
          329  +** if this is not the last copy of the function, do not invoke it.
   332    330   */
   333    331   static void functionDestroy(sqlite4 *db, FuncDef *p){
   334         -  FuncDestructor *pDestructor = p->pDestructor;
   335         -  if( pDestructor ){
   336         -    pDestructor->nRef--;
   337         -    if( pDestructor->nRef==0 ){
   338         -      pDestructor->xDestroy(pDestructor->pUserData);
   339         -      sqlite4DbFree(db, pDestructor);
   340         -    }
          332  +  if( p->xDestroy ){
          333  +    p->xDestroy(p->pUserData);
   341    334     }
   342    335   }
   343    336   
   344    337   /*
   345    338   ** Close an existing SQLite database
   346    339   */
   347    340   int sqlite4_close(sqlite4 *db, unsigned int flags){
................................................................................
   542    535     sqlite4 *db,
   543    536     const char *zFunctionName,
   544    537     int nArg,
   545    538     void *pUserData,
   546    539     void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
   547    540     void (*xStep)(sqlite4_context*,int,sqlite4_value **),
   548    541     void (*xFinal)(sqlite4_context*),
   549         -  FuncDestructor *pDestructor
          542  +  void (*xDestroy)(void *)
   550    543   ){
   551    544     FuncDef *p;
   552    545     int nName;
   553    546   
   554    547     assert( sqlite4_mutex_held(db->mutex) );
   555    548     if( zFunctionName==0 ||
   556    549         (xFunc && (xFinal || xStep)) || 
................................................................................
   584    577       return SQLITE4_NOMEM;
   585    578     }
   586    579   
   587    580     /* If an older version of the function with a configured destructor is
   588    581     ** being replaced invoke the destructor function here. */
   589    582     functionDestroy(db, p);
   590    583   
   591         -  if( pDestructor ){
   592         -    pDestructor->nRef++;
   593         -  }
   594         -  p->pDestructor = pDestructor;
          584  +  p->xDestroy = xDestroy;
   595    585     p->flags = 0;
   596    586     p->xFunc = xFunc;
   597    587     p->xStep = xStep;
   598    588     p->xFinalize = xFinal;
   599    589     p->pUserData = pUserData;
   600    590     p->nArg = (u16)nArg;
   601    591     return SQLITE4_OK;
   602    592   }
   603    593   
   604         -/*
   605         -** This function is the same as sqlite4_create_function(), except that
   606         -** it does not grab the database handle mutex or call sqlite4ApiExit().
   607         -*/
   608         -static int createFunctionDestructor(
   609         -  sqlite4 *db,
   610         -  const char *zFunc,
   611         -  int nArg,
   612         -  void *p,
   613         -  void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
   614         -  void (*xStep)(sqlite4_context*,int,sqlite4_value **),
   615         -  void (*xFinal)(sqlite4_context*),
   616         -  void (*xDestroy)(void *)
   617         -){
   618         -  int rc;
   619         -  FuncDestructor *pArg = 0;
   620         -
   621         -  if( xDestroy ){
   622         -    pArg = (FuncDestructor *)sqlite4DbMallocZero(db, sizeof(FuncDestructor));
   623         -    if( !pArg ){
   624         -      xDestroy(p);
   625         -      return SQLITE4_NOMEM;
   626         -    }
   627         -    pArg->xDestroy = xDestroy;
   628         -    pArg->pUserData = p;
   629         -  }
   630         -  rc = sqlite4CreateFunc(db, zFunc, nArg, p, xFunc, xStep, xFinal, pArg);
   631         -  if( pArg && pArg->nRef==0 ){
   632         -    assert( rc!=SQLITE4_OK );
   633         -    xDestroy(p);
   634         -    sqlite4DbFree(db, pArg);
   635         -  }
   636         -
   637         -  return rc;
   638         -}
   639         -
   640    594   /*
   641    595   ** Create new user functions.
   642    596   */
   643    597   int sqlite4_create_function(
   644    598     sqlite4 *db,
   645    599     const char *zFunc,
   646    600     int nArg,
................................................................................
   648    602     void (*xFunc)(sqlite4_context*,int,sqlite4_value **),
   649    603     void (*xStep)(sqlite4_context*,int,sqlite4_value **),
   650    604     void (*xFinal)(sqlite4_context*),
   651    605     void (*xDestroy)(void *)
   652    606   ){
   653    607     int rc;
   654    608     sqlite4_mutex_enter(db->mutex);
   655         -  rc = createFunctionDestructor(
          609  +  rc = sqlite4CreateFunc(
   656    610         db, zFunc, nArg, p, xFunc, xStep, xFinal, xDestroy
   657    611     );
   658    612     rc = sqlite4ApiExit(db, rc);
          613  +  if( rc!=SQLITE4_OK && xDestroy ) xDestroy(p);
   659    614     sqlite4_mutex_leave(db->mutex);
   660    615     return rc;
   661    616   }
   662    617   
   663    618   int sqlite4_create_mi_function(
   664    619     sqlite4 *db,
   665    620     const char *zFunc,

Changes to src/pragma.c.

   197    197       void (*xFunc)(sqlite4_context *, int, sqlite4_value **);
   198    198       void (*xDestroy)(void *);
   199    199       void *pArg;
   200    200   
   201    201       rc = pKV->pStoreVfunc->xGetMethod(pKV, zPragma, &pArg, &xFunc, &xDestroy);
   202    202       if( rc==SQLITE4_OK ){
   203    203         FuncDef *pDef;
   204         -      int nByte;
   205    204         int r1 = 0;
   206    205         int regOut;               /* Result register */
   207    206   
   208    207         if( sqlite4AuthCheck(pParse, SQLITE4_PRAGMA, zPragma, 0, zDb) ){
   209    208           goto pragma_out;
   210    209         }
   211    210   
   212         -      nByte = sizeof(FuncDef) + sizeof(FuncDestructor);
   213         -      pDef = (FuncDef *)sqlite4DbMallocZero(db, nByte);
          211  +      pDef = (FuncDef *)sqlite4DbMallocZero(db, sizeof(FuncDef));
   214    212         if( !pDef ) goto pragma_out;
   215    213         pDef->flags = SQLITE4_FUNC_EPHEM;
   216    214         pDef->pUserData = pArg;
   217    215         pDef->xFunc = xFunc;
   218         -      pDef->pDestructor = (FuncDestructor *)&pDef[1];
   219         -      pDef->pDestructor->nRef = 1;
   220         -      pDef->pDestructor->xDestroy = xDestroy;
   221         -      pDef->pDestructor->pUserData = pArg;
          216  +      pDef->xDestroy = xDestroy;
   222    217   
   223    218         sqlite4VdbeSetNumCols(v, 1);
   224    219         sqlite4VdbeSetColName(v, 0, COLNAME_NAME, zPragma, SQLITE4_TRANSIENT);
   225    220   
   226    221         if( pList ){
   227    222           r1 = pParse->nMem+1;
   228    223           pParse->nMem += pList->nExpr;

Changes to src/resolve.c.

   576    576         int no_such_func = 0;       /* True if no such function exists */
   577    577         int wrong_num_args = 0;     /* True if wrong number of arguments */
   578    578         int is_agg = 0;             /* True if is an aggregate function */
   579    579         int auth;                   /* Authorization to use the function */
   580    580         int nId;                    /* Number of characters in function name */
   581    581         const char *zId;            /* The function name. */
   582    582         FuncDef *pDef;              /* Information about the function */
   583         -      u8 enc = ENC(pParse->db);   /* The database encoding */
   584    583   
   585    584         testcase( pExpr->op==TK_CONST_FUNC );
   586    585         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
   587    586         zId = pExpr->u.zToken;
   588    587         nId = sqlite4Strlen30(zId);
   589    588         pDef = sqlite4FindFunction(pParse->db, zId, nId, n, 0);
   590    589         if( pDef==0 ){

Changes to src/sqlite.h.in.

  2339   2339   ** These constant define integer codes that represent the various
  2340   2340   ** text encodings supported by SQLite.
  2341   2341   */
  2342   2342   #define SQLITE4_UTF8           1
  2343   2343   #define SQLITE4_UTF16LE        2
  2344   2344   #define SQLITE4_UTF16BE        3
  2345   2345   #define SQLITE4_UTF16          4    /* Use native byte order */
  2346         -#define SQLITE4_ANY            5    /* sqlite4_create_function only */
  2347   2346   #define SQLITE4_UTF16_ALIGNED  8    /* sqlite4_create_collation only */
  2348   2347   
  2349   2348   /*
  2350   2349   ** CAPIREF: Obtaining SQL Function Parameter Values
  2351   2350   **
  2352   2351   ** The C-language implementation of SQL functions and aggregates uses
  2353   2352   ** this set of interface routines to access the parameter values on

Changes to src/sqliteInt.h.

   566    566   typedef struct Db Db;
   567    567   typedef struct Schema Schema;
   568    568   typedef struct Expr Expr;
   569    569   typedef struct ExprList ExprList;
   570    570   typedef struct ExprListItem ExprListItem;
   571    571   typedef struct ExprSpan ExprSpan;
   572    572   typedef struct FKey FKey;
   573         -typedef struct FuncDestructor FuncDestructor;
   574    573   typedef struct FuncDef FuncDef;
   575    574   typedef struct FuncDefTable FuncDefTable;
   576    575   typedef struct Fts5Tokenizer Fts5Tokenizer;
   577    576   typedef struct Fts5Index Fts5Index;
   578    577   typedef struct Fts5Info Fts5Info;
   579    578   typedef struct Fts5Cursor Fts5Cursor;
   580    579   typedef struct IdList IdList;
................................................................................
   641    640   struct FuncDef {
   642    641     i16 nArg;            /* Number of arguments.  -1 means unlimited */
   643    642     u8 flags;            /* Some combination of SQLITE4_FUNC_* */
   644    643     void *pUserData;     /* User data parameter */
   645    644     FuncDef *pSameName;  /* Next with a different name but the same hash */
   646    645     void (*xFunc)(sqlite4_context*,int,sqlite4_value**); /* Regular function */
   647    646     void (*xStep)(sqlite4_context*,int,sqlite4_value**); /* Aggregate step */
   648         -  void (*xFinalize)(sqlite4_context*);                /* Aggregate finalizer */
          647  +  void (*xFinalize)(sqlite4_context*);                 /* Aggregate finalizer */
   649    648     char *zName;         /* SQL name of the function. */
   650    649     FuncDef *pNextName;  /* Next function with a different name */
   651         -  FuncDestructor *pDestructor;   /* Reference counted destructor function */
   652    650     u8 bMatchinfo;       /* True for matchinfo function */
          651  +  void (*xDestroy)(void *);       /* Users destructor function */
   653    652   };
   654    653   
   655    654   /*
   656    655   ** A table of SQL functions.  
   657    656   **
   658    657   ** The content is a linked list of FuncDef structures with branches.  When
   659    658   ** there are two or more FuncDef objects with the same name, they are 
................................................................................
   930    929   */
   931    930   #define SQLITE4_MAGIC_OPEN    0x4d06c919  /* Database is open */
   932    931   #define SQLITE4_MAGIC_CLOSED  0x5f2246b4  /* Database is closed */
   933    932   #define SQLITE4_MAGIC_SICK    0xcaad9e61  /* Error and awaiting close */
   934    933   #define SQLITE4_MAGIC_BUSY    0xb07f8c8c  /* Database currently in use */
   935    934   #define SQLITE4_MAGIC_ERROR   0x912e4c46  /* An SQLITE4_MISUSE error occurred */
   936    935   
   937         -/*
   938         -** This structure encapsulates a user-function destructor callback (as
   939         -** configured using create_function_v2()) and a reference counter. When
   940         -** create_function_v2() is called to create a function with a destructor,
   941         -** a single object of this type is allocated. FuncDestructor.nRef is set to 
   942         -** the number of FuncDef objects created (either 1 or 3, depending on whether
   943         -** or not the specified encoding is SQLITE4_ANY). The FuncDef.pDestructor
   944         -** member of each of the new FuncDef objects is set to point to the allocated
   945         -** FuncDestructor.
   946         -**
   947         -** Thereafter, when one of the FuncDef objects is deleted, the reference
   948         -** count on this object is decremented. When it reaches 0, the destructor
   949         -** is invoked and the FuncDestructor structure freed.
   950         -*/
   951         -struct FuncDestructor {
   952         -  int nRef;
   953         -  void (*xDestroy)(void *);
   954         -  void *pUserData;
   955         -};
   956         -
   957    936   /*
   958    937   ** Possible values for FuncDef.flags
   959    938   */
   960    939   #define SQLITE4_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
   961    940   #define SQLITE4_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
   962    941   #define SQLITE4_FUNC_EPHEM    0x04 /* Ephemeral.  Delete with VDBE */
   963    942   #define SQLITE4_FUNC_NEEDCOLL 0x08 /* sqlite4GetFuncCollSeq() might be called */
................................................................................
  3017   2996   void sqlite4SchemaClear(sqlite4_env*,Schema*);
  3018   2997   Schema *sqlite4SchemaGet(sqlite4*);
  3019   2998   int sqlite4SchemaToIndex(sqlite4 *db, Schema *);
  3020   2999   KeyInfo *sqlite4IndexKeyinfo(Parse *, Index *);
  3021   3000   int sqlite4CreateFunc(sqlite4 *, const char *, int, void *, 
  3022   3001     void (*)(sqlite4_context*,int,sqlite4_value **),
  3023   3002     void (*)(sqlite4_context*,int,sqlite4_value **), void (*)(sqlite4_context*),
  3024         -  FuncDestructor *pDestructor
         3003  +  void (*)(void *)
  3025   3004   );
  3026   3005   int sqlite4ApiExit(sqlite4 *db, int);
  3027   3006   int sqlite4OpenTempDatabase(Parse *);
  3028   3007   
  3029   3008   void sqlite4StrAccumInit(StrAccum*, char*, int, int);
  3030   3009   void sqlite4StrAccumAppend(StrAccum*,const char*,int);
  3031   3010   void sqlite4AppendSpace(StrAccum*,int);

Changes to src/vdbeaux.c.

   564    564   
   565    565   /*
   566    566   ** If the input FuncDef structure is ephemeral, then free it.  If
   567    567   ** the FuncDef is not ephermal, then do nothing.
   568    568   */
   569    569   static void freeEphemeralFunction(sqlite4 *db, FuncDef *pDef){
   570    570     if( ALWAYS(pDef) && (pDef->flags & SQLITE4_FUNC_EPHEM)!=0 ){
   571         -    if( pDef->pDestructor->xDestroy ){
   572         -      pDef->pDestructor->xDestroy(pDef->pDestructor->pUserData);
          571  +    if( pDef->xDestroy ){
          572  +      pDef->xDestroy(pDef->pUserData);
   573    573       }
   574    574       sqlite4DbFree(db, pDef);
   575    575     }
   576    576   }
   577    577   
   578    578   static void vdbeFreeOpArray(sqlite4 *, Op *, int);
   579    579   

Changes to test/func3.test.

    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   
    20     20   do_test func3-2.1 {
    21     21     set destroyed 0
    22     22     proc destroy {} { set ::destroyed 1 }
    23         -  sqlite4_create_function_v2 db f3 -1 utf8 -func f3 -destroy destroy
           23  +  sqlite4_create_function_v2 db f3 -1 -func f3 -destroy destroy
    24     24     set destroyed
    25     25   } 0
    26     26   do_test func3-2.2 {
    27         -  sqlite4_create_function_v2 db f3 -1 utf8 -func f3
           27  +  sqlite4_create_function_v2 db f3 -1 -func f3
    28     28     set destroyed
    29     29   } 1
    30     30   
    31     31   do_test func3-3.1 {
    32     32     set destroyed 0
    33     33     proc destroy {} { set ::destroyed 1 }
    34         -  sqlite4_create_function_v2 db f3 -1 any -func f3 -destroy destroy
           34  +  sqlite4_create_function_v2 db f3 -1 -func f3 -destroy destroy
    35     35     set destroyed
    36     36   } 0
    37     37   do_test func3-3.2 {
    38     38     db close
    39     39     set destroyed
    40     40   } 1
    41     41   
    42     42   sqlite4 db test.db
    43     43   do_test func3-4.1 {
    44     44     set destroyed 0
    45     45     set rc [catch { 
    46         -    sqlite4_create_function_v2 db f3 -1 any -func f3 -step f3 -destroy destroy
           46  +    sqlite4_create_function_v2 db f3 -1 -func f3 -step f3 -destroy destroy
    47     47     } msg]
    48     48     list $rc $msg
    49     49   } {1 SQLITE4_MISUSE}
    50     50   do_test func3-4.2 { set destroyed } 1
    51     51   
    52     52   finish_test

Changes to test/test_main.c.

  1470   1470     Tcl_Interp *interp,             /* The invoking TCL interpreter */
  1471   1471     int objc,                       /* Number of arguments */
  1472   1472     Tcl_Obj *CONST objv[]           /* Command arguments */
  1473   1473   ){
  1474   1474     sqlite4 *db;
  1475   1475     const char *zFunc;
  1476   1476     int nArg;
  1477         -  int enc;
  1478   1477     CreateFunctionV2 *p;
  1479   1478     int i;
  1480   1479     int rc;
  1481   1480   
  1482         -  struct EncTable {
  1483         -    const char *zEnc;
  1484         -    int enc;
  1485         -  } aEnc[] = {
  1486         -    {"utf8",    SQLITE4_UTF8 },
  1487         -    {"utf16",   SQLITE4_UTF16 },
  1488         -    {"utf16le", SQLITE4_UTF16LE },
  1489         -    {"utf16be", SQLITE4_UTF16BE },
  1490         -    {"any",     SQLITE4_ANY },
  1491         -    {"0", 0 }
  1492         -  };
  1493         -
  1494         -  if( objc<5 || (objc%2)==0 ){
  1495         -    Tcl_WrongNumArgs(interp, 1, objv, "DB NAME NARG ENC SWITCHES...");
         1481  +  if( objc<4 || (objc%2) ){
         1482  +    Tcl_WrongNumArgs(interp, 1, objv, "DB NAME NARG SWITCHES...");
  1496   1483       return TCL_ERROR;
  1497   1484     }
  1498   1485   
  1499   1486     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  1500   1487     zFunc = Tcl_GetString(objv[2]);
  1501   1488     if( Tcl_GetIntFromObj(interp, objv[3], &nArg) ) return TCL_ERROR;
  1502         -  if( Tcl_GetIndexFromObjStruct(interp, objv[4], aEnc, sizeof(aEnc[0]), 
  1503         -          "encoding", 0, &enc)
  1504         -  ){
  1505         -    return TCL_ERROR;
  1506         -  }
  1507         -  enc = aEnc[enc].enc;
  1508   1489   
  1509   1490     p = sqlite4_malloc(0, sizeof(CreateFunctionV2));
  1510   1491     assert( p );
  1511   1492     memset(p, 0, sizeof(CreateFunctionV2));
  1512   1493     p->interp = interp;
  1513   1494   
  1514         -  for(i=5; i<objc; i+=2){
         1495  +  for(i=4; i<objc; i+=2){
  1515   1496       int iSwitch;
  1516   1497       const char *azSwitch[] = {"-func", "-step", "-final", "-destroy", 0};
  1517   1498       if( Tcl_GetIndexFromObj(interp, objv[i], azSwitch, "switch", 0, &iSwitch) ){
  1518   1499         sqlite4_free(0, p);
  1519   1500         return TCL_ERROR;
  1520   1501       }
  1521   1502