From 3a96a5d91924eb2be3d31fb4f6df220832c77801 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Jun 2017 23:09:03 +0000 Subject: [PATCH 1/5] Add APIs for binding pointers that can be used by app-defined functions. FossilOrigin-Name: d9f4a831ba957ead3890b36d0e33e30cfa4c79b7de6400e623b9746a0a5a02d0 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 25 +++++++++++++++++++++++++ src/vdbeInt.h | 2 ++ src/vdbeapi.c | 24 ++++++++++++++++++++++++ src/vdbemem.c | 11 +++++++++++ 6 files changed, 75 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6134e77a2f..7bacb1143e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdocumentation\sfor\ssqlite3_value_type(). -D 2017-06-30T20:11:45.610 +C Add\sAPIs\sfor\sbinding\spointers\sthat\scan\sbe\sused\sby\sapp-defined\sfunctions. +D 2017-06-30T23:09:03.695 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -450,7 +450,7 @@ F src/resolve.c d1e69759e7a79c156c692793f5d16f82f9a60ce5e82efd95e4374b2423034946 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 741937503c74d85e64828b63d5a4219d3cfce480a717efef635839606001b1ba F src/shell.c a2b148e4ca8eb81b96e1050207c83d4a16ea6bf9182374faee4dd2a43628c291 -F src/sqlite.h.in 731f189fd07c115e274a09f83043f822866144f68861c38a08ea4a977b1fbd84 +F src/sqlite.h.in e1db5dd6c7058352f0853a789a1c5822a83c32450f0c30fa83dd74169e1d2e61 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h 37f1a9a3266aa7b11126585314cd98cf11ba6f174b1244de2221270107ea754d @@ -517,11 +517,11 @@ F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf F src/vdbe.c adc8a378710ec2376101483cc8a5f499539ee9bbebfb2a784f3370704d5d44ad F src/vdbe.h dde459b1e8a02b8445ecfd5959f38cd5ebb6b0ad392d491d8b159ac8193d231a -F src/vdbeInt.h 8dd7548d86a98b77b6ed910d8014d0e9e0666356b56f3d16ab7063aad4f102f5 -F src/vdbeapi.c 899d8f021c89ab348708b3a9b00b855f5ecc3c0f949a75359a61a3c621021281 +F src/vdbeInt.h 7420cd23d2c8810c37c4bb63819bcf124be81e4aeaaab4dacc3cf76fb5457877 +F src/vdbeapi.c 8f830cf2e37929315a09b578a975d77070bad8185ade2006b14e72bf60227f3e F src/vdbeaux.c 32ff5e8a7226c0bc6df0f214a5cc1a76fcc5d8863c491a800ef3d6f5236feae7 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c 8d78df62becfd2dce3c317f64b32a94ecaff8346d814bc8b0b877b38a1ad3718 +F src/vdbemem.c 78dfccca73eba44f4f6988f1f3d6ca93dd6431fcf9e6946945f4505fff1fb03f F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b @@ -1628,7 +1628,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 d076d58ff108d286f7ac1f81e1ce945d6f4a4f5f97e3b8d5cee6f8d9a6c48d8f -R b000ea732df88b8ca94b02ddd6334c48 +P 0db20efe201736b3ebb177948f6a440ce28e62454536a8496fae64a3b55cb702 +R ba965b8e14ab1010e011e2c12b1e3073 +T *branch * bind-pointer +T *sym-bind-pointer * +T -sym-trunk * U drh -Z 9442c52c473ff462a81f68567d54c14b +Z 294aa6db3d1ac71c2ec90e0da2e36fa3 diff --git a/manifest.uuid b/manifest.uuid index 4052db8326..c596f52ada 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0db20efe201736b3ebb177948f6a440ce28e62454536a8496fae64a3b55cb702 \ No newline at end of file +d9f4a831ba957ead3890b36d0e33e30cfa4c79b7de6400e623b9746a0a5a02d0 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3ca909fce4..18487082a6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3881,6 +3881,15 @@ 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 +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P. +** ^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 ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], @@ -3914,6 +3923,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_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4687,6 +4697,11 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** 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)] or [sqlite3_result_pointer(C,P)], then +** sqlite3_value_pointer(V) will return the pointer P. Otherwise, +** sqlite3_value_pointer(V) 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], @@ -4725,6 +4740,7 @@ 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*); +void *sqlite3_value_pointer(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); @@ -5023,6 +5039,14 @@ 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 +** 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 +** [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. @@ -5046,6 +5070,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_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d8e899b0af..c868ea91ed 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -190,6 +190,7 @@ struct sqlite3_value { 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; /* Used when bit MEM_Zero is set in flags */ + void *pPtr; /* Pointer when flags=MEM_NULL and eSubtype='p' */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ @@ -475,6 +476,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64); #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif +void sqlite3VdbeMemSetPointer(Mem*, void*); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index dd5bf68bab..b94faceadd 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -199,6 +199,14 @@ 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){ + Mem *p = (Mem*)pVal; + if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ + return p->u.pPtr; + }else{ + return 0; + } +} const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } @@ -377,6 +385,12 @@ 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){ + Mem *pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetPointer(pOut, pPtr); +} void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); @@ -1380,6 +1394,16 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ } return rc; } +int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} int sqlite3_bind_text( sqlite3_stmt *pStmt, int i, diff --git a/src/vdbemem.c b/src/vdbemem.c index 41bb9b5c43..d73233c0e5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -705,6 +705,17 @@ 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){ + assert( pMem->flags==MEM_Null ); + pMem->flags = MEM_Null|MEM_Subtype; + pMem->u.pPtr = pPtr; + pMem->eSubtype = 'p'; +} + #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val, From 3561dd4afe53f07ececf28e4a46f31925f188de8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Jun 2017 23:46:16 +0000 Subject: [PATCH 2/5] Update the carray() and remember() extension functions so that they user the new sqlite3_value_pointer() interface. FossilOrigin-Name: a99fa94db7185b8eaf3c9b184cb1479f8b3d5781f71f1717a4b3f2dd1d184fe4 --- ext/misc/carray.c | 54 ++++++++++++++++++++++++++++++++++++--------- ext/misc/remember.c | 6 ++--- manifest | 19 +++++++--------- manifest.uuid | 2 +- test/tabfunc01.test | 27 ++++++++++++----------- 5 files changed, 70 insertions(+), 38 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 025eb5db2c..7c12067e5a 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -73,7 +73,7 @@ typedef struct carray_cursor carray_cursor; struct carray_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ sqlite3_int64 iRowid; /* The rowid */ - sqlite3_int64 iPtr; /* Pointer to array of values */ + void *pPtr; /* Pointer to the array of values */ sqlite3_int64 iCnt; /* Number of integers in the array */ unsigned char eType; /* One of the CARRAY_type values */ }; @@ -167,7 +167,7 @@ static int carrayColumn( carray_cursor *pCur = (carray_cursor*)cur; sqlite3_int64 x = 0; switch( i ){ - case CARRAY_COLUMN_POINTER: x = pCur->iPtr; break; + case CARRAY_COLUMN_POINTER: return SQLITE_OK; case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break; case CARRAY_COLUMN_CTYPE: { sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC); @@ -176,22 +176,22 @@ static int carrayColumn( default: { switch( pCur->eType ){ case CARRAY_INT32: { - int *p = (int*)pCur->iPtr; + int *p = (int*)pCur->pPtr; sqlite3_result_int(ctx, p[pCur->iRowid-1]); return SQLITE_OK; } case CARRAY_INT64: { - sqlite3_int64 *p = (sqlite3_int64*)pCur->iPtr; + sqlite3_int64 *p = (sqlite3_int64*)pCur->pPtr; sqlite3_result_int64(ctx, p[pCur->iRowid-1]); return SQLITE_OK; } case CARRAY_DOUBLE: { - double *p = (double*)pCur->iPtr; + double *p = (double*)pCur->pPtr; sqlite3_result_double(ctx, p[pCur->iRowid-1]); return SQLITE_OK; } case CARRAY_TEXT: { - const char **p = (const char**)pCur->iPtr; + const char **p = (const char**)pCur->pPtr; sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT); return SQLITE_OK; } @@ -232,8 +232,8 @@ static int carrayFilter( ){ carray_cursor *pCur = (carray_cursor *)pVtabCursor; if( idxNum ){ - pCur->iPtr = sqlite3_value_int64(argv[0]); - pCur->iCnt = sqlite3_value_int64(argv[1]); + pCur->pPtr = sqlite3_value_pointer(argv[0]); + pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0; if( idxNum<3 ){ pCur->eType = CARRAY_INT32; }else{ @@ -251,7 +251,7 @@ static int carrayFilter( } } }else{ - pCur->iPtr = 0; + pCur->pPtr = 0; pCur->iCnt = 0; } pCur->iRowid = 1; @@ -345,6 +345,34 @@ static sqlite3_module carrayModule = { 0, /* xRename */ }; +/* +** For testing purpose in the TCL test harness, we need a method for +** setting the pointer value. The inttoptr(X) SQL function accomplishes +** this. Tcl script will bind an integer to X and the inttoptr() SQL +** function will use sqlite3_result_pointer() to convert that integer into +** a pointer. +** +** This is for testing on TCL only. +*/ +#ifdef SQLITE_TEST +static void inttoptrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + void *p; + sqlite3_int64 i64; + 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); +} +#endif /* SQLITE_TEST */ + #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifdef _WIN32 @@ -359,6 +387,12 @@ int sqlite3_carray_init( SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "carray", &carrayModule, 0); -#endif +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0, + inttoptrFunc, 0, 0); + } +#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_VIRTUALTABLE */ return rc; } diff --git a/ext/misc/remember.c b/ext/misc/remember.c index aa3eff8a3f..587d44a12c 100644 --- a/ext/misc/remember.c +++ b/ext/misc/remember.c @@ -44,11 +44,11 @@ static void rememberFunc( sqlite3_value **argv ){ sqlite3_int64 v; - sqlite3_int64 ptr; + sqlite3_int64 *ptr; assert( argc==2 ); v = sqlite3_value_int64(argv[0]); - ptr = sqlite3_value_int64(argv[1]); - *((sqlite3_int64*)ptr) = v; + ptr = sqlite3_value_pointer(argv[1]); + if( ptr ) *ptr = v; sqlite3_result_int64(pCtx, v); } diff --git a/manifest b/manifest index 7bacb1143e..9c7fc3fcfe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sAPIs\sfor\sbinding\spointers\sthat\scan\sbe\sused\sby\sapp-defined\sfunctions. -D 2017-06-30T23:09:03.695 +C Update\sthe\scarray()\sand\sremember()\sextension\sfunctions\sso\sthat\sthey\suser\nthe\snew\ssqlite3_value_pointer()\sinterface. +D 2017-06-30T23:46:16.781 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -254,7 +254,7 @@ F ext/lsm1/lsm_win32.c 69eb9fd25197432b084037efd69b365d8182ab1e4372a9c45a9c47e54 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb -F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d +F ext/misc/carray.c 1fbaf9ada5b1919c07a5e76e260a41c13a20fe6d399411e41f1e9cc4a559479f F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 @@ -268,7 +268,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 8440f8d0b452c5cdefb62b57135ccd1267aa729d +F ext/misc/remember.c bee7963ddfa5b0633f4ac13f01cb471ae712f323a87978c9a9a47108b555598f F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c b0f5f346aca9b7ff7caaf0da2efb4ad462441abd4dcd92a460cb573b3ea2370b @@ -1228,7 +1228,7 @@ F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 +F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b969a51 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1628,10 +1628,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 0db20efe201736b3ebb177948f6a440ce28e62454536a8496fae64a3b55cb702 -R ba965b8e14ab1010e011e2c12b1e3073 -T *branch * bind-pointer -T *sym-bind-pointer * -T -sym-trunk * +P d9f4a831ba957ead3890b36d0e33e30cfa4c79b7de6400e623b9746a0a5a02d0 +R b4c2909e137aa3ef17d38c2e54e31341 U drh -Z 294aa6db3d1ac71c2ec90e0da2e36fa3 +Z 8bdfe5f6d40ad5cfb9816549ee2c5181 diff --git a/manifest.uuid b/manifest.uuid index c596f52ada..3149df671b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9f4a831ba957ead3890b36d0e33e30cfa4c79b7de6400e623b9746a0a5a02d0 \ No newline at end of file +a99fa94db7185b8eaf3c9b184cb1479f8b3d5781f71f1717a4b3f2dd1d184fe4 \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index dcaafa420c..7e6a4b10be 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -150,62 +150,63 @@ do_execsql_test tabfunc01-600 { do_test tabfunc01-700 { set PTR1 [intarray_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR1,5) WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR1),5) WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-701 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int32'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int32'); } } {(005) (007) (013) (017) (023)} do_test tabfunc01-702 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR1,4,'int32'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),4,'int32'); } } {(005) (007) (013) (017)} do_catchsql_test tabfunc01-710 { - SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int33'); + SELECT b FROM t600 WHERE a IN carray(inttoptr($PTR1),5,'int33'); } {1 {unknown datatype: 'int33'}} do_test tabfunc01-720 { set PTR2 [int64array_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR2,5,'int64') WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR2),5,'int64') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-721 { db eval { - SELECT remember(123,$PTR2); - SELECT value FROM carray($PTR2,5,'int64'); + SELECT remember(123,inttoptr($PTR2)); + SELECT value FROM carray(inttoptr($PTR2),5,'int64'); } } {123 123 7 13 17 23} do_test tabfunc01-722 { set PTR3 [expr {$PTR2+16}] db eval { - SELECT remember(987,$PTR3); - SELECT value FROM carray($PTR2,5,'int64'); + SELECT remember(987,inttoptr($PTR3)); + SELECT value FROM carray(inttoptr($PTR2),5,'int64'); } } {987 123 7 987 17 23} do_test tabfunc01-730 { set PTR4 [doublearray_addr 5.0 7.0 13.0 17.0 23.0] db eval { - SELECT b FROM t600, carray($PTR4,5,'double') WHERE a=value; + SELECT b FROM t600, carray(inttoptr($PTR4),5,'double') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-740 { set PTR5 [textarray_addr x5 x7 x13 x17 x23] db eval { - SELECT b FROM t600, carray($PTR5,5,'char*') WHERE a=trim(value,'x'); + SELECT b FROM t600, carray(inttoptr($PTR5),5,'char*') + WHERE a=trim(value,'x'); } } {(005) (007) (013) (017) (023)} do_test tabfunc01-750 { db eval { SELECT aa.value, bb.value, '|' - FROM carray($PTR4,5,'double') AS aa - JOIN carray($PTR5,5,'char*') AS bb ON aa.rowid=bb.rowid; + FROM carray(inttoptr($PTR4),5,'double') AS aa + JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid; } } {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} From d43748aa98d0dde766ff473f565da484b005839c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Jul 2017 17:48:14 +0000 Subject: [PATCH 3/5] Update the FTS3 extension to use sqlite3_result_pointer() and sqlite3_value_pointer() for passing FTS3 cursor objects from the table into functions such as snippet(). FossilOrigin-Name: 0fa2e170e5e078d155c98b212ade36bd8424502ae07f2d82ebf77a76f57586ba --- ext/fts3/fts3.c | 10 +++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 31dbefa63b..7f59e331eb 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3353,8 +3353,7 @@ static int fts3ColumnMethod( switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ - sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT); - sqlite3_result_subtype(pCtx, SQLITE_BLOB); + sqlite3_result_pointer(pCtx, pCsr); break; case 1: @@ -3572,9 +3571,10 @@ static int fts3FunctionArg( sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ - int rc = SQLITE_OK; - if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){ - *ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal); + int rc; + *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal); + if( (*ppCsr)!=0 ){ + rc = SQLITE_OK; }else{ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); diff --git a/manifest b/manifest index 8f0c798822..cb473d27b6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\schanges\sfrom\strunk. -D 2017-07-13T17:34:46.253 +C Update\sthe\sFTS3\sextension\sto\suse\ssqlite3_result_pointer()\sand\nsqlite3_value_pointer()\sfor\spassing\sFTS3\scursor\sobjects\sfrom\sthe\stable\ninto\sfunctions\ssuch\sas\ssnippet(). +D 2017-07-13T17:48:14.032 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 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 b47d3ba5c00f550d1f436e62017264fed818665819471b4699aac9527906459b +F ext/fts3/fts3.c 02fbd2215309a7a73cbf29045897344987b6e17bb0b1685d13155f8b29768a50 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -1631,7 +1631,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 73d0fc027ddcc24e55cdc8c54443a96083cc9a29e57c0abe97e8586ff8a7f4c5 0c80593520d30958231be41fc443209eb39e0b3ee0e66308c3ef3a0f4cb8ea66 -R 24fe995205a9d315b689d2540b0fa4a9 +P a54be6e041a9185787a22b86603dcb0654e5e4af71225b556d1b6279f8520ad8 +R 06f4e52cc42a344de01e760ac4095fb4 U drh -Z cbf44fd2ddc942904c634ff7c93b4cf7 +Z 339b64dea01a24343c82d73c9da8b215 diff --git a/manifest.uuid b/manifest.uuid index 3b20dfa83b..05788fb77c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a54be6e041a9185787a22b86603dcb0654e5e4af71225b556d1b6279f8520ad8 \ No newline at end of file +0fa2e170e5e078d155c98b212ade36bd8424502ae07f2d82ebf77a76f57586ba \ No newline at end of file From 5587d86ddd71ef2f8cc20edf7024ff6640278104 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Jul 2017 17:54:12 +0000 Subject: [PATCH 4/5] Add the three new pointer interfaces to the loadable extension mechanism. Update sqlite3_value_subtype() documentation to remove the statement about it not being used internally. FossilOrigin-Name: e5a518038fcb23376d2b17d4d70648320bc5540c5bd8b164201044ebe1ce45c5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 5 ++++- src/sqlite.h.in | 4 ---- src/sqlite3ext.h | 6 ++++++ 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index cb473d27b6..8740c2c081 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sFTS3\sextension\sto\suse\ssqlite3_result_pointer()\sand\nsqlite3_value_pointer()\sfor\spassing\sFTS3\scursor\sobjects\sfrom\sthe\stable\ninto\sfunctions\ssuch\sas\ssnippet(). -D 2017-07-13T17:48:14.032 +C Add\sthe\sthree\snew\spointer\sinterfaces\sto\sthe\sloadable\sextension\smechanism.\nUpdate\ssqlite3_value_subtype()\sdocumentation\sto\sremove\sthe\sstatement\sabout\nit\snot\sbeing\sused\sinternally. +D 2017-07-13T17:54:12.238 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -413,7 +413,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e -F src/loadext.c 15e458a122bccef49850cc1d6b69802040ea3f9022e564a125faf599354fe050 +F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2 F src/main.c 20574bb9a0d7911efcd659ac252f2126dc4e3308bed3c8764ea3fb5a00f70420 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -452,9 +452,9 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 95659b7990e390f9bd8dc30b8975c675fcd1d46e569bc4f5a14e22a8d03e3d14 F src/shell.c 0401a716fc5343594b8ee60ce065d9a71373d3403f0b81f9fed684741e6401d1 F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940cad -F src/sqlite.h.in e8193d6157ba10f6b78a447b41c2ccec431ac8fceb1308cac773829adc791d8a +F src/sqlite.h.in 77f4bee882ad4999bf04cf011e1c4cd7f1c6488e290764f3fb46833810447c5d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 5539ec41f3d81890d626d5a845b08c82bd0e946ddc5c1c341144b700bc56101e +F src/sqlite3ext.h 635712b4108d3ac526a4821d646e9f40f831277ecdb004e73b31f00f3f413493 F src/sqliteInt.h 0ba730cdc8afa723a5642380712f8bb33abd6a69218571c18b94acf3562de22a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 @@ -1631,7 +1631,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 a54be6e041a9185787a22b86603dcb0654e5e4af71225b556d1b6279f8520ad8 -R 06f4e52cc42a344de01e760ac4095fb4 +P 0fa2e170e5e078d155c98b212ade36bd8424502ae07f2d82ebf77a76f57586ba +R 138dbbf6db8f3af3b160229e048b5334 U drh -Z 339b64dea01a24343c82d73c9da8b215 +Z a38953a262acd0f45b83dd587cf33d77 diff --git a/manifest.uuid b/manifest.uuid index 05788fb77c..4864423525 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0fa2e170e5e078d155c98b212ade36bd8424502ae07f2d82ebf77a76f57586ba \ No newline at end of file +e5a518038fcb23376d2b17d4d70648320bc5540c5bd8b164201044ebe1ce45c5 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index b1f1b03e35..6751425936 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -427,7 +427,10 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_set_last_insert_rowid, /* Version 3.20.0 and later */ sqlite3_prepare_v3, - sqlite3_prepare16_v3 + sqlite3_prepare16_v3, + sqlite3_bind_pointer, + sqlite3_result_pointer, + sqlite3_value_pointer }; /* diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3b6c8eb997..5b1bc98567 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4810,10 +4810,6 @@ int sqlite3_value_numeric_type(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. */ unsigned int sqlite3_value_subtype(sqlite3_value*); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 06b5e5b71c..e866a6eb64 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -289,6 +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*); + int (*result_pointer)(sqlite3_context*,void*); + void *(*value_pointer)(sqlite3_value*); }; /* @@ -552,6 +555,9 @@ typedef int (*sqlite3_loadext_entry)( /* Version 3.20.0 and later */ #define sqlite3_prepare_v3 sqlite3_api->prepare_v3 #define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 +#define sqlite3_bind_pointer sqlite3_api->bind_pointer +#define sqlite3_result_pointer sqlite3_api->result_pointer +#define sqlite3_value_pointer sqlite3_api->value_pointer #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From 4c997c6e751909cfc2caa6b7bc187fa6da4ba2fa Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Jul 2017 17:56:52 +0000 Subject: [PATCH 5/5] Fix an incorrect type signature for the loadable extension pointer for sqlite3_result_pointer(). FossilOrigin-Name: 0bd7875bd9948836a14061275eb8ddac627f562a49f59f400ec98c00e2be82c5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite3ext.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8740c2c081..198d4d2a4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sthree\snew\spointer\sinterfaces\sto\sthe\sloadable\sextension\smechanism.\nUpdate\ssqlite3_value_subtype()\sdocumentation\sto\sremove\sthe\sstatement\sabout\nit\snot\sbeing\sused\sinternally. -D 2017-07-13T17:54:12.238 +C Fix\san\sincorrect\stype\ssignature\sfor\sthe\sloadable\sextension\spointer\nfor\ssqlite3_result_pointer(). +D 2017-07-13T17:56:52.837 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -454,7 +454,7 @@ F src/shell.c 0401a716fc5343594b8ee60ce065d9a71373d3403f0b81f9fed684741e6401d1 F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940cad F src/sqlite.h.in 77f4bee882ad4999bf04cf011e1c4cd7f1c6488e290764f3fb46833810447c5d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 635712b4108d3ac526a4821d646e9f40f831277ecdb004e73b31f00f3f413493 +F src/sqlite3ext.h 654d76dd288780a460be9c88edc6a5eb2d61df03a7153c92f1d87aba41f73b96 F src/sqliteInt.h 0ba730cdc8afa723a5642380712f8bb33abd6a69218571c18b94acf3562de22a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 @@ -1631,7 +1631,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 0fa2e170e5e078d155c98b212ade36bd8424502ae07f2d82ebf77a76f57586ba -R 138dbbf6db8f3af3b160229e048b5334 +P e5a518038fcb23376d2b17d4d70648320bc5540c5bd8b164201044ebe1ce45c5 +R c5909f0683f2365e40f92a217eed2222 U drh -Z a38953a262acd0f45b83dd587cf33d77 +Z 36e4bbc5bdc1a46b79fe430f87487a42 diff --git a/manifest.uuid b/manifest.uuid index 4864423525..0f75f066f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5a518038fcb23376d2b17d4d70648320bc5540c5bd8b164201044ebe1ce45c5 \ No newline at end of file +0bd7875bd9948836a14061275eb8ddac627f562a49f59f400ec98c00e2be82c5 \ No newline at end of file diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index e866a6eb64..8d254b236b 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -290,7 +290,7 @@ struct sqlite3_api_routines { int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, sqlite3_stmt**,const void**); int (*bind_pointer)(sqlite3_stmt*,int,void*); - int (*result_pointer)(sqlite3_context*,void*); + void (*result_pointer)(sqlite3_context*,void*); void *(*value_pointer)(sqlite3_value*); };