]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add an experimental "pointer type" parameter to sqlite3_bind_pointer(),
authordrh <drh@noemail.net>
Mon, 17 Jul 2017 00:40:19 +0000 (00:40 +0000)
committerdrh <drh@noemail.net>
Mon, 17 Jul 2017 00:40:19 +0000 (00:40 +0000)
sqlite3_result_pointer(), and sqlite3_value_pointer().  The pointer type is
a string that must compare equal using strcmp() or else the pointer comes
through as a NULL.

FossilOrigin-Name: 211cce04e97d2e325a6ea3e99738fc71115d673dc13daeffb03ac3140deb11de

ext/fts3/fts3.c
ext/misc/carray.c
ext/misc/remember.c
manifest
manifest.uuid
src/sqlite.h.in
src/sqlite3ext.h
src/vdbeInt.h
src/vdbeapi.c
src/vdbemem.c

index 7f59e331ebf725c1aa106ec24da7a3016bedb36c..ca17888276b317f7d7b7e1e39e160c3cc15178b0 100644 (file)
@@ -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{
index 82735765fd8f2ea4c67e5eec4ab0d6769c01aee7..b182ea1bcf22b30ef7dbb234540d7115143ac27d 100644 (file)
 ** 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 */
 
index 97efb6ae81b7c48e4053e79f99403c21c0dd0fab..b6ab2af2534df85ad504c06865fc92c13d21e361 100644 (file)
@@ -21,8 +21,9 @@
 **    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.
 **
 ** One can imagine doing similar things with floating-point values and
 ** strings, but this demonstration extension will stick to using just
@@ -47,7 +48,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);
 }
index e859ce2f5a012cde16abbe5ebc4d224b9ef4f036..918dbe8065d899cb3a3a92089eba4bc84fab121f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\sfix\sfor\sticket\s[a4e06e75a9ab61a12]\sfrom\strunk.
-D 2017-07-15T20:44:33.555
+C Add\san\sexperimental\s"pointer\stype"\sparameter\sto\ssqlite3_bind_pointer(),\nsqlite3_result_pointer(),\sand\ssqlite3_value_pointer().\s\sThe\spointer\stype\sis\na\sstring\sthat\smust\scompare\sequal\susing\sstrcmp()\sor\selse\sthe\spointer\scomes\nthrough\sas\sa\sNULL.
+D 2017-07-17T00:40:19.127
 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 9b9e220ca9d08466508018a9643d4a367bc03bb038d5213c21f70ab74bfc7f20
 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 07edd8c96112acb8b8f5e4a6d0c404bef0796484cd1d28408f6ec7a4b3f96f97
 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 c42a2f0a34dc202aeee6ae33de4e2f7634a1b56ff31f1214f7f77443d5e51ed2
 F src/vdbeaux.c 518d1cf6728ecb591390541c58b14902e8d61735ef574426b9971624c54d2c4b
 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
-F src/vdbemem.c 78dfccca73eba44f4f6988f1f3d6ca93dd6431fcf9e6946945f4505fff1fb03f
+F src/vdbemem.c cdc72bb347aab890d50346cfc5b4f6a074c84c9c239139070652dbd90f915b6c
 F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
@@ -1633,7 +1633,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 47cf83a0682b7b3219cf255457f5fbe05f3c1f46be42f6bbab33b78a57a252f6 253945d480b052bfe311888022b5eb0be91c8c80cda05036e58207d57520262c
-R fc177602ad383f813078bc7976231f1f
+P b64d64c84484162d1822430036ba0483365a39ef4cf82cd6a7b9436d9e9f50c8
+R c8735c4bec2daec9a986616d49ca5640
+T *branch * pointer-types
+T *sym-pointer-types *
+T -sym-branch-3.20 *
 U drh
-Z 72e0051f8920101ae819b65d7e9be4d4
+Z 0bdcc63008f6f6671f1faf99a5a3de4d
index c774bc0dfdcb5a9068e49667dfdf1b26fe90cb87..2f32d8b627d2fbdf82c2e63358b1af60d93355d7 100644 (file)
@@ -1 +1 @@
-b64d64c84484162d1822430036ba0483365a39ef4cf82cd6a7b9436d9e9f50c8
\ No newline at end of file
+211cce04e97d2e325a6ea3e99738fc71115d673dc13daeffb03ac3140deb11de
\ No newline at end of file
index 9d63a775bef87754dd5b670a98ab32dc6076f171..4b3b0bc814f42ed1f1b35b2b634fcbb47a7f9805 100644 (file)
@@ -3883,9 +3883,9 @@ 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
@@ -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,10 +5096,10 @@ 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()].
 ** This mechanism can be used to pass non-SQL values between
 ** application-defined functions.
@@ -5126,7 +5127,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);
 
index 8d254b236b3501adad2a214cf6dbacc30400a442..c585f17f2f9567901b065eb59fa1e0c646f4bb65 100644 (file)
@@ -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*);
 };
 
 /*
index 2d8d3652f491aedf3bdb0438403a3b31e265590d..599fe704145688ff298fcafc762ace3b9faa8321 100644 (file)
@@ -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);
index b94faceadd208123d3f46aeabda8632ab7618bca..9de24863356d4aee8717d57a350343f34b211660 100644 (file)
@@ -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_TypeMask)==(MEM_Null|MEM_Subtype)
+   && 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;
index d73233c0e5604a9e7e58b4471d434a3f48363e5d..64f7c3d6343900375e0344b8666e3fab40c0dca8 100644 (file)
@@ -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;
+    pMem->u.pPtr = pPtr;
+    pMem->eSubtype = 'p';
+    pMem->z = (char*)zPType;
+  }
 }
 
 #ifndef SQLITE_OMIT_FLOATING_POINT