Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the pointer-type parameter to sqlite3_bind_pointer(), sqlite3_result_pointer(), and sqlite3_value_pointer(). The pointer type is a static string that must match (according to strcmp()) or else the pointer is passed as a NULL. This is a security measure to prevent crossing pointers between different extensions. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | branch-3.20 |
Files: | files | file ages | folders |
SHA3-256: |
e1196567fcbc313657836262ed9f7166 |
User & Date: | drh 2017-07-17 12:27:43.686 |
Context
2017-07-17
| ||
12:41 | Comment changes clarifying details of the pointer-type parameter. No changes to code. (check-in: e4579e50a1 user: drh tags: branch-3.20) | |
12:27 | Add the pointer-type parameter to sqlite3_bind_pointer(), sqlite3_result_pointer(), and sqlite3_value_pointer(). The pointer type is a static string that must match (according to strcmp()) or else the pointer is passed as a NULL. This is a security measure to prevent crossing pointers between different extensions. (check-in: e1196567fc user: drh tags: branch-3.20) | |
11:39 | Improve the sqlite3_result_pointer() interface so that it cannot be faked using sqlite3_result_null() and sqlite3_result_subtype(). (Closed-Leaf check-in: c13264d5ef user: drh tags: pointer-types) | |
2017-07-15
| ||
20:44 | Merge the fix for ticket [a4e06e75a9ab61a12] from trunk. (check-in: b64d64c844 user: drh tags: branch-3.20) | |
Changes
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"); break; case 1: /* The docid column */ sqlite3_result_int64(pCtx, pCsr->iPrevId); break; |
︙ | ︙ | |||
3568 3569 3570 3571 3572 3573 3574 | static int fts3FunctionArg( sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ int rc; | | | 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 | static int fts3FunctionArg( sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ int rc; *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor"); if( (*ppCsr)!=0 ){ rc = SQLITE_OK; }else{ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); sqlite3_free(zErr); rc = SQLITE_ERROR; |
︙ | ︙ |
Changes to ext/misc/carray.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** Examples: ** ** SELECT * FROM carray($ptr,5) ** ** The query above returns 5 integers contained in a C-language array ** at the address $ptr. $ptr is a pointer to the array of integers. ** The pointer value must be assigned to $ptr using the | | > > > > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ** Examples: ** ** SELECT * FROM carray($ptr,5) ** ** The query above returns 5 integers contained in a C-language array ** 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"); ** ** 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*'); ** ** The default value of the third parameter is 'int32'. ** ** HOW IT WORKS ** ** The carray "function" is really a virtual table with the ** following schema: ** ** CREATE TABLE carray( |
︙ | ︙ | |||
229 230 231 232 233 234 235 | static int carrayFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ carray_cursor *pCur = (carray_cursor *)pVtabCursor; if( idxNum ){ | | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | static int carrayFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ carray_cursor *pCur = (carray_cursor *)pVtabCursor; if( idxNum ){ pCur->pPtr = sqlite3_value_pointer(argv[0], "carray"); pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; if( idxNum<3 ){ pCur->eType = CARRAY_INT32; }else{ unsigned char i; const char *zType = (const char*)sqlite3_value_text(argv[2]); for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){ |
︙ | ︙ | |||
366 367 368 369 370 371 372 | 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"); } #endif /* SQLITE_TEST */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifdef _WIN32 __declspec(dllexport) |
︙ | ︙ |
Changes to ext/misc/remember.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** ** This allows, for example, a counter to incremented and the original ** value retrieved, atomically, using a single statement: ** ** UPDATE counterTab SET cnt=remember(cnt,$PTR)+1 WHERE id=$ID ** ** Prepare the above statement once. Then to use it, bind the address | | > | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** ** This allows, for example, a counter to incremented and the original ** value retrieved, atomically, using a single statement: ** ** UPDATE counterTab SET cnt=remember(cnt,$PTR)+1 WHERE id=$ID ** ** Prepare the above statement once. Then to use it, bind the address ** of the output variable to $PTR using sqlite3_bind_pointer() with a ** pointer type of "carray" and bind the id of the counter to $ID and ** run the prepared statement. ** ** One can imagine doing similar things with floating-point values and ** strings, but this demonstration extension will stick to using just ** integers. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 |
︙ | ︙ | |||
43 44 45 46 47 48 49 | int argc, sqlite3_value **argv ){ sqlite3_int64 v; sqlite3_int64 *ptr; assert( argc==2 ); v = sqlite3_value_int64(argv[0]); | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | int argc, sqlite3_value **argv ){ sqlite3_int64 v; sqlite3_int64 *ptr; assert( argc==2 ); v = sqlite3_value_int64(argv[0]); ptr = sqlite3_value_pointer(argv[1], "carray"); if( ptr ) *ptr = v; sqlite3_result_int64(pCtx, v); } #ifdef _WIN32 __declspec(dllexport) #endif |
︙ | ︙ |
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 | ** 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) 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. ** ^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()]. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer |
︙ | ︙ | |||
3921 3922 3923 3924 3925 3926 3927 | 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*); | | | 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 | 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*); 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 ** |
︙ | ︙ | |||
4754 4755 4756 4757 4758 4759 4760 | ** ** ^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 | | > | | | 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 | ** ** ^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)] or [sqlite3_result_pointer(C,P,X)] ** 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], ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ ** Other interfaces might change the datatype for an sqlite3_value object. ** For example, if the datatype is initially SQLITE_INTEGER and |
︙ | ︙ | |||
4790 4791 4792 4793 4794 4795 4796 | ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ const void *sqlite3_value_blob(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); sqlite3_int64 sqlite3_value_int64(sqlite3_value*); | | | 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 | ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ const void *sqlite3_value_blob(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); sqlite3_int64 sqlite3_value_int64(sqlite3_value*); void *sqlite3_value_pointer(sqlite3_value*, const char*); const unsigned char *sqlite3_value_text(sqlite3_value*); const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); |
︙ | ︙ | |||
5091 5092 5093 5094 5095 5096 5097 | ** 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. ** | | | | | 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 | ** 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) 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()]. ** This mechanism can be used to pass non-SQL values between ** application-defined functions. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. |
︙ | ︙ | |||
5122 5123 5124 5125 5126 5127 5128 | 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*); | | | 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 | 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 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 301 | /* 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 (*result_pointer)(sqlite3_context*,void*,const char*); 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". */ typedef int (*sqlite3_loadext_entry)( |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
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 | | | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | 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 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.
︙ | ︙ | |||
195 196 197 198 199 200 201 | sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } | | > | > > > | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } 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_Null|MEM_Subtype|MEM_Term|MEM_Static) && p->eSubtype=='p' && zPType!=0 && strcmp(p->z, zPType)==0 ){ return p->u.pPtr; }else{ return 0; } } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); |
︙ | ︙ | |||
381 382 383 384 385 386 387 | 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); } | | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | 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 *zPT){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemSetNull(pOut); sqlite3VdbeMemSetPointer(pOut, pPtr, zPT); } 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; } |
︙ | ︙ | |||
1390 1391 1392 1393 1394 1395 1396 | Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3_mutex_leave(p->db->mutex); } return rc; } | | | | 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 | 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 *zT){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zT); sqlite3_mutex_leave(p->db->mutex); } return rc; } int sqlite3_bind_text( sqlite3_stmt *pStmt, int i, |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
705 706 707 708 709 710 711 | } } /* ** Set the value stored in *pMem should already be a NULL. ** Also store a pointer to go with it. */ | | > | | | > > | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | } } /* ** 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){ assert( pMem->flags==MEM_Null ); if( zPType ){ pMem->flags = MEM_Null|MEM_Subtype|MEM_Term|MEM_Static; pMem->u.pPtr = pPtr; pMem->eSubtype = 'p'; pMem->z = (char*)zPType; } } #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val, ** manifest type REAL. */ |
︙ | ︙ |