Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the sqlite3_set_auxdata() and sqlite3_get_auxdata() APIs. (CVS 1532) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c2899b437366d879258ab4f6ae478684 |
User & Date: | danielk1977 2004-06-05 10:22:17.000 |
Context
2004-06-06
| ||
00:42 | Added sqlite3OsLock for win32. Assertion fault in attach.test. (CVS 1533) (check-in: 9e6cd9ec75 user: drh tags: trunk) | |
2004-06-05
| ||
10:22 | Add the sqlite3_set_auxdata() and sqlite3_get_auxdata() APIs. (CVS 1532) (check-in: c2899b4373 user: danielk1977 tags: trunk) | |
08:04 | Ensure blob values survive the ".dump" command of the shell. (CVS 1531) (check-in: e82eb722b0 user: danielk1977 tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.134 2004/06/05 10:22:17 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> char const *sqlite3AffinityString(char affinity){ switch( affinity ){ case SQLITE_AFF_INTEGER: return "i"; |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 | case TK_LIKE: case TK_FUNCTION: { ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; int nId; const char *zId; getFunctionName(pExpr, &zId, &nId); pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); | > > > > > | | 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | case TK_LIKE: case TK_FUNCTION: { ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; 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); 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: { sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); break; } case TK_IN: { |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.92 2004/06/05 10:22:18 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
910 911 912 913 914 915 916 917 918 919 920 921 922 923 | ** The pUserData parameter to the sqlite3_create_function() and ** sqlite3_create_aggregate() routines used to register user functions ** is available to the implementation of the function using this ** call. */ void *sqlite3_user_data(sqlite3_context*); /* ** User-defined functions invoke the following routines in order to ** set their return value. */ void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 | ** The pUserData parameter to the sqlite3_create_function() and ** sqlite3_create_aggregate() routines used to register user functions ** is available to the implementation of the function using this ** call. */ 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. */ void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.358 2004/06/05 10:22:18 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
1214 1215 1216 1217 1218 1219 1220 | Release(pTos); pTos--; Release(pTos); pTos->flags = MEM_Null; break; } | | | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 | Release(pTos); pTos--; Release(pTos); pTos->flags = MEM_Null; break; } /* Opcode: Function P1 P2 P3 ** ** Invoke a user function (P3 is a pointer to a Function structure that ** 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 */ case OP_Function: { int i; Mem *pArg; sqlite3_context ctx; sqlite3_value **apVal; int n = pOp->p1; n = pOp->p1; apVal = p->apArg; assert( apVal || n==0 ); pArg = &pTos[1-n]; for(i=0; i<n; i++, pArg++){ apVal[i] = pArg; storeTypeInfo(pArg, db->enc); } 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; ctx.isStep = 0; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); 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; if( pTos->flags & MEM_Short ){ pTos->z = pTos->zShort; } |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** 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.85 2004/06/05 10:22:18 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #define P3_NOTUSED 0 /* The P3 parameter is not used */ #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #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 */ /* 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 ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #define P3_NOTUSED 0 /* The P3 parameter is not used */ #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #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 ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | /* The following MEM_ value appears only in AggElem.aMem.s.flag fields. ** It indicates that the corresponding AggElem.aMem.z points to a ** aggregate function context that needs to be finalized. */ #define MEM_AggCtx 0x0400 /* Mem.z points to an agg function context */ /* ** The "context" argument for a installable function. A pointer to an ** instance of this structure is the first argument to the routines used ** implement the SQL functions. ** ** There is a typedef for this structure in sqlite.h. So all routines, ** even the public interface to SQLite, can use a pointer to this structure. ** But this file is the only place where the internal details of this ** structure are known. ** ** This structure is defined inside of vdbe.c because it uses substructures ** (Mem) which are only defined there. */ struct sqlite3_context { FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ Mem s; /* The return value is stored here */ void *pAgg; /* Aggregate context */ u8 isError; /* Set to true for an error */ u8 isStep; /* Current in the step function */ int cnt; /* Number of times that the step function has been called */ }; | > > > > > > > > > > > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | /* The following MEM_ value appears only in AggElem.aMem.s.flag fields. ** It indicates that the corresponding AggElem.aMem.z points to a ** aggregate function context that needs to be finalized. */ #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 ** implement the SQL functions. ** ** There is a typedef for this structure in sqlite.h. So all routines, ** even the public interface to SQLite, can use a pointer to this structure. ** But this file is the only place where the internal details of this ** structure are known. ** ** This structure is defined inside of vdbe.c because it uses substructures ** (Mem) which are only defined there. */ 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 */ u8 isStep; /* Current in the step function */ int cnt; /* Number of times that the step function has been called */ }; |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
212 213 214 215 216 217 218 219 220 221 222 223 224 225 | memset(p->pAgg, 0, nByte); }else{ p->pAgg = sqliteMalloc( nByte ); } } return p->pAgg; } /* ** Return the number of times the Step function of a aggregate has been ** called. ** ** This routine is defined here in vdbe.c because it depends on knowing ** the internals of the sqlite3_context structure which is only defined in | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | memset(p->pAgg, 0, nByte); }else{ p->pAgg = sqliteMalloc( 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. ** ** This routine is defined here in vdbe.c because it depends on knowing ** the internals of the sqlite3_context structure which is only defined in |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | p->aOp = 0; p->nOp = 0; } for(i=0; i<p->nOp; i++){ Op *pOp = &p->aOp[i]; if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){ sqliteFree(pOp->p3); } #ifndef NDEBUG sqliteFree(pOp->zComment); #endif } for(i=0; i<p->nVar; i++){ if( p->apVar[i].flags&MEM_Dyn ){ | > > > > > > > > > > | 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 | p->aOp = 0; p->nOp = 0; } for(i=0; i<p->nOp; i++){ Op *pOp = &p->aOp[i]; 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 } for(i=0; i<p->nVar; i++){ if( p->apVar[i].flags&MEM_Dyn ){ |
︙ | ︙ |