]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the sqlite3_set_auxdata() and sqlite3_get_auxdata() APIs. (CVS 1532)
authordanielk1977 <danielk1977@noemail.net>
Sat, 5 Jun 2004 10:22:17 +0000 (10:22 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 5 Jun 2004 10:22:17 +0000 (10:22 +0000)
FossilOrigin-Name: c2899b437366d879258ab4f6ae47868441010eca

manifest
manifest.uuid
src/expr.c
src/sqlite.h.in
src/vdbe.c
src/vdbe.h
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c

index 21bb3f0fa9e9ff8240fc6f650bb43bc966c90be7..a7fa8de09f454d262164ebf7646efcd2213182ca 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sblob\svalues\ssurvive\sthe\s".dump"\scommand\sof\sthe\sshell.\s(CVS\s1531)
-D 2004-06-05T08:04:36
+C Add\sthe\ssqlite3_set_auxdata()\sand\ssqlite3_get_auxdata()\sAPIs.\s(CVS\s1532)
+D 2004-06-05T10:22:17
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -31,7 +31,7 @@ F src/build.c e12e602f06e37a0fbcb49af17cba68ad85e101b6
 F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
 F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
-F src/expr.c 5145de7d25a4b960a4afdb754a9e88b60cce0405
+F src/expr.c c55461f27a29c593d5b670a77583e44a0d80af0e
 F src/func.c 3b87e2e8b9aaa3a6d36b2c9616e7f404be38a667
 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
@@ -55,7 +55,7 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 02d711160100ef3a730060f7cfb5bc85fde06d72
 F src/shell.c 79af86d39b2149c7f16219fcbe636e7c2da9df8e
-F src/sqlite.h.in 8236db65bc6d8f5f47dc5a5e86c4a9bce42f2adf
+F src/sqlite.h.in dae6a7b4f0ff7310b2ae3f0952feaa9caae94f12
 F src/sqliteInt.h 99f2b4ff4ed28123890a0c71359fec3d2c5901c9
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5
@@ -70,11 +70,11 @@ F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
 F src/utf.c c8be20ecdcb10659e23c43e35d835460e964d248
 F src/util.c d3d2f62ec94160db3cb2b092267405ba99122152
 F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
-F src/vdbe.c e1e62347215a8dbe0ec72c155e4a042e81c6aa71
-F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
-F src/vdbeInt.h 9f5df0a21474be02fe870cbb0a414d09b66eb31a
-F src/vdbeapi.c 77d2e681a992ef189032cd9c1b7bf922f01ebe3e
-F src/vdbeaux.c 55c6d501175edb35cd84430302bbbde8dad4b752
+F src/vdbe.c 7f270f9a882bd51f7156cb87e24c5805b192be45
+F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
+F src/vdbeInt.h ab592f23ed5a1913f9a506bd7b76c5e39377942a
+F src/vdbeapi.c b3d8e559eb4a6cd6b49db5b2650426a54324adc5
+F src/vdbeaux.c 185f5ad1269d92684565be3a9bdb330bbda4f597
 F src/vdbemem.c 5d029d83bc60eaf9c45837fcbc0b03348ec95d7a
 F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
@@ -215,7 +215,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
 F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P cb1ffabf86996ab20dfffcb5f133fa9a9b56bbe2
-R ea7bd988d55c4ea96c95b0dedf76ecab
+P e82eb722b0e0b223ddaf7d85669792c33594f9da
+R 89202e63414e4abff52f3cb8f1936bee
 U danielk1977
-Z 4e22795b8cf7e800bcb3f1d60cd6c40a
+Z d38834ee375024a85c02b119ebf3aa3d
index 81c71f85e548a99475530968c3f90404379272f9..1f77420d3203cd57622805332ac57b2d16a3e7c2 100644 (file)
@@ -1 +1 @@
-e82eb722b0e0b223ddaf7d85669792c33594f9da
\ No newline at end of file
+c2899b437366d879258ab4f6ae47868441010eca
\ No newline at end of file
index 12dbd9992d5caa32193bfe4a38edbfe1449a3154..b3ba9f47f2d96c599ef1725a375eb707ab0260b1 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.133 2004/05/30 01:38:43 drh Exp $
+** $Id: expr.c,v 1.134 2004/06/05 10:22:17 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1231,11 +1231,16 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
       FuncDef *pDef;
       int nId;
       const char *zId;
+      int p2 = 0;
+      int i;
       getFunctionName(pExpr, &zId, &nId);
       pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0);
       assert( pDef!=0 );
       nExpr = sqlite3ExprCodeExprList(pParse, pList);
