]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add alternative sqlite3_carray_bind_v2() interface.
authordrh <>
Mon, 26 Jan 2026 13:44:42 +0000 (13:44 +0000)
committerdrh <>
Mon, 26 Jan 2026 13:44:42 +0000 (13:44 +0000)
FossilOrigin-Name: 925384d7711867428644595c0903682e6e365eb974c57e6680b51d511c980054

manifest
manifest.uuid
src/carray.c
src/sqlite.h.in
src/sqlite3ext.h
src/test1.c
test/carray01.test

index 12036b048200740a6b3711da3f0b1504f8f146b8..bcb5a027931cd72e66fc87ac03b0cac94d2c6232 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sspeedtest1.wasm\sbuild\sregression\sintroduced\swith\sEmscripten\s5.0.0.
-D 2026-01-26T10:53:24.426
+C Add\salternative\ssqlite3_carray_bind_v2()\sinterface.
+D 2026-01-26T13:44:42.812
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -683,7 +683,7 @@ F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
 F src/build.c 4e1afafc56504ed6253e1b115c1502de4243c2287a0c799f4967fcd2d7716ad9
 F src/callback.c 3605bbf02bd7ed46c79cd48346db4a32fc51d67624400539c0532f4eead804ad
-F src/carray.c ff6081a31878fc34df8fa1052a9cbf17ddc22652544dcb3e2326886ed1053b55
+F src/carray.c 3efe3982d5fb323334c29328a4e189ccaef6b95612a6084ad5fa124fd5db1179
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
 F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
@@ -740,16 +740,16 @@ F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c 65d7ffa2af9670b5e9ca2b23a98a92cd4a32c12b098edeff80e6df61da9b9a6e
 F src/shell.c.in e8818572acd50464bc00426fe0d755e98239f73d531437c3dc7721d1fecb1231
-F src/sqlite.h.in 69eccc01b4c0ff8e8c830e1961971290f1b94d46dc59cfd40f82d26cb9331eb0
+F src/sqlite.h.in 8bcbaecfe2cbecf8c5c1381354fcdd7d307443e88b4953fccb222456c1267b61
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
-F src/sqlite3ext.h f590cd8cb4c36fc727632c9b5fbbafc85f7efe2c6890f9958d7e711dc26ec01e
+F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
 F src/sqliteInt.h f4b50f8c287b858bb23dd51daee29ff424697be9a0753cf37df98fbe1806125b
 F src/sqliteLimit.h 904a3f520362c7065c18165aaabd504fb13cc1b76cb411f38bd41ac219e4af1e
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c 85b5a20df96016e5d1d8fdc68c8a4c279c5b93e2049b77cd806c2cc50b9d8c56
 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
-F src/test1.c 2986148389a86555db7e6b731767154f165a2c7bc690131f90596fa6263fe79d
+F src/test1.c 302cc00a5f0bbfa36d73b299d600c073b02ffa7f2b59fd2c81091983ccd574a8
 F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
 F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
 F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
@@ -955,7 +955,7 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
 F test/capi3c.test 31d3a6778f2d06f2d9222bd7660c41a516d1518a059b069e96ebbeadb5a490f7
 F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde
 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
-F test/carray01.test 49e2aedfdf2c715bc002d2773cdc1217166679639542c79c8aa4115f06421407
+F test/carray01.test 17c1cf8287862b15dda949dba626fd5fee5c58471dcc1cae0341471c2ae7da01
 F test/carray02.test 9d070b54f24a34d1f3b3c552ba34db0375a9d1c4219067416fb07d1595987c9d
 F test/carrayfault.test 108a7d83904fc267c448e27c13b2a857c700bd6ddaa2f1e2518be718b159cb6b
 F test/cast.test a2a3b32df86e3c0601ffa2e9f028a18796305d251801efea807092dbf374a040
