diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 7f59e331eb..ca17888276 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3353,7 +3353,7 @@ static int fts3ColumnMethod( switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ - sqlite3_result_pointer(pCtx, pCsr); + sqlite3_result_pointer(pCtx, pCsr, "fts3cursor"); break; case 1: @@ -3572,7 +3572,7 @@ static int fts3FunctionArg( Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ int rc; - *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal); + *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor"); if( (*ppCsr)!=0 ){ rc = SQLITE_OK; }else{ diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 82735765fd..b182ea1bcf 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -19,7 +19,12 @@ ** 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. +** 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 @@ -27,6 +32,8 @@ ** ** 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 @@ -233,7 +240,7 @@ static int carrayFilter( ){ carray_cursor *pCur = (carray_cursor *)pVtabCursor; if( idxNum ){ - pCur->pPtr = sqlite3_value_pointer(argv[0]); + 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; @@ -370,7 +377,7 @@ static void inttoptrFunc( int i32 = i64 & 0xffffffff; memcpy(&p, &i32, sizeof(p)); } - sqlite3_result_pointer(context, p); + sqlite3_result_pointer(context, p, "carray"); } #endif /* SQLITE_TEST */ diff --git a/ext/misc/remember.c b/ext/misc/remember.c index 97efb6ae81..18f6edec9d 100644 --- a/ext/misc/remember.c +++ b/ext/misc/remember.c @@ -21,8 +21,12 @@ ** 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()) and -** bind the id of the counter to $ID and run the prepared statement. +** 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. +** +** This implementation of the remember() function uses a "carray" +** pointer so that it can share pointers with the carray() extension. ** ** One can imagine doing similar things with floating-point values and ** strings, but this demonstration extension will stick to using just @@ -47,7 +51,7 @@ static void rememberFunc( sqlite3_int64 *ptr; assert( argc==2 ); v = sqlite3_value_int64(argv[0]); - ptr = sqlite3_value_pointer(argv[1]); + ptr = sqlite3_value_pointer(argv[1], "carray"); if( ptr ) *ptr = v; sqlite3_result_int64(pCtx, v); } diff --git a/manifest b/manifest index a0044545dc..861e277588 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sregister\sallocation\sproblem\sin\sPRAGMA\sintegrity_check\sthat\scaused\nthe\ssame\sregister\sto\sbe\sused\sfor\stwo\sdifferent\spurposes\son\sthe\sfirst\nATTACHed\sdatabase\sif\sthe\sschema\sfor\sthe\sATTACHed\sdatabase\swas\snoticable\nmore\scomplex\sthan\sthe\sschema\sfor\sthe\sfirst\sdatabase.\nFix\sfor\sticket\s[a4e06e75a9ab61a1]. -D 2017-07-15T20:33:19.899 +C Merge\sthe\spointer-type\senhancement\sfrom\sthe\s3.20\sbranch. +D 2017-07-17T13:37:07.979 F Makefile.in eda8bedf08c4c93e2137ef1218b3d3302488c68c2774918de0335a1133aab157 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -70,7 +70,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 02fbd2215309a7a73cbf29045897344987b6e17bb0b1685d13155f8b29768a50 +F ext/fts3/fts3.c dfda8bb464d229785e0528fcf7017b4f8e95656d40d28333dfc3f3363bbe229e F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -256,7 +256,7 @@ F ext/lsm1/test/lsm1_simple.test 3bb38951450cd1f12a6c294949334d6fbb109a3da38c48e F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb -F ext/misc/carray.c 5a330eea8f2f5382f9bd794eb37eadf234c4db190074ea6104cc66d2a724c1d3 +F ext/misc/carray.c 880684b2796ef6ad915094093297eede40db6c07f280c7f491c8eff72ea03ec7 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 @@ -271,7 +271,7 @@ F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 -F ext/misc/remember.c 0cbd7526e1bc956c493ed21125683f8554ef4819982400b65a8da2e4e18e9ecd +F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c b0f5f346aca9b7ff7caaf0da2efb4ad462441abd4dcd92a460cb573b3ea2370b @@ -454,9 +454,9 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 95659b7990e390f9bd8dc30b8975c675fcd1d46e569bc4f5a14e22a8d03e3d14 F src/shell.c e89ad1135cb47c95896a1aec4bd0113af90a057d80f20003f354fa56fc10a616 F src/shell.c.in dae43a6a43988d955014f070341f296561ea4a43ca2685166a32495b0667ef59 -F src/sqlite.h.in 042383fde795a11009248dd465629ef4f08837684820f6c660d3c12dcdc0f706 +F src/sqlite.h.in dad804d4e1979a2ddec33cc8da6aa50c04e6ba0dcb4058e7b3609588d010e041 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 654d76dd288780a460be9c88edc6a5eb2d61df03a7153c92f1d87aba41f73b96 +F src/sqlite3ext.h 967154985ed2ae62f90d9029bb5b5071793d847f1696a2ebe9e8cc0b042ae60b F src/sqliteInt.h 0ba730cdc8afa723a5642380712f8bb33abd6a69218571c18b94acf3562de22a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 @@ -521,11 +521,11 @@ F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf F src/vdbe.c adc8a378710ec2376101483cc8a5f499539ee9bbebfb2a784f3370704d5d44ad F src/vdbe.h 7bf719031782823b915aff2c1f93d1944c1c6b300770a15339b7dbc9610b802e -F src/vdbeInt.h 36b162cce2410f07cc6ad1c4472af7d5e31bcc0b8a532082aa6f2740e124a11f -F src/vdbeapi.c 8f830cf2e37929315a09b578a975d77070bad8185ade2006b14e72bf60227f3e +F src/vdbeInt.h 19bd04a4211fe56c712ab35b48be77fd5a0579b851e9dea2cb8deade359b72b9 +F src/vdbeapi.c f600bf0dfcea8edb0e0a44a98035bbe3310824af18c193ba242449db250627a4 F src/vdbeaux.c 518d1cf6728ecb591390541c58b14902e8d61735ef574426b9971624c54d2c4b F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c 78dfccca73eba44f4f6988f1f3d6ca93dd6431fcf9e6946945f4505fff1fb03f +F src/vdbemem.c fe8fce1cdc258320b465934039fe4b1230d63f81d6b81b1eac775b6eec00af0d F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b @@ -1178,7 +1178,7 @@ F test/shell1.test f78ea0e2637ae9f497cb41206f6346f983052ffc7a359e664aaf6847fc704 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d -F test/shell5.test 0d973866d0df8501486a840f51d1502ab0d9b38ca12c9b242ee26adc788af576 +F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458 F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 @@ -1633,7 +1633,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 687bd478710eb827e041533eea67115464f5a0de767bb6cfdbe36a0d3c597fa1 -R 522613d16f7d47bea7a7f05e6d39255f +P 253945d480b052bfe311888022b5eb0be91c8c80cda05036e58207d57520262c e4579e50a1ece4f65dfdae39d5c1670f0e3f7d4824e7d242f07ec9859d15155f +R 44ab723208e3fb1d41d5a4d6b1798a34 U drh -Z 4ddd385f7f3a9276d818cfc9da4dbe0b +Z 494325537ef296d6ee8662e5f6765eae diff --git a/manifest.uuid b/manifest.uuid index cc1f259bcc..baaa5c4025 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -253945d480b052bfe311888022b5eb0be91c8c80cda05036e58207d57520262c \ No newline at end of file +9e8e1c4aa14bcda165b392d1d8af2ce394a56a8e7b67e4c73c742d8da75e73e2 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9d63a775be..427b6f747e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3883,14 +3883,14 @@ typedef struct sqlite3_context sqlite3_context; ** [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) routine causes the I-th parameter in +** ^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. +** 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()]. +** [sqlite3_value_pointer()]. The T parameter should be a static string. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which @@ -3925,7 +3925,7 @@ 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*); +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); @@ -4758,9 +4758,10 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** 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)] or [sqlite3_result_pointer(C,P)], then -** sqlite3_value_pointer(V) will return the pointer P. Otherwise, -** sqlite3_value_pointer(V) returns a NULL. +** 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 @@ -4794,7 +4795,7 @@ 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*); +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*); @@ -5095,11 +5096,12 @@ typedef void (*sqlite3_destructor_type)(void*); ** [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) interface sets the result to an +** ^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 with that NULL value such -** that the pointer can be retrieved within an +** 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()]. +** The T parameter should be a static string. ** This mechanism can be used to pass non-SQL values between ** application-defined functions. ** @@ -5126,7 +5128,7 @@ 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*); +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); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 8d254b236b..c585f17f2f 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -289,9 +289,9 @@ struct sqlite3_api_routines { sqlite3_stmt**,const char**); int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, sqlite3_stmt**,const void**); - int (*bind_pointer)(sqlite3_stmt*,int,void*); - void (*result_pointer)(sqlite3_context*,void*); - void *(*value_pointer)(sqlite3_value*); + int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*); + void (*result_pointer)(sqlite3_context*,void*,const char*); + void *(*value_pointer)(sqlite3_value*,const char*); }; /* diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 2d8d3652f4..599fe70414 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -476,7 +476,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64); #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif -void sqlite3VdbeMemSetPointer(Mem*, void*); +void sqlite3VdbeMemSetPointer(Mem*, void*, const char*); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b94faceadd..3646d497a6 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -199,9 +199,13 @@ 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){ +void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ Mem *p = (Mem*)pVal; - if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ + 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; @@ -385,11 +389,11 @@ 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){ +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); + sqlite3VdbeMemSetPointer(pOut, pPtr, zPT); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; @@ -1394,12 +1398,12 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ } return rc; } -int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ +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); + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zT); sqlite3_mutex_leave(p->db->mutex); } return rc; diff --git a/src/vdbemem.c b/src/vdbemem.c index d73233c0e5..eac3b9ed3e 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -709,11 +709,14 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ ** 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){ +void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr, const char *zPType){ assert( pMem->flags==MEM_Null ); - pMem->flags = MEM_Null|MEM_Subtype; - pMem->u.pPtr = pPtr; - pMem->eSubtype = 'p'; + 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 diff --git a/test/shell5.test b/test/shell5.test index 62b91ffa85..72f20ca3a6 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -188,7 +188,8 @@ do_test shell5-1.4.10.2 { # do_test shell5-1.4.11 { set in [open shell5.csv wb] - puts $in "\xef\xbb\xbf2|3" + puts -nonewline $in "\xef\xbb\xbf" + puts $in "2|3" puts $in "4|5" close $in set res [catchcmd "test.db" {CREATE TABLE t2(x INT, y INT);