-      sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_FUNCDEF);
+      for(i=0; i<nExpr && i<32; i++){
+        p2 &= (1<<i);
+      }
+      sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
       break;
     }
     case TK_SELECT: {
index 5243e94a069aec02fc2910b50e1e5c6f07ea2e6e..e710ada5d1152a4b7b91ef2b05398be9ad2d8bad 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.91 2004/06/02 01:22:02 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.92 2004/06/05 10:22:18 danielk1977 Exp $
 */
 #ifndef _SQLITE_H_
 #define _SQLITE_H_
@@ -914,6 +914,35 @@ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 */
 void *sqlite3_user_data(sqlite3_context*);
 
+/*
+** The following two functions may be used by scalar user functions to
+** associate meta-data with argument values. If the same value is passed to
+** multiple invocations of the user-function during query execution, under
+** some circumstances the associated meta-data may be preserved. This may
+** be used, for example, to add a regular-expression matching scalar
+** function. The compiled version of the regular expression is stored as
+** meta-data associated with the SQL value passed as the regular expression
+** pattern.
+**
+** Calling sqlite3_get_auxdata() returns a pointer to the meta data
+** associated with the Nth argument value to the current user function
+** call, where N is the second parameter. If no meta-data has been set for
+** that value, then a NULL pointer is returned.
+**
+** The sqlite3_set_auxdata() is used to associate meta data with a user
+** function argument. The third parameter is a pointer to the meta data
+** to be associated with the Nth user function argument value. The fourth
+** parameter specifies a 'delete function' that will be called on the meta
+** data pointer to release it when it is no longer required. If the delete
+** function pointer is NULL, it is not invoked.
+**
+** In practice, meta-data is preserved between function calls for
+** expressions that are constant at compile time. This includes literal
+** values and SQL variables.
+*/
+void *sqlite3_get_auxdata(sqlite3_context*, int);
+void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
+
 /*
 ** User-defined functions invoke the following routines in order to
 ** set their return value.
index dfc25601d1a680ea25169c13599578bf37046cb2..29ac27cff6dbcb50590ddf2e29c4a63ca5568f88 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.357 2004/06/04 06:22:02 danielk1977 Exp $
+** $Id: vdbe.c,v 1.358 2004/06/05 10:22:18 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1218,11 +1218,18 @@ divide_by_zero:
   break;
 }
 
-/* Opcode: Function P1 * P3
+/* Opcode: Function P1 P2 P3
 **
 ** Invoke a user function (P3 is a pointer to a Function structure that
-** defines the function) with P1 string arguments taken from the stack.
-** Pop all arguments from the stack and push back the result.
+** defines the function) with P1 arguments taken from the stack.  Pop all
+** arguments from the stack and push back the result.
+**
+** P2 is a 32-bit bitmask indicating whether or not each argument to the 
+** function was determined to be constant at compile time. If the first
+** argument was constant then bit 0 of P2 is set. This is used to determine
+** whether meta data associated with a user function argument using the
+** sqlite3_set_auxdata() API may be safely retained until the next
+** invocation of this opcode.
 **
 ** See also: AggFunc
 */
@@ -1243,7 +1250,15 @@ case OP_Function: {
     storeTypeInfo(pArg, db->enc);
   }
 
-  ctx.pFunc = (FuncDef*)pOp->p3;
+  assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
+  if( pOp->p3type==P3_FUNCDEF ){
+    ctx.pFunc = (FuncDef*)pOp->p3;
+    ctx.pVdbeFunc = 0;
+  }else{
+    ctx.pVdbeFunc = (VdbeFunc*)pOp->p3;
+    ctx.pFunc = ctx.pVdbeFunc->pFunc;
+  }
+
   ctx.s.flags = MEM_Null;
   ctx.s.z = 0;
   ctx.isError = 0;
@@ -1253,6 +1268,22 @@ case OP_Function: {
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   popStack(&pTos, n);
 
+  /* If any auxilary data functions have been called by this user function,
+  ** immediately call the destructor for any non-static values.
+  */
+  if( ctx.pVdbeFunc ){
+    int mask = pOp->p2;
+    for(i=0; i<n; i++){
+      struct AuxData *pAux = &ctx.pVdbeFunc->apAux[i];
+      if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
+        pAux->xDelete(pAux->pAux);
+        pAux->pAux = 0;
+      }
+    }
+    pOp->p3 = (char *)ctx.pVdbeFunc;
+    pOp->p3type = P3_VDBEFUNC;
+  }
+
   /* Copy the result of the function to the top of the stack */
   pTos++;
   *pTos = ctx.s;
index b093f308292e7fc1c66eeef73092b67843160980..1f5f8108d83b8b67a6e49134918fe3959e17b685 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.84 2004/05/26 16:54:48 drh Exp $
+** $Id: vdbe.h,v 1.85 2004/06/05 10:22:18 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -71,6 +71,7 @@ typedef struct VdbeOpList VdbeOpList;
 #define P3_COLLSEQ  (-4)  /* P3 is a pointer to a CollSeq structure */
 #define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
 #define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
+#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */
 
 /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
 ** is made.  That copy is freed when the Vdbe is finalized.  But if the
index 40c8fa8acada5a813c30f5b4ac046169cfe088b3..9512d42313e463787b5f4cb5728aed0eac1cc228 100644 (file)
@@ -177,6 +177,16 @@ typedef struct Mem Mem;
 */
 #define MEM_AggCtx    0x0400  /* Mem.z points to an agg function context */
 
+struct VdbeFunc {
+  FuncDef *pFunc;
+  int nAux;
+  struct AuxData {
+    void *pAux;
+    void (*xDelete)(void *);
+  } apAux[0];
+};
+typedef struct VdbeFunc VdbeFunc;
+
 /*
 ** The "context" argument for a installable function.  A pointer to an
 ** instance of this structure is the first argument to the routines used
@@ -192,6 +202,7 @@ typedef struct Mem Mem;
 */
 struct sqlite3_context {
   FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
+  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   Mem s;            /* The return value is stored here */
   void *pAgg;       /* Aggregate context */
   u8 isError;       /* Set to true for an error */
index 6c685985ecbda18e9ef8b6ea571ca9c9a1dd24ed..1e40fad7517d84a73f4cb98d3c4e15399599d7e4 100644 (file)
@@ -217,6 +217,47 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
   return p->pAgg;
 }
 
+/*
+** Return the auxilary data pointer, if any, for the iArg'th argument to
+** the user-function defined by pCtx.
+*/
+void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+  VdbeFunc *pVdbeFunc = pCtx->pVdbeFunc;
+  if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
+    return 0;
+  }
+  return pCtx->pVdbeFunc->apAux[iArg].pAux;
+}
+
+/*
+** Set the auxilary data pointer and delete function, for the iArg'th
+** argument to the user-function defined by pCtx. Any previous value is
+** deleted by calling the delete function specified when it was set.
+*/
+void sqlite3_set_auxdata(
+  sqlite3_context *pCtx, 
+  int iArg, 
+  void *pAux, 
+  void (*xDelete)(void*)
+){
+  struct AuxData *pAuxData;
+  if( iArg<0 ) return;
+
+  if( !pCtx->pVdbeFunc || pCtx->pVdbeFunc->nAux<=iArg ){
+    int nMalloc = sizeof(VdbeFunc)+sizeof(struct AuxData)*(iArg+1);
+    pCtx->pVdbeFunc = sqliteRealloc(pCtx->pVdbeFunc, nMalloc);
+    if( !pCtx->pVdbeFunc ) return;
+    pCtx->pVdbeFunc->nAux = iArg+1;
+  }
+
+  pAuxData = &pCtx->pVdbeFunc->apAux[iArg];
+  if( pAuxData->pAux && pAuxData->xDelete ){
+    pAuxData->xDelete(pAuxData->pAux);
+  }
+  pAuxData->pAux = pAux;
+  pAuxData->xDelete = xDelete;
+}
+
 /*
 ** Return the number of times the Step function of a aggregate has been 
 ** called.
index 4c343946c3bffdf3f0b32ee8dc3b9bc8212b7ac3..d3a982ad6354f0faa7f5673a66151d6a47e2fea8 100644 (file)
@@ -1234,6 +1234,16 @@ void sqlite3VdbeDelete(Vdbe *p){
     if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
       sqliteFree(pOp->p3);
     }
+    if( pOp->p3type==P3_VDBEFUNC ){
+      VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
+      for(i=0; i<pVdbeFunc->nAux; i++){
+        struct AuxData *pAuxData = &pVdbeFunc->apAux[i].pAux;
+        if( pAuxData->pAux && pAuxData->xDelete ){
+          pAuxData->xDelete(pAuxData->pAux);
+        }
+      }
+      sqliteFree(pVdbeFunc);
+    }
 #ifndef NDEBUG
     sqliteFree(pOp->zComment);
 #endif