Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch pointer-with-destructor Excluding Merge-Ins
This is equivalent to a diff from f39cb76b to d6684d2a
2017-07-27
| ||
17:45 | Add destructor functions for the pointer argument (NB: not the type string) to the sqlite3_bind_pointer() and sqlite3_result_pointer() interfaces. Use this new capability to resolve a pointer leak in the custom geometry function mechanism of the RTREE extension. (check-in: 5a2340b8 user: drh tags: branch-3.20) | |
16:42 | In sqlite3_bind_pointer(), invoke the destructor if the bind index is out of range, like sqlite3_bind_blob() does. (Closed-Leaf check-in: d6684d2a user: drh tags: pointer-with-destructor) | |
15:53 | Improved implementation of the destructor on pointer-passing interfaces. (check-in: 601ad679 user: drh tags: pointer-with-destructor) | |
14:04 | A demonstration of how FTS3 cursor pointers can be passed from the MATCH operator to the snippet() function securely and opaquely without having to use the sqlite3_result_pointer() and sqlite3_value_pointer() interfaces. (Closed-Leaf check-in: 49cf31da user: drh tags: pass-pointer-as-blob) | |
03:48 | Add a destructor argument to sqlite3_bind_pointer() and sqlite3_result_pointer(). (check-in: 3d9e841f user: drh tags: pointer-with-destructor) | |
2017-07-25
| ||
15:12 | Release candidate 2 for 3.20.0. (check-in: f39cb76b user: drh tags: branch-3.20) | |
01:34 | Fix a bug in the deterministic date/time function logic that can only appear with STAT3 or STAT4. (check-in: 1ca707a4 user: drh tags: trunk) | |
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
3349 3350 3351 3352 3353 3354 3355 | /* The column value supplied by SQLite must be in range. */ assert( iCol>=0 && iCol<=p->nColumn+2 ); switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ | | | 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 | /* The column value supplied by SQLite must be in range. */ assert( iCol>=0 && iCol<=p->nColumn+2 ); switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0); break; case 1: /* The docid column */ sqlite3_result_int64(pCtx, pCsr->iPrevId); break; |
︙ | ︙ |
Changes to ext/fts5/fts5_tcl.c.
︙ | ︙ | |||
100 101 102 103 104 105 106 | fts5_api *pApi = 0; rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0); return TCL_ERROR; } | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | fts5_api *pApi = 0; rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0); return TCL_ERROR; } sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0); sqlite3_step(pStmt); if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0); return TCL_ERROR; } |
︙ | ︙ |
Changes to ext/fts5/fts5_test_mi.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){ sqlite3_stmt *pStmt = 0; int rc; *ppApi = 0; rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0); if( rc==SQLITE_OK ){ | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){ sqlite3_stmt *pStmt = 0; int rc; *ppApi = 0; rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0); if( rc==SQLITE_OK ){ sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr", 0); (void)sqlite3_step(pStmt); rc = sqlite3_finalize(pStmt); } return rc; } |
︙ | ︙ |
Changes to ext/misc/carray.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** at the address $ptr. $ptr is a pointer to the array of integers. ** The pointer value must be assigned to $ptr using the ** sqlite3_bind_pointer() interface with a pointer type of "carray". ** For example: ** ** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; ** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** at the address $ptr. $ptr is a pointer to the array of integers. ** The pointer value must be assigned to $ptr using the ** sqlite3_bind_pointer() interface with a pointer type of "carray". ** For example: ** ** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; ** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); ** sqlite3_bind_value(pStmt, i, aX, "carray", 0); ** ** There is an optional third parameter to determine the datatype of ** the C-language array. Allowed values of the third parameter are ** 'int32', 'int64', 'double', 'char*'. Example: ** ** SELECT * FROM carray($ptr,10,'char*'); ** |
︙ | ︙ | |||
373 374 375 376 377 378 379 | i64 = sqlite3_value_int64(argv[0]); if( sizeof(i64)==sizeof(p) ){ memcpy(&p, &i64, sizeof(p)); }else{ int i32 = i64 & 0xffffffff; memcpy(&p, &i32, sizeof(p)); } | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | i64 = sqlite3_value_int64(argv[0]); if( sizeof(i64)==sizeof(p) ){ memcpy(&p, &i64, sizeof(p)); }else{ int i32 = i64 & 0xffffffff; memcpy(&p, &i32, sizeof(p)); } sqlite3_result_pointer(context, p, "carray", 0); } #endif /* SQLITE_TEST */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifdef _WIN32 __declspec(dllexport) |
︙ | ︙ |
Changes to ext/rtree/rtree.c.
︙ | ︙ | |||
335 336 337 338 339 340 341 | struct RtreeGeomCallback { int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); int (*xQueryFunc)(sqlite3_rtree_query_info*); void (*xDestructor)(void*); void *pContext; }; | < < < < < < < < | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | struct RtreeGeomCallback { int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); int (*xQueryFunc)(sqlite3_rtree_query_info*); void (*xDestructor)(void*); void *pContext; }; /* ** An instance of this structure (in the form of a BLOB) is returned by ** the SQL functions that sqlite3_rtree_geometry_callback() and ** sqlite3_rtree_query_callback() create, and is read as the right-hand ** operand to the MATCH operator of an R-Tree. */ struct RtreeMatchArg { u32 iSize; /* Size of this object */ RtreeGeomCallback cb; /* Info about the callback functions */ int nParam; /* Number of parameters to the SQL function */ sqlite3_value **apSqlParam; /* Original SQL parameter values */ RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ }; #ifndef MAX |
︙ | ︙ | |||
1645 1646 1647 1648 1649 1650 1651 | /* ** This function is called to configure the RtreeConstraint object passed ** as the second argument for a MATCH constraint. The value passed as the ** first argument to this function is the right-hand operand to the MATCH ** operator. */ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ | | < < < < < < | < | < < | > < | < < < < < < < | 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | /* ** This function is called to configure the RtreeConstraint object passed ** as the second argument for a MATCH constraint. The value passed as the ** first argument to this function is the right-hand operand to the MATCH ** operator. */ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */ sqlite3_rtree_query_info *pInfo; /* Callback information */ pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg"); if( pSrc==0 ) return SQLITE_ERROR; pInfo = (sqlite3_rtree_query_info*) sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize ); if( !pInfo ) return SQLITE_NOMEM; memset(pInfo, 0, sizeof(*pInfo)); pBlob = (RtreeMatchArg*)&pInfo[1]; memcpy(pBlob, pSrc, pSrc->iSize); pInfo->pContext = pBlob->cb.pContext; pInfo->nParam = pBlob->nParam; pInfo->aParam = pBlob->aParam; pInfo->apSqlParam = pBlob->apSqlParam; if( pBlob->cb.xGeom ){ pCons->u.xGeom = pBlob->cb.xGeom; |
︙ | ︙ | |||
3709 3710 3711 3712 3713 3714 3715 | nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) + nArg*sizeof(sqlite3_value*); pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); }else{ int i; | | | | 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 | nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) + nArg*sizeof(sqlite3_value*); pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); }else{ int i; pBlob->iSize = nBlob; pBlob->cb = pGeomCtx[0]; pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg]; pBlob->nParam = nArg; for(i=0; i<nArg; i++){ pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]); if( pBlob->apSqlParam[i]==0 ) memErr = 1; #ifdef SQLITE_RTREE_INT_ONLY pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); #else pBlob->aParam[i] = sqlite3_value_double(aArg[i]); #endif } if( memErr ){ sqlite3_result_error_nomem(ctx); rtreeMatchArgFree(pBlob); }else{ sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree); } } } /* ** Register a new geometry function for use with the r-tree MATCH operator. */ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
3879 3880 3881 3882 3883 3884 3885 | ** is filled with zeroes. ^A zeroblob uses a fixed amount of memory ** (just an integer to hold its size) while it is being processed. ** Zeroblobs are intended to serve as placeholders for BLOBs whose ** content is later written using ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** | | | > | | | 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 | ** is filled with zeroes. ^A zeroblob uses a fixed amount of memory ** (just an integer to hold its size) while it is being processed. ** Zeroblobs are intended to serve as placeholders for BLOBs whose ** content is later written using ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function that is called when P goes out of scope. ** ^The sqlite3_bind_pointer() routine can be used to pass ** host-language pointers into [application-defined SQL functions]. ** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears ** to be an ordinary SQL NULL value to everything other than ** [sqlite3_value_pointer()]. The T parameter should be a static string, ** preferably a string literal. The procedure that invokes ** sqlite3_bind_pointer(S,I,P,T,D) owns the T string and ** must guarantee that it remains valid and unchanged until after the last ** access via [sqlite3_value_pointer()]. The sqlite3_bind_pointer() routine ** is part of the [pointer passing interface] added for SQLite 3.20.0. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() |
︙ | ︙ | |||
3926 3927 3928 3929 3930 3931 3932 | int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); | | | 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 | int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); /* ** CAPI3REF: Number Of SQL Parameters ** METHOD: sqlite3_stmt ** |
︙ | ︙ | |||
4759 4760 4761 4762 4763 4764 4765 | ** ** ^The sqlite3_value_text16() interface extracts a UTF-16 string ** in the native byte-order of the host machine. ^The ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** ** ^If [sqlite3_value] object V was initialized | | | 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 | ** ** ^The sqlite3_value_text16() interface extracts a UTF-16 string ** in the native byte-order of the host machine. ^The ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** ** ^If [sqlite3_value] object V was initialized ** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] ** and if X and Y are strings that compare equal according to strcmp(X,Y), ** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, ** sqlite3_value_pointer(V,Y) returns a NULL. ** ** ^(The sqlite3_value_type(V) interface returns the ** [SQLITE_INTEGER | datatype code] for the initial datatype of the ** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], |
︙ | ︙ | |||
5097 5098 5099 5100 5101 5102 5103 | ** sqlite3_result_value() interface makes a copy of the [sqlite3_value] ** so that the [sqlite3_value] specified in the parameter may change or ** be deallocated after sqlite3_result_value() returns without harm. ** ^A [protected sqlite3_value] object may always be used where an ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** | | > > > | | 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 | ** sqlite3_result_value() interface makes a copy of the [sqlite3_value] ** so that the [sqlite3_value] specified in the parameter may change or ** be deallocated after sqlite3_result_value() returns without harm. ** ^A [protected sqlite3_value] object may always be used where an ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** ** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an ** SQL NULL value, just like [sqlite3_result_null(C)], except that it ** also associates the host-language pointer P or type T with that ** NULL value such that the pointer can be retrieved within an ** [application-defined SQL function] using [sqlite3_value_pointer()]. ** ^If the D parameter is not NULL, then it is a pointer to a destructor ** for the P parameter. ^The destructor D is invoked on P when the result ** value goes out of scope. ** The T parameter should be a static string and preferably a string ** literal. The procedure that invokes sqlite3_result_pointer(C,P,T,D) ** continues to own the P and T pointers and must guarantee that ** those pointers remain valid until after the last access via ** [sqlite3_value_pointer()]. The sqlite3_result_pointer() routine ** is part of the [pointer passing interface] added for SQLite 3.20.0. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received |
︙ | ︙ | |||
5132 5133 5134 5135 5136 5137 5138 | void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); | | | 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 | void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); void sqlite3_result_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); /* ** CAPI3REF: Setting The Subtype Of An SQL Function ** METHOD: sqlite3_context |
︙ | ︙ |
Changes to src/sqlite3ext.h.
︙ | ︙ | |||
285 286 287 288 289 290 291 | /* Version 3.18.0 and later */ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); /* Version 3.20.0 and later */ int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, sqlite3_stmt**,const char**); int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, sqlite3_stmt**,const void**); | | | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | /* Version 3.18.0 and later */ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); /* Version 3.20.0 and later */ int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, sqlite3_stmt**,const char**); int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, sqlite3_stmt**,const void**); int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); void *(*value_pointer)(sqlite3_value*,const char*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
185 186 187 188 189 190 191 | ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ |
︙ | ︙ | |||
218 219 220 221 222 223 224 | */ #define MEMCELLSIZE offsetof(Mem,zMalloc) /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. | > | | | | | 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 | */ #define MEMCELLSIZE offsetof(Mem,zMalloc) /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also ** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0xc1ff /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management ** policy for Mem.z. The MEM_Term flag tells us whether or not the ** string is \000 or \u0000 terminated */ #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */ #define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ #define MEM_Static 0x0800 /* Mem.z points to a static string */ #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ #define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ #ifdef SQLITE_OMIT_INCRBLOB |
︙ | ︙ | |||
472 473 474 475 476 477 478 | int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif | | | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); void sqlite3VdbeMemSetRowSet(Mem*); int sqlite3VdbeMemMakeWriteable(Mem*); int sqlite3VdbeMemStringify(Mem*, u8, u8); i64 sqlite3VdbeIntValue(Mem*); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
197 198 199 200 201 202 203 | } unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ Mem *p = (Mem*)pVal; | > | | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | } unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ Mem *p = (Mem*)pVal; if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == (MEM_Null|MEM_Term|MEM_Subtype) && zPType!=0 && p->eSubtype=='p' && strcmp(p->u.zPType, zPType)==0 ){ return (void*)p->z; }else{ return 0; } } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } |
︙ | ︙ | |||
385 386 387 388 389 390 391 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } void sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } | | > > > > > | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } void sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } void sqlite3_result_pointer( sqlite3_context *pCtx, void *pPtr, const char *zPType, void (*xDestructor)(void*) ){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemSetNull(pOut); sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; } |
︙ | ︙ | |||
1394 1395 1396 1397 1398 1399 1400 | Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } | | > > > > > > | > > | 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 | Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } int sqlite3_bind_pointer( sqlite3_stmt *pStmt, int i, void *pPtr, const char *zPTtype, void (*xDestructor)(void*) ){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); } return rc; } int sqlite3_bind_text( sqlite3_stmt *pStmt, int i, const char *zData, |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | ** Check invariants on a Mem object. ** ** This routine is intended for use inside of assert() statements, like ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); */ int sqlite3VdbeCheckMemInvariants(Mem *p){ /* If MEM_Dyn is set then Mem.xDel!=0. | | > | | > | > > > > > > > > > > > > > > > > > > > > > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | ** Check invariants on a Mem object. ** ** This routine is intended for use inside of assert() statements, like ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); */ int sqlite3VdbeCheckMemInvariants(Mem *p){ /* If MEM_Dyn is set then Mem.xDel!=0. ** Mem.xDel might not be initialized if MEM_Dyn is clear. */ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we ** ensure that if Mem.szMalloc>0 then it is safe to do ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. ** That saves a few cycles in inner loops. */ assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 ); /* If MEM_Null is set, then either the value is a pure NULL (the usual ** case) or it is a pointer set using sqlite3_bind_pointer() or ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be ** set. */ if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){ /* This is a pointer type. There may be a flag to indicate what to ** do with the pointer. */ assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 ); /* No other bits set */ assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype |MEM_Dyn|MEM_Ephem|MEM_Static))==0 ); }else{ /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn, ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */ } }else{ /* The MEM_Cleared bit is only allowed on NULLs */ assert( (p->flags & MEM_Cleared)==0 ); } /* The szMalloc field holds the correct memory allocation size */ assert( p->szMalloc==0 || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: |
︙ | ︙ | |||
701 702 703 704 705 706 707 708 709 710 711 | vdbeReleaseAndSetInt64(pMem, val); }else{ pMem->u.i = val; pMem->flags = MEM_Int; } } /* ** Set the value stored in *pMem should already be a NULL. ** Also store a pointer to go with it. */ | > > > | > > > > > | > | < | | < | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | vdbeReleaseAndSetInt64(pMem, val); }else{ pMem->u.i = val; pMem->flags = MEM_Int; } } /* A no-op destructor */ static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } /* ** Set the value stored in *pMem should already be a NULL. ** Also store a pointer to go with it. */ void sqlite3VdbeMemSetPointer( Mem *pMem, void *pPtr, const char *zPType, void (*xDestructor)(void*) ){ assert( pMem->flags==MEM_Null ); pMem->u.zPType = zPType ? zPType : ""; pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; pMem->eSubtype = 'p'; pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; } #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val, ** manifest type REAL. */ |
︙ | ︙ |