@@ -2193,8 +2193,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P c38797d400dc4135108a6e303f2c10779ba9adf0daae28f1789f9106a68d21d5
-R 548ba2dbbfa7fb559bd775cbf8869e64
-U stephan
-Z f43acac73851a6860774192e86d8201c
+P 4733d351ec2376291f093ba8d2ba71d82c6f100c68dc860eee0532986c154e71
+R 6915ffc4b5955ec1130e76c663a36e6f
+U drh
+Z f6d7b74ce0e68fae0513da37a10a7a67
 # Remove this line to create a well-formed Fossil manifest.
index fb4f2f09304781287da67cc147451d0d9afaad55..d41034337cc3f7eafbf1e535013c971d316382ec 100644 (file)
@@ -1 +1 @@
-4733d351ec2376291f093ba8d2ba71d82c6f100c68dc860eee0532986c154e71
+925384d7711867428644595c0903682e6e365eb974c57e6680b51d511c980054
index 154d107ddf8ae65932e41da52cad8095bd5384f3..ff0691a8514ad0188cd3594810fe3aec2f20ca61 100644 (file)
@@ -79,6 +79,7 @@ struct carray_bind {
   int nData;                  /* Number of elements */
   int mFlags;                 /* Control flags */
   void (*xDel)(void*);        /* Destructor for aData */
+  void *pDel;                 /* Alternative argument to xDel() */
 };
 
 
@@ -411,7 +412,7 @@ static sqlite3_module carrayModule = {
 static void carrayBindDel(void *pPtr){
   carray_bind *p = (carray_bind*)pPtr;
   if( p->xDel!=SQLITE_STATIC ){
-     p->xDel(p->aData);
+    p->xDel(p->pDel);
   }
   sqlite3_free(p);
 }
@@ -419,14 +420,26 @@ static void carrayBindDel(void *pPtr){
 /*
 ** Invoke this interface in order to bind to the single-argument
 ** version of CARRAY().
+**
+**    pStmt        The prepared statement to which to bind
+**    idx          The index of the parameter of pStmt to which to bind
+**    aData        The data to be bound
+**    nData        The number of elements in aData
+**    mFlags       One of SQLITE_CARRAY_xxxx indicating datatype of aData
+**    xDestroy     Destructor for pDestroy or aData if pDestroy==NULL.
+**    pDestroy     Invoke xDestroy on this pointer if not NULL
+**
+** The destructor is called pDestroy if pDestroy!=NULL, or against
+** aData if pDestroy==NULL.
 */
-SQLITE_API int sqlite3_carray_bind(
+SQLITE_API int sqlite3_carray_bind_v2(
   sqlite3_stmt *pStmt,
   int idx,
   void *aData,
   int nData,
   int mFlags,
-  void (*xDestroy)(void*)
+  void (*xDestroy)(void*),
+  void *pDestroy
 ){
   carray_bind *pNew = 0;
   int i;
@@ -503,20 +516,38 @@ SQLITE_API int sqlite3_carray_bind(
       memcpy(pNew->aData, aData, sz);
     }
     pNew->xDel = sqlite3_free;
+    pNew->pDel = pNew->aData;
   }else{
     pNew->aData = aData;
     pNew->xDel = xDestroy;
+    pNew->pDel = pDestroy;
   }
   return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
  
  carray_bind_error:
   if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
-    xDestroy(aData);
+    xDestroy(pDestroy);
   }
   sqlite3_free(pNew);
   return rc;
 }
 
+/*
+** Invoke this interface in order to bind to the single-argument
+** version of CARRAY().  Same as sqlite3_carray_bind_v2() with the
+** pDestroy parameter set to NULL.
+*/
+SQLITE_API int sqlite3_carray_bind(
+  sqlite3_stmt *pStmt,
+  int idx,
+  void *aData,
+  int nData,
+  int mFlags,
+  void (*xDestroy)(void*)
+){
+  return sqlite3_carray_bind_v2(pStmt,idx,aData,nData,mFlags,xDestroy,aData);
+}
+
 /*
 ** Invoke this routine to register the carray() function.
 */
index 67e03ef3870f8e8e28859edad7f452e026f964c0..e1f478a0a9e8a2d914f7f37c8070b6387f04fd91 100644 (file)
@@ -11252,19 +11252,41 @@ int sqlite3_deserialize(
 /*
 ** CAPI3REF: Bind array values to the CARRAY table-valued function
 **
-** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to
-** one of the first argument of the [carray() table-valued function].  The
-** S parameter is a pointer to the [prepared statement] that uses the carray()
-** functions.  I is the parameter index to be bound.  P is a pointer to the
-** array to be bound, and N is the number of eements in the array.  The
-** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
-** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
-** indicate the datatype of the array being bound.  The X argument is not a
-** NULL pointer, then SQLite will invoke the function X on the P parameter
-** after it has finished using P, even if the call to
-** sqlite3_carray_bind() fails. The special-case finalizer
-** SQLITE_TRANSIENT has no effect here.
-*/
+** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to
+** parameter that is the first argument of the [carray() table-valued function].
+** The S parameter is a pointer to the [prepared statement] that uses the carray()
+** functions.  I is the parameter index to be bound.  I must be the index of the
+** parameter that is the first argument to the carray() table-valued function.
+** P is a pointer to the array to be bound, and N is the number of elements in
+** the array.  The F argument is one of constants [SQLITE_CARRAY_INT32],
+** [SQLITE_CARRAY_INT64], [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT],
+** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P.
+**
+** If the X argument is not a NULL pointer or one of the special
+** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke
+** the function X with argument D when it is finished using the data in P.
+** The call to X(D) is a destructor for the array P. The destructor X(D)
+** is invoked even if the call to sqlite3_carray_bind() fails. If the X 
+** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes
+** that the data static and the destructor is never invoked.  If the X
+** parameter is the special-case value [SQLITE_TRANSIENT], then
+** sqlite3_carray_bind_v2() makes its own private copy of the data prior
+** to returning and never invokes the destructor X.
+**
+** The sqlite3_carray_bind() function works the same as sqlite_carray_bind_v2()
+** with a D parameter set to P.  In other words,
+** sqlite3_carray_bind(S,I,P,N,F,X) is same as
+** sqlite3_carray_bind(S,I,P,N,F,X,P).
+*/
+int sqlite3_carray_bind_v2(
+  sqlite3_stmt *pStmt,        /* Statement to be bound */
+  int i,                      /* Parameter index */
+  void *aData,                /* Pointer to array data */
+  int nData,                  /* Number of data elements */
+  int mFlags,                 /* CARRAY flags */
+  void (*xDel)(void*),        /* Destructor for aData */
+  void *pDel                  /* Optional argument to xDel() */
+);
 int sqlite3_carray_bind(
   sqlite3_stmt *pStmt,        /* Statement to be bound */
   int i,                      /* Parameter index */
index 36c35b7b104b11548a812b40f7a83feda11a8ed5..cad1a2a0016041b2c400bf0f350a88489c6dcd16 100644 (file)
@@ -375,6 +375,7 @@ struct sqlite3_api_routines {
   void (*str_truncate)(sqlite3_str*,int);
   void (*str_free)(sqlite3_str*);
   int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
+  int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
 };
 
 /*
@@ -717,6 +718,7 @@ typedef int (*sqlite3_loadext_entry)(
 #define sqlite3_str_truncate           sqlite3_api->str_truncate
 #define sqlite3_str_free               sqlite3_api->str_free
 #define sqlite3_carray_bind            sqlite3_api->carray_bind
+#define sqlite3_carray_bind_v2         sqlite3_api->carray_bind_v2
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
index 6f2e2e94edc2541d7f396b84205252d3b5b80acc..230034fa011eb21acfa259a7dc2fa082d9dcc922 100644 (file)
@@ -4411,7 +4411,7 @@ static void delIntptr(void *p){
 }
 
 /*
-** bind_carray_intptr STMT IPARAM  INT0 INT1 INT2...
+** bind_carray_intptr STMT IPARAM INT-0 INT-1 INT-2...
 */
 static int SQLITE_TCLAPI bind_carray_intptr(
   void * clientData,
@@ -4455,6 +4455,7 @@ static int SQLITE_TCLAPI bind_carray_intptr(
 **    -malloc
 **    -transient
 **    -static
+**    -v2
 **    -int32
 **    -int64
 **    -double
@@ -4477,6 +4478,7 @@ static int SQLITE_TCLAPI test_carray_bind(
   void *aData = 0;
   int isTransient = 0;
   int isStatic = 0;
+  int isV2 = 0;
   int isMalloc = 0;               /* True to use custom xDel function */
   int idx;
   int i, j;
@@ -4509,16 +4511,22 @@ static int SQLITE_TCLAPI test_carray_bind(
     const char *z = Tcl_GetString(objv[i]);
     if( strcmp(z, "-transient")==0 ){
       isTransient = 1;
+      isStatic = isMalloc = 0;
       xDel = SQLITE_TRANSIENT;
     }else
     if( strcmp(z, "-static")==0 ){
       isStatic = 1;
+      isMalloc = isTransient = 0;
       xDel = SQLITE_STATIC;
     }else
     if( strcmp(z, "-malloc")==0 ){
       isMalloc = 1;
+      isStatic = isTransient = 0;
       xDel = testCarrayFree;
     }else
+    if( strcmp(z, "-v2")==0 ){
+      isV2 = 1;
+    }else
     if( strcmp(z, "-int32")==0 ){
       eType = 0;  /* CARRAY_INT32 */
     }else
@@ -4687,7 +4695,20 @@ static int SQLITE_TCLAPI test_carray_bind(
 
   if( rc==SQLITE_OK ){
     if( mFlagsOverride==0 ) mFlagsOverride = eType;
-    rc = sqlite3_carray_bind(pStmt, idx, aData, nData, mFlagsOverride, xDel);
+    if( isV2 ){
+      void *pDel;
+      if( xDel==testCarrayFree ){
+        u8 *p2 = (u8*)aData;
+        pDel = (void*)&p2[-16];
+        xDel = sqlite3_free;
+      }else{
+        pDel = aData;
+      }
+      rc = sqlite3_carray_bind_v2(pStmt, idx, aData, nData, mFlagsOverride,
+                                  xDel, pDel);
+    }else{
+      rc = sqlite3_carray_bind(pStmt, idx, aData, nData, mFlagsOverride, xDel);
+    }
   }
   if( isTransient ){
     if( eType==3 && aData ){
index 86ea069961a90350bc20b38f1da220f7a574e64e..b17a481e1bc476fd5aa6be2a02eb2e59dbe7970b 100644 (file)
@@ -51,6 +51,10 @@ do_test 101 {
   run_stmt $STMT
 } {1}
 do_test 102 {
+  sqlite3_carray_bind -v2 -malloc $STMT 3 1 2 3 4 5 6 7
+  run_stmt $STMT
+} {1}
+do_test 103 {
   set STMT2 [sqlite3_prepare_v2 db {
        SELECT DISTINCT typeof(value) FROM carray(?3)} -1]
   sqlite3_carray_bind $STMT2 3 1 2 3 4 5 6 7
@@ -124,6 +128,10 @@ do_test 160 {
   sqlite3_carray_bind -double $STMT 3 1 2 3 4 5 6 7
   run_stmt $STMT
 } {1}
+do_test 161 {
+  sqlite3_carray_bind -double -v2 $STMT 3 1 2 3 4 5 6 7
+  run_stmt $STMT
+} {1}
 do_test 170 {
   sqlite3_carray_bind -text -static $STMT 3 1 2 3 4 6 7
   run_stmt $STMT