From 913dcaf0ca06a75e4d8e3aae2eee67ea782bf5bf Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 22 Dec 2022 10:53:08 +0000 Subject: [PATCH 001/165] sessionfuzz.c: use lt/gt brackets instead of double-quotes when #including zlib.h, as reported in [forum:91a104bd65 | forum post 91a104bd65]. FossilOrigin-Name: 7d7780c350f3239f9c9feb91924a01a4eba31b88060946c766719c9d50c16bcd --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sessionfuzz.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index cf2db3b182..a416ddaffd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sefficient\simplementation\sof\slarge\sprecisions\son\sthe\s"%c"\sformat\sfor\nthe\sbuilt-in\sprintf().\s\sThis\sis\san\seffort\sto\savoid\sa\sreported\ntimeout\son\sa\s(ridiculous)\squery\sgenerated\sby\sOSSFuzz. -D 2022-12-21T19:11:56.600 +C sessionfuzz.c:\suse\slt/gt\sbrackets\sinstead\sof\sdouble-quotes\swhen\s#including\szlib.h,\sas\sreported\sin\s[forum:91a104bd65\s|\sforum\spost\s91a104bd65]. +D 2022-12-22T10:53:08.958 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1488,7 +1488,7 @@ F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d785dc4 F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb -F test/sessionfuzz.c f74c4e806bab5a093fb9c11b6123d17a6e0cf73fb7a0f49b12f5a75bf0b7b1a8 +F test/sessionfuzz.c 5eef09af01eeff6f20250ae4c0112c2e576e4d2f2026cc9a49dc5be6886fa6ee F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test f8cd07c1a2b7cdb315c01671a0b2f8e3830b11ef31da6baa9a9cd8da88965403 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 40549bacb3923e439627b0103bedd7da30258b69a46960040f7176e060f51f2f -R b8948321b04d25266ba13687cc331ab6 -U drh -Z fb87aea17e86619f82d9de43213241b3 +P 371f9b88387a44a5f820279d79733d1deb7eafc72f320ec47a11679bbdbb49ef +R 628eedf5dffe439daf55d651e55cc62e +U stephan +Z 8e36eea40550d456da71194c9dffe516 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3a6089430d..c2acbc29bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -371f9b88387a44a5f820279d79733d1deb7eafc72f320ec47a11679bbdbb49ef \ No newline at end of file +7d7780c350f3239f9c9feb91924a01a4eba31b88060946c766719c9d50c16bcd \ No newline at end of file diff --git a/test/sessionfuzz.c b/test/sessionfuzz.c index d8cc1bebfb..f2e4cd5a68 100644 --- a/test/sessionfuzz.c +++ b/test/sessionfuzz.c @@ -699,7 +699,7 @@ static const char zHelp[] = #include #include #ifndef OMIT_ZLIB -#include "zlib.h" +#include #endif /* From 57366d8cec951518cb34de0600ef45f3672703ce Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Dec 2022 17:36:02 +0000 Subject: [PATCH 002/165] Small performance optimization on the OP_Insert opcode. FossilOrigin-Name: 781fdcb9ce85aa2844ef8c00cf908f1a87eeff80dadaf73a71f88b4279260e57 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a416ddaffd..b45d071541 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C sessionfuzz.c:\suse\slt/gt\sbrackets\sinstead\sof\sdouble-quotes\swhen\s#including\szlib.h,\sas\sreported\sin\s[forum:91a104bd65\s|\sforum\spost\s91a104bd65]. -D 2022-12-22T10:53:08.958 +C Small\sperformance\soptimization\son\sthe\sOP_Insert\sopcode. +D 2022-12-22T17:36:02.174 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -717,7 +717,7 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 5c66a10b2372082fb8eb06caef7617cc23e832a6b689e3163305caee6191da6d +F src/vdbe.c 03185a27a021df4209dcca057881d56707bdaa926e6c63d65ad6c4ff57f53875 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h 8651e4c4e04d1860d0bdcf330cb8294e3778a9d4222be30ce4c490d9220af783 F src/vdbeapi.c df3f73a4d0a487f2068e3c84776cd6e3fba5ae80ff612659dcfda4307686420b @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 371f9b88387a44a5f820279d79733d1deb7eafc72f320ec47a11679bbdbb49ef -R 628eedf5dffe439daf55d651e55cc62e -U stephan -Z 8e36eea40550d456da71194c9dffe516 +P 7d7780c350f3239f9c9feb91924a01a4eba31b88060946c766719c9d50c16bcd +R a79a9647bde3a72723a187f1de5c75d2 +U drh +Z caedf858b975dd266664ead43db463b2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c2acbc29bc..c783207052 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d7780c350f3239f9c9feb91924a01a4eba31b88060946c766719c9d50c16bcd \ No newline at end of file +781fdcb9ce85aa2844ef8c00cf908f1a87eeff80dadaf73a71f88b4279260e57 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bd8f57791e..bd540e97e9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5559,8 +5559,11 @@ case OP_Insert: { if( pOp->p5 & OPFLAG_ISNOOP ) break; #endif - if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; + assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); + if( pOp->p5 & OPFLAG_NCHANGE ){ + p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; + } assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); x.pData = pData->z; x.nData = pData->n; From c2d853e56249bbf5c570178ee916fdd9ec24cad8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Dec 2022 18:35:21 +0000 Subject: [PATCH 003/165] Small performance optimization associated with shared cache in the byte-code engine. FossilOrigin-Name: 3181331c1c0259d5cd274dcb33faba930dae51b1f0fe51e8a0318d9c564b94f9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b45d071541..579c9a34b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\son\sthe\sOP_Insert\sopcode. -D 2022-12-22T17:36:02.174 +C Small\sperformance\soptimization\sassociated\swith\sshared\scache\sin\sthe\s\nbyte-code\sengine. +D 2022-12-22T18:35:21.964 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -717,7 +717,7 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 03185a27a021df4209dcca057881d56707bdaa926e6c63d65ad6c4ff57f53875 +F src/vdbe.c 2cb6f6b38b2cc50035d491b367efd17cde7b9fa516d034770070cee22b15238d F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h 8651e4c4e04d1860d0bdcf330cb8294e3778a9d4222be30ce4c490d9220af783 F src/vdbeapi.c df3f73a4d0a487f2068e3c84776cd6e3fba5ae80ff612659dcfda4307686420b @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7d7780c350f3239f9c9feb91924a01a4eba31b88060946c766719c9d50c16bcd -R a79a9647bde3a72723a187f1de5c75d2 +P 781fdcb9ce85aa2844ef8c00cf908f1a87eeff80dadaf73a71f88b4279260e57 +R 6ad8f3aec031a59c06fb544af5840d29 U drh -Z caedf858b975dd266664ead43db463b2 +Z 6be85e967e4dcdafadc5fb2522e97361 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c783207052..d665aec528 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -781fdcb9ce85aa2844ef8c00cf908f1a87eeff80dadaf73a71f88b4279260e57 \ No newline at end of file +3181331c1c0259d5cd274dcb33faba930dae51b1f0fe51e8a0318d9c564b94f9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bd540e97e9..543f16c0de 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -734,7 +734,7 @@ int sqlite3VdbeExec( /*** INSERT STACK UNION HERE ***/ assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ - sqlite3VdbeEnter(p); + if( !DbMaskAllZero(p->lockMask) )sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; @@ -8830,7 +8830,7 @@ vdbe_return: } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - sqlite3VdbeLeave(p); + if( !DbMaskAllZero(p->lockMask) ) sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); From edc2713fdc8cecfcc2821da5469bd609418db174 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Dec 2022 18:44:39 +0000 Subject: [PATCH 004/165] Rename the Vdbe.pResultSet field to pResultRow in order to better distinguish it from other variables with similar names. FossilOrigin-Name: 1fd6211ef7bd26ed625177bfedfd5153ace547de6a71365ecfa076578d043f1a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 6 +++--- src/vdbeInt.h | 2 +- src/vdbeapi.c | 6 +++--- src/vdbeaux.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 579c9a34b8..96d254eae2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sassociated\swith\sshared\scache\sin\sthe\s\nbyte-code\sengine. -D 2022-12-22T18:35:21.964 +C Rename\sthe\sVdbe.pResultSet\sfield\sto\spResultRow\sin\sorder\sto\sbetter\sdistinguish\nit\sfrom\sother\svariables\swith\ssimilar\snames. +D 2022-12-22T18:44:39.948 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -717,11 +717,11 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 2cb6f6b38b2cc50035d491b367efd17cde7b9fa516d034770070cee22b15238d +F src/vdbe.c 6be002bb5faa47de14fe1dc31082f969ef1814ce48b527d7f24cf315b7339933 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c -F src/vdbeInt.h 8651e4c4e04d1860d0bdcf330cb8294e3778a9d4222be30ce4c490d9220af783 -F src/vdbeapi.c df3f73a4d0a487f2068e3c84776cd6e3fba5ae80ff612659dcfda4307686420b -F src/vdbeaux.c 25691b395bf57ae0a754570fc3ba2d6f8bd2f0a8944f1d2589b9e68114e01c2b +F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 +F src/vdbeapi.c a9ddd91f1907023efd3035642d4bd47cf65effcbeae211d6af4aa2426687e552 +F src/vdbeaux.c f01f4c96c836b9d2c7749ddcef2a779cab3974f478a4034389fd3c59c055749a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 6cfed43758d57b6e3b99d9cdedfeccd86e45a07e427b22d8487cbdbebb6c522a F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 781fdcb9ce85aa2844ef8c00cf908f1a87eeff80dadaf73a71f88b4279260e57 -R 6ad8f3aec031a59c06fb544af5840d29 +P 3181331c1c0259d5cd274dcb33faba930dae51b1f0fe51e8a0318d9c564b94f9 +R 9394973e55c6ccfeb1c979e40b4ba15e U drh -Z 6be85e967e4dcdafadc5fb2522e97361 +Z 82b58542dbd948888420949bdd4642ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d665aec528..8db7649c83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3181331c1c0259d5cd274dcb33faba930dae51b1f0fe51e8a0318d9c564b94f9 \ No newline at end of file +1fd6211ef7bd26ed625177bfedfd5153ace547de6a71365ecfa076578d043f1a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 543f16c0de..1ed7216d1d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -755,7 +755,7 @@ int sqlite3VdbeExec( assert( p->bIsReader || p->readOnly!=0 ); p->iCurrentTime = 0; assert( p->explain==0 ); - p->pResultSet = 0; + p->pResultRow = 0; db->busyHandler.nBusy = 0; if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); @@ -1586,10 +1586,10 @@ case OP_ResultRow: { assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); p->cacheCtr = (p->cacheCtr + 2)|1; - p->pResultSet = &aMem[pOp->p1]; + p->pResultRow = &aMem[pOp->p1]; #ifdef SQLITE_DEBUG { - Mem *pMem = p->pResultSet; + Mem *pMem = p->pResultRow; int i; for(i=0; ip2; i++){ assert( memIsValid(&pMem[i]) ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index cd112e9c48..03f4ec5429 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -454,7 +454,7 @@ struct Vdbe { int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Slots allocated for aOp[] */ Mem *aColName; /* Column names to return */ - Mem *pResultSet; /* Pointer to an array of results */ + Mem *pResultRow; /* Current output row */ char *zErrMsg; /* Error message written here */ VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 414745e8ba..34727c30ed 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1117,7 +1117,7 @@ int sqlite3_column_count(sqlite3_stmt *pStmt){ */ int sqlite3_data_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; - if( pVm==0 || pVm->pResultSet==0 ) return 0; + if( pVm==0 || pVm->pResultRow==0 ) return 0; return pVm->nResColumn; } @@ -1172,8 +1172,8 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ if( pVm==0 ) return (Mem*)columnNullValue(); assert( pVm->db ); sqlite3_mutex_enter(pVm->db->mutex); - if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ - pOut = &pVm->pResultSet[i]; + if( pVm->pResultRow!=0 && inResColumn && i>=0 ){ + pOut = &pVm->pResultRow[i]; }else{ sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8d284746f1..bcd67020e8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2316,7 +2316,7 @@ int sqlite3VdbeList( ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); - p->pResultSet = 0; + p->pResultRow = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or @@ -2373,7 +2373,7 @@ int sqlite3VdbeList( sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); p->nResColumn = 8; } - p->pResultSet = pMem; + p->pResultRow = pMem; if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; rc = SQLITE_ERROR; @@ -3505,7 +3505,7 @@ int sqlite3VdbeReset(Vdbe *p){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } - p->pResultSet = 0; + p->pResultRow = 0; #ifdef SQLITE_DEBUG p->nWrite = 0; #endif From cce70d52d0ac5c06a781a4d19e6807bba68a00ce Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Dec 2022 19:12:48 +0000 Subject: [PATCH 005/165] Avoid having to reinitialize Vdbe.pResultRow upon each call to sqlite3_step() for a small size reduction and performance increase. FossilOrigin-Name: 6a00d67f5955ab86eea982c27b3a03b680fdf644ec63f49586ade6342a4d64a6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 1 - src/vdbeapi.c | 2 +- src/vdbeaux.c | 1 - 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 96d254eae2..3f59b5e9de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sVdbe.pResultSet\sfield\sto\spResultRow\sin\sorder\sto\sbetter\sdistinguish\nit\sfrom\sother\svariables\swith\ssimilar\snames. -D 2022-12-22T18:44:39.948 +C Avoid\shaving\sto\sreinitialize\sVdbe.pResultRow\supon\seach\scall\sto\ssqlite3_step()\nfor\sa\ssmall\ssize\sreduction\sand\sperformance\sincrease. +D 2022-12-22T19:12:48.752 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -717,11 +717,11 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 6be002bb5faa47de14fe1dc31082f969ef1814ce48b527d7f24cf315b7339933 +F src/vdbe.c 65097b1b8dc19096a547c0fa54f9e3821e9d513d536654e77c63e85b8f195f1f F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 -F src/vdbeapi.c a9ddd91f1907023efd3035642d4bd47cf65effcbeae211d6af4aa2426687e552 -F src/vdbeaux.c f01f4c96c836b9d2c7749ddcef2a779cab3974f478a4034389fd3c59c055749a +F src/vdbeapi.c 4ee67890913c1d2469c68e3ad2e7ddeab57ac5924a64bbfd0906a8ea0d542c7f +F src/vdbeaux.c 28d283db3e9e18fef46b2a726173ea57aee18ba3a17c88c763d826f85a7c5b5e F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 6cfed43758d57b6e3b99d9cdedfeccd86e45a07e427b22d8487cbdbebb6c522a F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3181331c1c0259d5cd274dcb33faba930dae51b1f0fe51e8a0318d9c564b94f9 -R 9394973e55c6ccfeb1c979e40b4ba15e +P 1fd6211ef7bd26ed625177bfedfd5153ace547de6a71365ecfa076578d043f1a +R d29f6177fe6e6d525f82d4157aa1b700 U drh -Z 82b58542dbd948888420949bdd4642ed +Z 0157da8e1ea08955e8449bebbef403a0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8db7649c83..a60a31ccf1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1fd6211ef7bd26ed625177bfedfd5153ace547de6a71365ecfa076578d043f1a \ No newline at end of file +6a00d67f5955ab86eea982c27b3a03b680fdf644ec63f49586ade6342a4d64a6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1ed7216d1d..caaf2f429c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -755,7 +755,6 @@ int sqlite3VdbeExec( assert( p->bIsReader || p->readOnly!=0 ); p->iCurrentTime = 0; assert( p->explain==0 ); - p->pResultRow = 0; db->busyHandler.nBusy = 0; if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 34727c30ed..e080449c5e 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -753,7 +753,7 @@ static int sqlite3Step(Vdbe *p){ /* If the statement completed successfully, invoke the profile callback */ checkProfileCallback(db, p); #endif - + p->pResultRow = 0; if( rc==SQLITE_DONE && db->autoCommit ){ assert( p->rc==SQLITE_OK ); p->rc = doWalCallbacks(db); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index bcd67020e8..4ce2e9ec9e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2316,7 +2316,6 @@ int sqlite3VdbeList( ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); - p->pResultRow = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or From f26bad66ba1d73b855a2eadfc0af42d0a2060c2d Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Dec 2022 21:32:58 +0000 Subject: [PATCH 006/165] Asserts added to ensure that the iCompare variable in the bytecode engine is correctly initialized before it is used. FossilOrigin-Name: 7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3f59b5e9de..2957f5698b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\shaving\sto\sreinitialize\sVdbe.pResultRow\supon\seach\scall\sto\ssqlite3_step()\nfor\sa\ssmall\ssize\sreduction\sand\sperformance\sincrease. -D 2022-12-22T19:12:48.752 +C Asserts\sadded\sto\sensure\sthat\sthe\siCompare\svariable\sin\sthe\sbytecode\sengine\nis\scorrectly\sinitialized\sbefore\sit\sis\sused. +D 2022-12-22T21:32:58.656 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -717,7 +717,7 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 65097b1b8dc19096a547c0fa54f9e3821e9d513d536654e77c63e85b8f195f1f +F src/vdbe.c 61fccecee1b1f1ba1e5e250dae33c8cec1b1ef5d3176cc69bea69f2754473fd5 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 F src/vdbeapi.c 4ee67890913c1d2469c68e3ad2e7ddeab57ac5924a64bbfd0906a8ea0d542c7f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1fd6211ef7bd26ed625177bfedfd5153ace547de6a71365ecfa076578d043f1a -R d29f6177fe6e6d525f82d4157aa1b700 +P 6a00d67f5955ab86eea982c27b3a03b680fdf644ec63f49586ade6342a4d64a6 +R 04b1867006a44cfaff07f5cc142409fe U drh -Z 0157da8e1ea08955e8449bebbef403a0 +Z f8e779d9bb555f0dbe2f776fde1b49c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a60a31ccf1..0ddac20a17 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a00d67f5955ab86eea982c27b3a03b680fdf644ec63f49586ade6342a4d64a6 \ No newline at end of file +7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index caaf2f429c..0ca67e73ed 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -713,6 +713,7 @@ int sqlite3VdbeExec( #ifdef SQLITE_DEBUG Op *pOrigOp; /* Value of pOp at the top of the loop */ int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ + u8 iCompareIsInit = 0; /* iCompare is initialized */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ @@ -2125,18 +2126,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ goto jump_to_p2; } iCompare = +1; + VVA_ONLY( iCompareIsInit = 1; ) }else if( pIn3->u.i < pIn1->u.i ){ if( sqlite3aLTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } iCompare = -1; + VVA_ONLY( iCompareIsInit = 1; ) }else{ if( sqlite3aEQb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } iCompare = 0; + VVA_ONLY( iCompareIsInit = 1; ) } VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); break; @@ -2168,6 +2172,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ goto jump_to_p2; } iCompare = 1; /* Operands are not equal */ + VVA_ONLY( iCompareIsInit = 1; ) break; } }else{ @@ -2224,6 +2229,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ res2 = sqlite3aGTb[pOp->opcode]; } iCompare = res; + VVA_ONLY( iCompareIsInit = 1; ) /* Undo any changes made by applyAffinity() to the input registers. */ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); @@ -2262,6 +2268,7 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */ break; } #endif /* SQLITE_DEBUG */ + assert( iCompareIsInit ); VdbeBranchTaken(iCompare==0, 2); if( iCompare==0 ) goto jump_to_p2; break; @@ -2356,6 +2363,7 @@ case OP_Compare: { pColl = pKeyInfo->aColl[i]; bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); + VVA_ONLY( iCompareIsInit = 1; ) if( iCompare ){ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) @@ -2380,6 +2388,7 @@ case OP_Compare: { */ case OP_Jump: { /* jump */ assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); + assert( iCompareIsInit ); if( iCompare<0 ){ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ From dc02d5658b2d452de4d191f1e6e68b06aaf269af Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 11:32:06 +0000 Subject: [PATCH 007/165] Squelch a new (and, in this case, harmless) compiler warning. FossilOrigin-Name: a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 8 ++++---- src/vdbe.c | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 2957f5698b..1a675a0239 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Asserts\sadded\sto\sensure\sthat\sthe\siCompare\svariable\sin\sthe\sbytecode\sengine\nis\scorrectly\sinitialized\sbefore\sit\sis\sused. -D 2022-12-22T21:32:58.656 +C Squelch\sa\snew\s(and,\sin\sthis\scase,\sharmless)\scompiler\swarning. +D 2022-12-23T11:32:06.928 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -650,7 +650,7 @@ F src/shell.c.in 24e0c75947dd8a3426473d90dfc4887f42553c8b57dff02a6865f04c5efcf86 F src/sqlite.h.in e752f82b9d71f1d42b259b1900e4b1caf0965e844d756cd5cc91cc2cf45ed925 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f -F src/sqliteInt.h da23a13868fc76ca8e16931c825f62b778754055d52448e46d6620e766e0af34 +F src/sqliteInt.h 281c83af2143e5861fa4563c8c1a103c85e0a87b0a6571ec12a5b532fa2af786 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -717,7 +717,7 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c 61fccecee1b1f1ba1e5e250dae33c8cec1b1ef5d3176cc69bea69f2754473fd5 +F src/vdbe.c b0a0fcf1906caa09de426bb5f59073ba268f7020bd6a19be677c95dd81cc4150 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 F src/vdbeapi.c 4ee67890913c1d2469c68e3ad2e7ddeab57ac5924a64bbfd0906a8ea0d542c7f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a00d67f5955ab86eea982c27b3a03b680fdf644ec63f49586ade6342a4d64a6 -R 04b1867006a44cfaff07f5cc142409fe -U drh -Z f8e779d9bb555f0dbe2f776fde1b49c2 +P 7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 +R e60c0e3c20a0e7bf83aa49203eb3c182 +U stephan +Z 6976083f5240fdbe68fe33f0caf6e410 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0ddac20a17..20c91dded8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 \ No newline at end of file +a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cdf447b710..fda99428d8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3638,10 +3638,10 @@ struct TriggerPrg { #else typedef unsigned int yDbMask; # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) -# define DbMaskZero(M) (M)=0 -# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) -# define DbMaskAllZero(M) (M)==0 -# define DbMaskNonZero(M) (M)!=0 +# define DbMaskZero(M) ((M)=0) +# define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I))) +# define DbMaskAllZero(M) ((M)==0) +# define DbMaskNonZero(M) ((M)!=0) #endif /* diff --git a/src/vdbe.c b/src/vdbe.c index 0ca67e73ed..87f5e0a314 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -735,7 +735,7 @@ int sqlite3VdbeExec( /*** INSERT STACK UNION HERE ***/ assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ - if( !DbMaskAllZero(p->lockMask) )sqlite3VdbeEnter(p); + if( DbMaskNonZero(p->lockMask) )sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; @@ -8838,7 +8838,7 @@ vdbe_return: } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - if( !DbMaskAllZero(p->lockMask) ) sqlite3VdbeLeave(p); + if( DbMaskNonZero(p->lockMask) ) sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); From cc1cc9d7b78a6c932d7f6201106c7b4ef094ea30 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 11:46:26 +0000 Subject: [PATCH 008/165] Initial pieces for binding the session API to JS. Far from complete. See [forum:210e36a1e3 | forum post 210e36a1e3] for the discussion. FossilOrigin-Name: cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 47 +++++++++++++++++++-- ext/wasm/api/sqlite3-api-glue.js | 12 ++++-- ext/wasm/api/sqlite3-wasm.c | 6 +++ manifest | 19 +++++---- manifest.uuid | 2 +- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 75e5ea3da1..2c94d0fada 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -1,3 +1,6 @@ +_malloc +_free +_realloc _sqlite3_aggregate_context _sqlite3_bind_blob _sqlite3_bind_double @@ -143,6 +146,44 @@ _sqlite3_vtab_in_next _sqlite3_vtab_nochange _sqlite3_vtab_on_conflict _sqlite3_vtab_rhs_value -_malloc -_free -_realloc +_sqlite3changegroup_add +_sqlite3changegroup_add_strm +_sqlite3changegroup_delete +_sqlite3changegroup_new +_sqlite3changegroup_output +_sqlite3changegroup_output_strm +_sqlite3changeset_apply +_sqlite3changeset_apply_strm +_sqlite3changeset_apply_v2 +_sqlite3changeset_apply_v2_strm +_sqlite3changeset_concat +_sqlite3changeset_concat_strm +_sqlite3changeset_conflict +_sqlite3changeset_finalize +_sqlite3changeset_fk_conflicts +_sqlite3changeset_invert +_sqlite3changeset_invert_strm +_sqlite3changeset_new +_sqlite3changeset_next +_sqlite3changeset_old +_sqlite3changeset_op +_sqlite3changeset_pk +_sqlite3changeset_start +_sqlite3changeset_start_strm +_sqlite3changeset_start_v2 +_sqlite3changeset_start_v2_strm +_sqlite3session_attach +_sqlite3session_changeset +_sqlite3session_changeset_size +_sqlite3session_changeset_strm +_sqlite3session_config +_sqlite3session_create +_sqlite3session_delete +_sqlite3session_diff +_sqlite3session_enable +_sqlite3session_indirect +_sqlite3session_isempty +_sqlite3session_memory_used +_sqlite3session_patchset +_sqlite3session_patchset_strm +_sqlite3session_table_filter diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 59b40786ec..958f1b845b 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -332,10 +332,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(1){// WhWasmUtil.xWrap() bindings... /** Add some descriptive xWrap() aliases for '*' intended to (A) - initially improve readability/correctness of capi.signatures - and (B) provide automatic conversion from higher-level - representations, e.g. capi.sqlite3_vfs to `sqlite3_vfs*` via - capi.sqlite3_vfs.pointer. + initially improve readability/correctness of + wasm.bindingSignatures and (B) provide automatic conversion + from higher-level representations, e.g. capi.sqlite3_vfs to + `sqlite3_vfs*` via capi.sqlite3_vfs.pointer. */ const aPtr = wasm.xWrap.argAdapter('*'); const nilType = function(){}; @@ -343,6 +343,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ('sqlite3_context*', aPtr) ('sqlite3_value*', aPtr) ('void*', aPtr) + ('sqlite3_changegroup*', aPtr) + ('sqlite3_changeset_iter*', aPtr) + //('sqlite3_rebaser*', aPtr) + ('sqlite3_session*', aPtr) ('sqlite3_stmt*', (v)=> aPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType)) ? v.pointer : v)) diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index a42ea68d42..34e7a63ee8 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -102,9 +102,15 @@ #ifndef SQLITE_ENABLE_OFFSET_SQL_FUNC # define SQLITE_ENABLE_OFFSET_SQL_FUNC 1 #endif +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK +# define SQLITE_ENABLE_PREUPDATE_HOOK 1 /*required by session extension*/ +#endif #ifndef SQLITE_ENABLE_RTREE # define SQLITE_ENABLE_RTREE 1 #endif +#ifndef SQLITE_ENABLE_SESSION +# define SQLITE_ENABLE_SESSION 1 +#endif #ifndef SQLITE_ENABLE_STMTVTAB # define SQLITE_ENABLE_STMTVTAB 1 #endif diff --git a/manifest b/manifest index 1a675a0239..6d1e106dfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Squelch\sa\snew\s(and,\sin\sthis\scase,\sharmless)\scompiler\swarning. -D 2022-12-23T11:32:06.928 +C Initial\spieces\sfor\sbinding\sthe\ssession\sAPI\sto\sJS.\sFar\sfrom\scomplete.\sSee\s[forum:210e36a1e3\s|\sforum\spost\s210e36a1e3]\sfor\sthe\sdiscussion. +D 2022-12-23T11:46:26.185 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile 06d385b51bfb206cf779cf1bb816862f77df97fff97a6df9baf05b98c027067a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 4c7788042196cecab32f87d8e4965c183fea59037603888059f244b1752babcc +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api ff6f8c477f6f38457bce1c604ac517ecc3dfea64f816dc90356c0402f96725b8 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 63daa4b9c36faa4c338a32a06eb142869b9ae4885a3e01aad473e1b45357089f +F ext/wasm/api/sqlite3-api-glue.js dfdfbcdf1a9d4e42836ec53fda02c70869cfe5651a75e785b62ff69c4fe822e2 F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 44ce4cf12318b0577d8222cf59132617ab9925ca3cf5fbb8c7b30d1e947c13b5 +F ext/wasm/api/sqlite3-wasm.c 15194e3d5e0bcbcdcafb928392438d83aed56bdb8e71984ac415cc6a3b75e602 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -2067,8 +2067,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 -R e60c0e3c20a0e7bf83aa49203eb3c182 +P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd +R 754103df3bb98463a7b36626ed444e4f +T *branch * wasm-session-api +T *sym-wasm-session-api * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z 6976083f5240fdbe68fe33f0caf6e410 +Z bbc6e7158315d4288a4f21a6ce2dd790 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20c91dded8..49a23b524f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd \ No newline at end of file +cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 \ No newline at end of file From de5f3af2b98f10d4fe0e6d72183127e74cade6b0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Dec 2022 11:46:57 +0000 Subject: [PATCH 009/165] Additional fixes for yet more completely harmless compiler warnings. FossilOrigin-Name: 7d3772f0bd0e2602fe919573b49001da4e2b9f3874cb0183dea675204afa7abd --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/alter.c | 5 +++-- src/vdbe.c | 8 ++++++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1a675a0239..0a5c57e495 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Squelch\sa\snew\s(and,\sin\sthis\scase,\sharmless)\scompiler\swarning. -D 2022-12-23T11:32:06.928 +C Additional\sfixes\sfor\syet\smore\scompletely\sharmless\scompiler\swarnings. +D 2022-12-23T11:46:57.966 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -577,7 +577,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c 0390ca1d69ec3626cfa9f153114b7ab233e6b2bada6a9eb91361ed385fe90deb +F src/alter.c 3ca2f449c890f8b86ec9e06f0c4fccf0648941c3308a16904cb2852227db83f7 F src/analyze.c d2fce73f6a024897593012c6ca25368629fa4aeb49960d88a52fac664582e483 F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf @@ -717,7 +717,7 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c b0a0fcf1906caa09de426bb5f59073ba268f7020bd6a19be677c95dd81cc4150 +F src/vdbe.c b51ec34314b64b77a6a97b67dabbf615f9fa44ba2584dfc1fa15d1792e40205f F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 F src/vdbeapi.c 4ee67890913c1d2469c68e3ad2e7ddeab57ac5924a64bbfd0906a8ea0d542c7f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b5900a111b9410f7d60c937e5a56304f2f66b94cd0881e94abcc5eedde52514 -R e60c0e3c20a0e7bf83aa49203eb3c182 -U stephan -Z 6976083f5240fdbe68fe33f0caf6e410 +P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd +R ec4fdcd273b8f133c09ff276d19e040a +U drh +Z fd6d92f62b8a4b6b153ebaa254842802 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20c91dded8..7d6a015196 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd \ No newline at end of file +7d3772f0bd0e2602fe919573b49001da4e2b9f3874cb0183dea675204afa7abd \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d8a9982873..cebeec3855 100644 --- a/src/alter.c +++ b/src/alter.c @@ -741,13 +741,14 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( pParse->nErr==0 ){ const RenameToken *p; - u8 i = 0; + u32 i = 1; for(p=pParse->pRename; p; p=p->pNext){ if( p->p ){ assert( p->p!=pPtr ); - i += *(u8*)(p->p); + i += *(u8*)(p->p) | 1; } } + assert( i>0 ); } } #else diff --git a/src/vdbe.c b/src/vdbe.c index 87f5e0a314..f1cb093e5a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -735,7 +735,9 @@ int sqlite3VdbeExec( /*** INSERT STACK UNION HERE ***/ assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ - if( DbMaskNonZero(p->lockMask) )sqlite3VdbeEnter(p); + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeEnter(p); + } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; @@ -8838,7 +8840,9 @@ vdbe_return: } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - if( DbMaskNonZero(p->lockMask) ) sqlite3VdbeLeave(p); + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeLeave(p); + } assert( rc!=SQLITE_OK || nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); From 0f29f17bf6ea1044d4daa7bbc00283a026a1c514 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 14:11:54 +0000 Subject: [PATCH 010/165] Add sqlite3.capi JS bindings for the sqlite3session_...(), sqlite3changeset_...() and sqlite3changegroup_...() APIs, noting that they are completely untested. Aside from missing tests, these bindings reveal a slight string-argument-type shortcoming in the callback function pointer "reverse binding" which should ideally be resolved before publishing them. FossilOrigin-Name: 0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 1 + ext/wasm/api/sqlite3-api-glue.js | 213 +++++++++++++++++++- ext/wasm/api/sqlite3-wasm.c | 21 ++ ext/wasm/common/whwasmutil.js | 20 +- manifest | 21 +- manifest.uuid | 2 +- 6 files changed, 249 insertions(+), 29 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 2c94d0fada..da4cc5bd21 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -184,6 +184,7 @@ _sqlite3session_enable _sqlite3session_indirect _sqlite3session_isempty _sqlite3session_memory_used +_sqlite3session_object_config _sqlite3session_patchset _sqlite3session_patchset_strm _sqlite3session_table_filter diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 958f1b845b..dc1e827d50 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -59,10 +59,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ the lines of sqlite3_prepare_v3(). The slightly problematic part is the final argument (text destructor). */ ], - //["sqlite3_busy_handler","int", "sqlite3*", "*", "*"], - // ^^^^ TODO: custom binding which auto-converts JS function arg - // to a WASM function, noting that calling it multiple times - // would introduce a leak. + ["sqlite3_busy_handler","int", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_busy_handler', + signature: 'i(pi)', + bindScope: 'context', + contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] + }), + "*" + ]], ["sqlite3_busy_timeout","int", "sqlite3*", "int"], ["sqlite3_close_v2", "int", "sqlite3*"], ["sqlite3_changes", "int", "sqlite3*"], @@ -131,14 +137,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ for those, depending on how their SQL argument is provided. */ /* sqlite3_randomness() uses a hand-written wrapper to extend the range of supported argument types. */ - [ + [ "sqlite3_progress_handler", undefined, [ - "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({ + "sqlite3*", "int", + new wasm.xWrap.FuncPtrAdapter({ name: 'xProgressHandler', signature: 'i(p)', bindScope: 'context', contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] - }), "*" + }), + "*" ] ], ["sqlite3_realloc", "*","*","int"], @@ -211,7 +219,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ optional features into account. */ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]); } - + /** Functions which require BigInt (int64) support are separated from the others because we need to conditionally bind them or apply @@ -263,6 +271,187 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"] ]; + // Add session/changeset APIs... + if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ + /* ACHTUNG: 2022-12-23: the session/changeset API bindings are + COMPLETELY UNTESTED. Additionally, the callback-taking APIs + have a shortcoming which will make using those which take + string-type arguments more painful than it should be. How best + to resolve that, such that we can perform the same type conversions + as we do when binding in "the other direction," is as yet + undetermined. + */ + /* TODO: we need hand-written wrappers to adapt callbacks which + take string arguments. Or we need to find a way to do this sort + of reverse-binding which includes type conversions. */ + wasm.bindingSignatures.int64.push(...[ + ['sqlite3changegroup_add', 'int', ['sqlite3_changegroup*', 'int', 'void*']], + ['sqlite3changegroup_add_strm', 'int', [ + 'sqlite3_changegroup*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changegroup_delete', undefined, ['sqlite3_changegroup*']], + ['sqlite3changegroup_new', 'int', ['**']], + ['sqlite3changegroup_output', 'int', ['sqlite3_changegroup*', 'int*', '**']], + ['sqlite3changegroup_output_strm', 'int', [ + 'sqlite3_changegroup*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply_strm', 'int', [ + 'sqlite3*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_apply_v2', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + + ]], + ['sqlite3changeset_apply_v2', 'int', [ + 'sqlite3*', 'int', 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + ]], + ['sqlite3changeset_apply_v2_strm', 'int', [ + 'sqlite3*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + }), + new wasm.xWrap.FuncPtrAdapter({ + name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' + }), + 'void*', '**', 'int*', 'int' + ]], + ['sqlite3changeset_concat', 'int', ['int','void*', 'int', 'void*', 'int*', '**']], + ['sqlite3changeset_concat_strm', 'int', [ + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInputA', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInputB', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_conflict', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_finalize', 'int', ['sqlite3_changeset_iter*']], + ['sqlite3changeset_fk_conflicts', 'int', ['sqlite3_changeset_iter*', 'int*']], + ['sqlite3changeset_invert', 'int', ['int', 'void*', 'int*', '**']], + ['sqlite3changeset_invert_strm', 'int', [ + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppi)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_new', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_next', 'int', ['sqlite3_changeset_iter*']], + ['sqlite3changeset_old', 'int', ['sqlite3_changeset_iter*', 'int', '**']], + ['sqlite3changeset_op', 'int', [ + 'sqlite3_changeset_iter*', '**', 'int*', 'int*','int*' + ]], + ['sqlite3changeset_pk', 'int', ['sqlite3_changeset_iter*', '**', 'int*']], + ['sqlite3changeset_start', 'int', ['**', 'int', '*']], + ['sqlite3changeset_start_strm', 'int', [ + '**', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3changeset_start_v2', 'int', ['**', 'int', '*', 'int']], + ['sqlite3changeset_start_v2_strm', 'int', [ + '**', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xInput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*', 'int' + ]], + ['sqlite3session_attach', 'int', ['sqlite3_session*', 'string']], + ['sqlite3session_changeset', 'int', ['sqlite3_session*', 'int*', '**']], + ['sqlite3session_changeset_size', 'i64', ['sqlite3_session*']], + ['sqlite3session_changeset_strm', 'int', [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3session_config', 'int', ['int', 'void*']], + ['sqlite3session_create', 'int', ['sqlite3*', 'string', '**']], + ['sqlite3session_delete', undefined, ['sqlite3_session*']], + ['sqlite3session_diff', 'int', ['sqlite3_session*', 'string', 'string', '**']], + ['sqlite3session_enable', 'int', ['sqlite3_session*', 'int']], + ['sqlite3session_indirect', 'int', ['sqlite3_session*', 'int']], + ['sqlite3session_isempty', 'int', ['sqlite3_session*']], + ['sqlite3session_memory_used', 'i64', ['sqlite3_session*']], + ['sqlite3session_object_config', 'int', ['sqlite3_session*', 'int', 'void*']], + ['sqlite3session_patchset', 'int', ['sqlite3_session*', '*', '**']], + ['sqlite3session_patchset_strm', 'int', [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xOutput', signature: 'i(ppp)', bindScope: 'transient' + }), + 'void*' + ]], + ['sqlite3session_table_filter', undefined, [ + 'sqlite3_session*', + new wasm.xWrap.FuncPtrAdapter({ + name: 'xFilter', signature: 'i(ps)', + contextKey: (argIndex,argv)=>argv[0/* (sqlite3_session*) */] + }), + '*' + ]] + ]); + }/*session/changeset APIs*/ + /** Functions which are intended solely for API-internal use by the WASM components, not client code. These get installed into @@ -513,7 +702,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); } let rc, pfCompare, pfDestroy; - try{ + try{ rc = __ccv2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); }catch(e){ rc = util.sqlite3_wasm_db_error(pDb, e); @@ -910,12 +1099,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); const defineGroups = ['access', 'authorizer', - 'blobFinalizers', 'config', 'dataTypes', + 'blobFinalizers', 'changeset', + 'config', 'dataTypes', 'dbConfig', 'dbStatus', 'encodings', 'fcntl', 'flock', 'ioCap', 'limits', 'openFlags', 'prepareFlags', 'resultCodes', - 'serialize', 'sqlite3Status', + 'serialize', 'session', + 'sqlite3Status', 'stmtStatus', 'syncFlags', 'trace', 'txnState', 'udfFlags', 'version' ]; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 34e7a63ee8..39720ff9d1 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -461,6 +461,22 @@ const char * sqlite3_wasm_enum_json(void){ out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); } _DefGroup; + DefGroup(changeset){ + DefInt(SQLITE_CHANGESETSTART_INVERT); + DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT); + DefInt(SQLITE_CHANGESETAPPLY_INVERT); + + DefInt(SQLITE_CHANGESET_DATA); + DefInt(SQLITE_CHANGESET_NOTFOUND); + DefInt(SQLITE_CHANGESET_CONFLICT); + DefInt(SQLITE_CHANGESET_CONSTRAINT); + DefInt(SQLITE_CHANGESET_FOREIGN_KEY); + + DefInt(SQLITE_CHANGESET_OMIT); + DefInt(SQLITE_CHANGESET_REPLACE); + DefInt(SQLITE_CHANGESET_ABORT); + } _DefGroup; + DefGroup(config){ DefInt(SQLITE_CONFIG_SINGLETHREAD); DefInt(SQLITE_CONFIG_MULTITHREAD); @@ -797,6 +813,11 @@ const char * sqlite3_wasm_enum_json(void){ DefInt(SQLITE_DESERIALIZE_RESIZEABLE); } _DefGroup; + DefGroup(session){ + DefInt(SQLITE_SESSION_CONFIG_STRMSIZE); + DefInt(SQLITE_SESSION_OBJCONFIG_SIZE); + } _DefGroup; + DefGroup(sqlite3Status){ DefInt(SQLITE_STATUS_MEMORY_USED); DefInt(SQLITE_STATUS_PAGECACHE_USED); diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 87cc100f33..c99e36041b 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -446,7 +446,7 @@ self.WhWasmUtilInstaller = function(target){ type(s) of the given function signature, or throws if the signature is invalid. */ /******** // only valid for use with the WebAssembly.Function ctor, which - // is not yet documented on MDN. + // is not yet documented on MDN. sigToWasm: function(sig){ const rc = {parameters:[], results: []}; if('v'!==sig[0]) rc.results.push(f.sigTypes(sig[0])); @@ -1581,10 +1581,20 @@ self.WhWasmUtilInstaller = function(target){ not actually bind any functions. Its convertArg() method is called via xWrap() to perform any bindings. - Shortcomings: function pointers which include C-string arguments - may still need a level of hand-written wrappers around them, - depending on how they're used, in order to provide the client - with JS strings. + Shortcomings: + + - These "reverse" bindings, i.e. calling into a JS-defined + function from a WASM-defined function (the generated proxy + wrapper), lack all type conversion support. That means, for + example, that... + + - Function pointers which include C-string arguments may still + need a level of hand-written wrappers around them, depending on + how they're used, in order to provide the client with JS + strings. Alternately, clients will need to perform such conversions + on their own, e.g. using cstrtojs(). Or maybe we can find a way + to perform such conversions here, via addition of an xWrap()-style + function signature to the options argument. */ xArg.FuncPtrAdapter = class FuncPtrAdapter extends AbstractArgAdapter { constructor(opt) { diff --git a/manifest b/manifest index 6d1e106dfb..eacaf992fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\spieces\sfor\sbinding\sthe\ssession\sAPI\sto\sJS.\sFar\sfrom\scomplete.\sSee\s[forum:210e36a1e3\s|\sforum\spost\s210e36a1e3]\sfor\sthe\sdiscussion. -D 2022-12-23T11:46:26.185 +C Add\ssqlite3.capi\sJS\sbindings\sfor\sthe\ssqlite3session_...(),\ssqlite3changeset_...()\sand\ssqlite3changegroup_...()\sAPIs,\snoting\sthat\sthey\sare\scompletely\suntested.\sAside\sfrom\smissing\stests,\sthese\sbindings\sreveal\sa\sslight\sstring-argument-type\sshortcoming\sin\sthe\scallback\sfunction\spointer\s"reverse\sbinding"\swhich\sshould\sideally\sbe\sresolved\sbefore\spublishing\sthem. +D 2022-12-23T14:11:54.508 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile 06d385b51bfb206cf779cf1bb816862f77df97fff97a6df9baf05b98c027067a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api ff6f8c477f6f38457bce1c604ac517ecc3dfea64f816dc90356c0402f96725b8 +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 8c15a035ca5263659f21a691d701e23294621a24d1e130fa8905a261b495ebe4 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js dfdfbcdf1a9d4e42836ec53fda02c70869cfe5651a75e785b62ff69c4fe822e2 +F ext/wasm/api/sqlite3-api-glue.js 5a28c384ece2066522cf8b04a454d44c0245835a6a26b681d3deed97b3805623 F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 15194e3d5e0bcbcdcafb928392438d83aed56bdb8e71984ac415cc6a3b75e602 +F ext/wasm/api/sqlite3-wasm.c f0aafd3e8f09c68bec14bd0cc7a31212964302134dec8c428e7afc517e78e257 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js ba1a8db1f32124e43e24b3d890102b6552b2c0b5a202185041a55887692df328 +F ext/wasm/common/whwasmutil.js af85d9a09fa79847d08279be0f61978ecc3bed893c88003f4a85d8bd204e6b5a F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,11 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd -R 754103df3bb98463a7b36626ed444e4f -T *branch * wasm-session-api -T *sym-wasm-session-api * -T -sym-trunk * Cancelled\sby\sbranch. +P cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 +R 042a575edf17a004d3f3655705629da7 U stephan -Z bbc6e7158315d4288a4f21a6ce2dd790 +Z 81bf3460fe50c1e6a01aac07ed8bed30 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 49a23b524f..aa150a668b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 \ No newline at end of file +0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d \ No newline at end of file From 3547e4997f29afa0df561653019b795e6f8f691a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Dec 2022 14:49:24 +0000 Subject: [PATCH 011/165] Fix lots of harmless, nuisance compiler warnings, mostly unused parameter warnings in extensions. FossilOrigin-Name: c14bbe1606c1450b709970f922b94a641dfc8f9bd09126501d7dc4db99ea4772 --- ext/fts5/fts5_index.c | 2 +- ext/misc/decimal.c | 2 +- ext/misc/regexp.c | 1 + ext/misc/stmt.c | 9 +++++++ ext/misc/zipfile.c | 9 +++++++ ext/recover/dbdata.c | 6 +++++ ext/recover/sqlite3recover.c | 15 ++++++++--- ext/rtree/geopoly.c | 25 +++++++++++++++++-- ext/rtree/rtree.c | 8 +++--- ext/session/sqlite3session.c | 11 +++++---- manifest | 48 ++++++++++++++++++------------------ manifest.uuid | 2 +- src/build.c | 1 + src/dbpage.c | 8 ++++++ src/dbstat.c | 4 +++ src/func.c | 4 +++ src/shell.c.in | 2 ++ src/sqliteInt.h | 4 +-- src/vdbe.c | 3 +++ src/vdbeaux.c | 2 ++ src/vdbevtab.c | 4 +++ 21 files changed, 127 insertions(+), 43 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 7eca9b1321..0c883f020a 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5073,7 +5073,7 @@ static void fts5MergePrefixLists( /* Initialize a doclist-iterator for each input buffer. Arrange them in ** a linked-list starting at pHead in ascending order of rowid. Avoid ** linking any iterators already at EOF into the linked list at all. */ - assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); + assert( nBuf+1<=(int)(sizeof(aMerger)/sizeof(aMerger[0])) ); memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); pHead = &aMerger[nBuf]; fts5DoclistIterInit(p1, &pHead->iter); diff --git a/ext/misc/decimal.c b/ext/misc/decimal.c index 37c6c2f52c..4495cae469 100644 --- a/ext/misc/decimal.c +++ b/ext/misc/decimal.c @@ -616,7 +616,7 @@ int sqlite3_decimal_init( SQLITE_EXTENSION_INIT2(pApi); - for(i=0; ipRow; for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ @@ -271,6 +279,7 @@ static int stmtBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ + (void)tab; pIdxInfo->estimatedCost = (double)500; pIdxInfo->estimatedRows = 500; return SQLITE_OK; diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index f818fbc11c..ba55b09cf2 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -352,6 +352,7 @@ static int zipfileConnect( const char *zFile = 0; ZipfileTab *pNew = 0; int rc; + (void)pAux; /* If the table name is not "zipfile", require that the argument be ** specified. This stops zipfile tables from being created as: @@ -808,6 +809,7 @@ static int zipfileGetEntry( u8 *aRead; char **pzErr = &pTab->base.zErrMsg; int rc = SQLITE_OK; + (void)nBlob; if( aBlob==0 ){ aRead = pTab->aBuffer; @@ -1254,6 +1256,9 @@ static int zipfileFilter( int rc = SQLITE_OK; /* Return Code */ int bInMemory = 0; /* True for an in-memory zipfile */ + (void)idxStr; + (void)argc; + zipfileResetCursor(pCsr); if( pTab->zFile ){ @@ -1314,6 +1319,7 @@ static int zipfileBestIndex( int i; int idx = -1; int unusable = 0; + (void)tab; for(i=0; inConstraint; i++){ const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; @@ -1564,6 +1570,8 @@ static int zipfileUpdate( int bIsDir = 0; u32 iCrc32 = 0; + (void)pRowid; + if( pTab->pWriteFd==0 ){ rc = zipfileBegin(pVtab); if( rc!=SQLITE_OK ) return rc; @@ -1898,6 +1906,7 @@ static int zipfileFindFunction( void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ void **ppArg /* OUT: User data for *pxFunc */ ){ + (void)nArg; if( sqlite3_stricmp("zipfile_cds", zName)==0 ){ *pxFunc = zipfileFunctionCds; *ppArg = (void*)pVtab; diff --git a/ext/recover/dbdata.c b/ext/recover/dbdata.c index 9563ab502a..da02b754b2 100644 --- a/ext/recover/dbdata.c +++ b/ext/recover/dbdata.c @@ -164,6 +164,9 @@ static int dbdataConnect( DbdataTable *pTab = 0; int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA); + (void)argc; + (void)argv; + (void)pzErr; if( rc==SQLITE_OK ){ pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable)); if( pTab==0 ){ @@ -768,6 +771,8 @@ static int dbdataFilter( DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; int rc = SQLITE_OK; const char *zSchema = "main"; + (void)idxStr; + (void)argc; dbdataResetCursor(pCsr); assert( pCsr->iPgno==1 ); @@ -936,6 +941,7 @@ int sqlite3_dbdata_init( const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; return sqlite3DbdataRegister(db); } diff --git a/ext/recover/sqlite3recover.c b/ext/recover/sqlite3recover.c index e62aba752f..8306e8ed8e 100644 --- a/ext/recover/sqlite3recover.c +++ b/ext/recover/sqlite3recover.c @@ -761,6 +761,7 @@ static void recoverEscapeCrnl( sqlite3_value **argv ){ const char *zText = (const char*)sqlite3_value_text(argv[0]); + (void)argc; if( zText && zText[0]=='\'' ){ int nText = sqlite3_value_bytes(argv[0]); int i; @@ -913,7 +914,7 @@ static void recoverTransferSettings(sqlite3_recover *p){ return; } - for(ii=0; iidbIn, "PRAGMA %Q.%s", p->zDb, zPrag); @@ -991,7 +992,9 @@ static int recoverOpenOutput(sqlite3_recover *p){ } /* Register the custom user-functions with the output handle. */ - for(ii=0; p->errCode==SQLITE_OK && iierrCode==SQLITE_OK && ii<(int)(sizeof(aFunc)/sizeof(aFunc[0])); + ii++){ p->errCode = sqlite3_create_function(db, aFunc[ii].zName, aFunc[ii].nArg, SQLITE_UTF8, (void*)p, aFunc[ii].xFunc, 0, 0 ); @@ -2388,7 +2391,7 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ if( pgsz==65536 ) pgsz = 1; recoverPutU16(&aHdr[16], pgsz); aHdr[20] = nReserve; - for(ii=0; ii=(4+6*sizeof(GeoCoord)) + && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) ){ const unsigned char *a = sqlite3_value_blob(pVal); int nVertex; @@ -362,6 +362,7 @@ static void geopolyBlobFunc( sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); @@ -381,6 +382,7 @@ static void geopolyJsonFunc( sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; if( p ){ sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_str *x = sqlite3_str_new(db); @@ -462,6 +464,7 @@ static void geopolyXformFunc( double F = sqlite3_value_double(argv[6]); GeoCoord x1, y1, x0, y0; int ii; + (void)argc; if( p ){ for(ii=0; iinVertex; ii++){ x0 = GeoX(p,ii); @@ -512,6 +515,7 @@ static void geopolyAreaFunc( sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; if( p ){ sqlite3_result_double(context, geopolyArea(p)); sqlite3_free(p); @@ -537,6 +541,7 @@ static void geopolyCcwFunc( sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; if( p ){ if( geopolyArea(p)<0.0 ){ int ii, jj; @@ -591,6 +596,7 @@ static void geopolyRegularFunc( int n = sqlite3_value_int(argv[3]); int i; GeoPoly *p; + (void)argc; if( n<3 || r<=0.0 ) return; if( n>1000 ) n = 1000; @@ -700,6 +706,7 @@ static void geopolyBBoxFunc( sqlite3_value **argv ){ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); + (void)argc; if( p ){ sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); @@ -727,6 +734,7 @@ static void geopolyBBoxStep( ){ RtreeCoord a[4]; int rc = SQLITE_OK; + (void)argc; (void)geopolyBBox(context, argv[0], a, &rc); if( rc==SQLITE_OK ){ GeoBBox *pBBox; @@ -815,6 +823,8 @@ static void geopolyContainsPointFunc( int v = 0; int cnt = 0; int ii; + (void)argc; + if( p1==0 ) return; for(ii=0; iinVertex-1; ii++){ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), @@ -854,6 +864,7 @@ static void geopolyWithinFunc( ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ @@ -1184,6 +1195,7 @@ static void geopolyOverlapFunc( ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ @@ -1204,8 +1216,12 @@ static void geopolyDebugFunc( int argc, sqlite3_value **argv ){ + (void)context; + (void)argc; #ifdef GEOPOLY_ENABLE_DEBUG geo_debug = sqlite3_value_int(argv[0]); +#else + (void)argv; #endif } @@ -1233,6 +1249,7 @@ static int geopolyInit( sqlite3_str *pSql; char *zSql; int ii; + (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); @@ -1349,6 +1366,7 @@ static int geopolyFilter( RtreeNode *pRoot = 0; int rc = SQLITE_OK; int iCell = 0; + (void)idxStr; rtreeReference(pRtree); @@ -1475,6 +1493,7 @@ static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int iRowidTerm = -1; int iFuncTerm = -1; int idxNum = 0; + (void)tab; for(ii=0; iinConstraint; ii++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; @@ -1721,6 +1740,8 @@ static int geopolyFindFunction( void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg ){ + (void)pVtab; + (void)nArg; if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ *pxFunc = geopolyOverlapFunc; *ppArg = 0; @@ -1790,7 +1811,7 @@ static int sqlite3_geopoly_init(sqlite3 *db){ } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, }; - int i; + unsigned int i; for(i=0; i=1300 pCoord->u = _byteswap_ulong(*(u32*)p); #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -555,7 +555,7 @@ static void writeInt16(u8 *p, int i){ } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; - assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ + assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -1283,7 +1283,7 @@ static void rtreeNonleafConstraint( assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); - assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ + assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ @@ -1336,7 +1336,7 @@ static void rtreeLeafConstraint( || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); pCellData += 8 + p->iCoord*4; - assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ + assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index fd06f3b4d6..a3f28abe9e 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1499,6 +1499,8 @@ static void xPreUpdate( int nDb = sqlite3Strlen30(zDb); assert( sqlite3_mutex_held(db->mutex) ); + (void)iKey1; + (void)iKey2; for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; @@ -1575,6 +1577,7 @@ static int sessionDiffCount(void *pCtx){ return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); } static int sessionDiffDepth(void *pCtx){ + (void)pCtx; return 0; } @@ -1648,7 +1651,6 @@ static char *sessionExprCompareOther( } static char *sessionSelectFindNew( - int nCol, const char *zDb1, /* Pick rows in this db only */ const char *zDb2, /* But not in this one */ const char *zTbl, /* Table name */ @@ -1672,7 +1674,7 @@ static int sessionDiffFindNew( char *zExpr ){ int rc = SQLITE_OK; - char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr); + char *zStmt = sessionSelectFindNew(zDb1, zDb2, pTab->zName,zExpr); if( zStmt==0 ){ rc = SQLITE_NOMEM; @@ -4189,7 +4191,6 @@ static int sessionBindRow( ** UPDATE, bind values from the old.* record. */ static int sessionSeekToRow( - sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ u8 *abPK, /* Primary key flags array */ sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ @@ -4319,7 +4320,7 @@ static int sessionConflictHandler( /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ if( pbReplace ){ - rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); + rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); }else{ rc = SQLITE_OK; } @@ -4493,7 +4494,7 @@ static int sessionApplyOneOp( /* Check if there is a conflicting row. For sqlite_stat1, this needs ** to be done using a SELECT, as there is no PRIMARY KEY in the ** database schema to throw an exception if a duplicate is inserted. */ - rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); + rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); if( rc==SQLITE_ROW ){ rc = SQLITE_CONSTRAINT; sqlite3_reset(p->pSelect); diff --git a/manifest b/manifest index 0a5c57e495..9863dbab45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\sfixes\sfor\syet\smore\scompletely\sharmless\scompiler\swarnings. -D 2022-12-23T11:46:57.966 +C Fix\slots\sof\sharmless,\snuisance\scompiler\swarnings,\smostly\sunused\sparameter\nwarnings\sin\sextensions. +D 2022-12-23T14:49:24.143 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -118,7 +118,7 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292 F ext/fts5/fts5_config.c 501e7d3566bc92766b0e11c0109a7c5a6146bc41144195459af5422f6c2078aa F ext/fts5/fts5_expr.c 40174a64829d30cc86e8266306ad24980f6911edd5ca0b8c1ce7821ea1341b88 F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982 -F ext/fts5/fts5_index.c a8ee270724ae1f958d0ce9897bcd60a5b760ecbeaa058fc8632805a283f1c20a +F ext/fts5/fts5_index.c e879315306f368b5681d32cffc90770b124649814214615b88d79ddd957f6747 F ext/fts5/fts5_main.c 3fd46be6a7aaac1d4210d4df0c7f9b1e78d1f0af566bfa2ab58d945ffa328ff7 F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082 F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae @@ -302,7 +302,7 @@ F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8b F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 F ext/misc/csv.c ca8d6dafc5469639de81937cb66ae2e6b358542aba94c4f791910d355a8e7f73 F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01 -F ext/misc/decimal.c 09f967dcf4a1ee35a76309829308ec278d3648168733f4a1147820e11ebefd12 +F ext/misc/decimal.c 57d85fa20a5a74d3b0dfc78ab7934ae6c9f5aa8eed915faa2b5246bec87ddc6d F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720 @@ -319,7 +319,7 @@ F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009 -F ext/misc/regexp.c 064838f7b31e90d312cce089cfafbb992034e75d359009c48886ca06c0a794b2 +F ext/misc/regexp.c f50ab59bfa8934b7ed98de069d2c74c187f2ef523fb09e85f8840f6459a90942 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 @@ -329,7 +329,7 @@ F ext/misc/shathree.c 9b7af7b7d55b27c5bbd16548b67fe6aa47a819e71bc6a80a456144f86f F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6 -F ext/misc/stmt.c ed05ad78013edccd43f4fc33d8244001f6f886eb2dfd2106ba33616ac514c6fb +F ext/misc/stmt.c bc30d60d55e70d0133f10ac6103fe9336543f673740b73946f98758a2bb16dd7 F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b @@ -341,7 +341,7 @@ F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c 22afe121d1a5e318453b7cdbc0f5492161d2fd4fce548ff3605da05e89be7140 +F ext/misc/zipfile.c bc4f8c552c8eed68fddc44600da9eed5d4de9c0e765b1256cf8750288097307f F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test c62904bd9526dcdc3496a21199aaf14ae191bbadbf67f076bf16be6b3f2115c2 @@ -389,7 +389,7 @@ F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2 F ext/rbu/sqlite3rbu.c 64d105c7c6c95272e7c12142cd021059214387a0d51e262bb0663285a2b91660 F ext/rbu/sqlite3rbu.h 02d981e2d39c151391759e1a400e29c7388730812957ac3db8dad7f6c9f9cfc8 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 -F ext/recover/dbdata.c 8f1f75d636431de69d7977ec50fc41bfdd0c48c510d5ee7eae0cbd4164e1429a +F ext/recover/dbdata.c dc25628e405c86936c597e28f3e6f56a257029c3034c5ef7f6b10f7c02f41018 F ext/recover/recover1.test 2a2df2943d6696f9487e75868feae4b1511c4a511b102854ba0d2af0326d9dfb F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e @@ -402,7 +402,7 @@ F ext/recover/recoverpgsz.test 3658ab8e68475b1bb87d6af88baa04551c84b73280a566a1b F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 -F ext/recover/sqlite3recover.c 6d37a422c8917b793548a7b2c6e7ff8e1af15ba5453eef37bb69331828b73186 +F ext/recover/sqlite3recover.c 3346e73e8570cb803618f0d4b65a0d07a3e246c6591347bdf04c7d0bb6d3bbde F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/test_recover.c 1a34e2d04533d919a30ae4d5caeb1643f6684e9ccd7597ca27721d8af81f4ade F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -415,8 +415,8 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782 F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/geopoly.c bb0dcd013dbb3fe0335b6bbae0d9c29fcfffda93d5ef6c31daa47e802132e435 -F ext/rtree/rtree.c b963ebced19f249d8523396a779351481d13a67c36c3c1f034b982886cd39a42 +F ext/rtree/geopoly.c 971e0b5bd9adaf0811feb8c0842a310811159da10319eb0e74fdb42bf26b99ca +F ext/rtree/rtree.c e05929e78d127613a9eea5dc372c77a049484892d8e9fac1fe0cce85ce4fba81 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test d47f58832145fcfed9067bc457ca8664962196c4566c17a1ebd679367db55d11 F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -484,7 +484,7 @@ F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2 F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a347ea9820a002dd8 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c b4254dd6e785cdd206c9ca7118796cf82273627fe2d4fd647597f08c2f821f96 +F ext/session/sqlite3session.c 13bdc093416cd284d4075328dd8599eb59bcedc23a21d561a15d78805c5866bf F ext/session/sqlite3session.h 0907de79bc13a2e3af30a6dc29acc60792a3eaf7d33d44cf52500d0f3c2b2171 F ext/session/test_session.c 94364b91cf4571d320ef5b1e04075d2c58c79b63afdf20c9e470555a691ca5b1 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 @@ -587,18 +587,18 @@ F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca F src/btree.c 2f794c217e52fdf4322bf37ee7778331b4d93aed2c00b5d67f914c0239a9edcc F src/btree.h 49da925329574798be3cbb745a49d069a9e67c99900d8a0d04b1e934d60394ea F src/btreeInt.h 88ad499c92b489afedbfefc3f067c4d15023ec021afe622db240dc9d2277cfa5 -F src/build.c 9288348515cad28371dd219b111503a444a05d478493ed5e247541bbe7e5d28d +F src/build.c e7b131773a3647701660d1b929b9947bccc9b3397788459168dd04a9e29a1f1f F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d F src/date.c 94ce83b4cd848a387680a5f920c9018c16655db778c4d36525af0a0f34679ac5 -F src/dbpage.c f1a87f4ebcf22284e0aaf0697862f4ccfc120dcd6db3d8dfa3b049b2580c01d8 -F src/dbstat.c a56a7ad1163a9888d46cd5820be2e65354fb1aa04ed6909f7c3e5831e0ee2c29 +F src/dbpage.c 254e3a228892ab6139beda795ebc9c60b876aae59eb9cd9290d11dc261c8d824 +F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e F src/expr.c 204af6a83c191f5ac19ec4af6ecc546f188cc2dd1c76fc5280982f710ec4b9c4 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002 -F src/func.c f6b7f49f4097461701311ff0126010e17239273cdcaaef9c3b85114f2e07a2d4 +F src/func.c 68f610a44962814a4ba593fc95137a6682cb7e65086f22167e167b75ee3432e7 F src/global.c e06ff8e0acd85aec13563c9ecb44fbbf38232ccf73594998fd880b92d619594b F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -646,11 +646,11 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 83de67e4857be2866d048c98e93f65461d8a0408ca4ce88fec68ebfe030997ae -F src/shell.c.in 24e0c75947dd8a3426473d90dfc4887f42553c8b57dff02a6865f04c5efcf864 +F src/shell.c.in fb29e3fb40c84a453b5f5d7bf32b5c2fb9f2207b1a97ff76490c5d8a2ec22575 F src/sqlite.h.in e752f82b9d71f1d42b259b1900e4b1caf0965e844d756cd5cc91cc2cf45ed925 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f -F src/sqliteInt.h 281c83af2143e5861fa4563c8c1a103c85e0a87b0a6571ec12a5b532fa2af786 +F src/sqliteInt.h 98bc12d3191ff4c70e8491b639784c83d577b7177377d4fb344826ac56bae8a8 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -717,16 +717,16 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050 F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c b51ec34314b64b77a6a97b67dabbf615f9fa44ba2584dfc1fa15d1792e40205f +F src/vdbe.c b2f2cbaae707685b9860bd54cdd6657076c28e82c725d795ae389c10850a97a6 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h fc15815b7bdafbb27e7f027faba2b0112e87d382c0d72241672528806ebc0db5 F src/vdbeapi.c 4ee67890913c1d2469c68e3ad2e7ddeab57ac5924a64bbfd0906a8ea0d542c7f -F src/vdbeaux.c 28d283db3e9e18fef46b2a726173ea57aee18ba3a17c88c763d826f85a7c5b5e +F src/vdbeaux.c 9eb7394126b88e55f81321d5e87636e0cd5e5856818d644d8abd6bfbb9c0be9d F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 6cfed43758d57b6e3b99d9cdedfeccd86e45a07e427b22d8487cbdbebb6c522a F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 -F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c +F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac F src/vtab.c b2f993aa954078985bc40317bb2140fe0880a08a7440f3a428b60fce74636808 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a02e19dd6ce00492f3d187e3c3c9bde4d9d1ee9a23616e62ea3590eec95652bd -R ec4fdcd273b8f133c09ff276d19e040a +P 7d3772f0bd0e2602fe919573b49001da4e2b9f3874cb0183dea675204afa7abd +R 16338e89b5ec3a31b67202fe13704742 U drh -Z fd6d92f62b8a4b6b153ebaa254842802 +Z 80509b64f86f8701ef91d19f5ff36290 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7d6a015196..f42d26d9c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d3772f0bd0e2602fe919573b49001da4e2b9f3874cb0183dea675204afa7abd \ No newline at end of file +c14bbe1606c1450b709970f922b94a641dfc8f9bd09126501d7dc4db99ea4772 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 415eeae70d..60d59c0c40 100644 --- a/src/build.c +++ b/src/build.c @@ -2584,6 +2584,7 @@ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ ** not pass them into code generator routines by mistake. */ static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ + (void)pWalker; ExprSetVVAProperty(pExpr, EP_Immutable); return WRC_Continue; } diff --git a/src/dbpage.c b/src/dbpage.c index 458f2bd501..9378dd4fc4 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -72,6 +72,10 @@ static int dbpageConnect( ){ DbpageTable *pTab = 0; int rc = SQLITE_OK; + (void)pAux; + (void)argc; + (void)argv; + (void)pzErr; sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); rc = sqlite3_declare_vtab(db, @@ -110,6 +114,7 @@ static int dbpageDisconnect(sqlite3_vtab *pVtab){ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iPlan = 0; + (void)tab; /* If there is a schema= constraint, it must be honored. Report a ** ridiculously large estimated cost if the schema= constraint is @@ -225,6 +230,8 @@ static int dbpageFilter( sqlite3 *db = pTab->db; Btree *pBt; + (void)idxStr; + /* Default setting is no rows of result */ pCsr->pgno = 1; pCsr->mxPgno = 0; @@ -320,6 +327,7 @@ static int dbpageUpdate( Pager *pPager; int szPage; + (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ zErr = "read-only"; goto update_fail; diff --git a/src/dbstat.c b/src/dbstat.c index fdef913f88..0a89d05249 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -163,6 +163,7 @@ static int statConnect( StatTable *pTab = 0; int rc = SQLITE_OK; int iDb; + (void)pAux; if( argc>=4 ){ Token nm; @@ -216,6 +217,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int iSchema = -1; int iName = -1; int iAgg = -1; + (void)tab; /* Look for a valid schema=? constraint. If found, change the idxNum to ** 1 and request the value of that constraint be sent to xFilter. And @@ -741,6 +743,8 @@ static int statFilter( int iArg = 0; /* Count of argv[] parameters used so far */ int rc = SQLITE_OK; /* Result of this operation */ const char *zName = 0; /* Only provide analysis of this table */ + (void)argc; + (void)idxStr; statResetCsr(pCsr); sqlite3_finalize(pCsr->pStmt); diff --git a/src/func.c b/src/func.c index 70ad3d5ca5..9a62470a0c 100644 --- a/src/func.c +++ b/src/func.c @@ -1440,6 +1440,9 @@ static void unknownFunc( sqlite3_value **argv ){ /* no-op */ + (void)context; + (void)argc; + (void)argv; } #endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ @@ -2183,6 +2186,7 @@ static void piFunc( sqlite3_value **argv ){ assert( argc==0 ); + (void)argv; sqlite3_result_double(context, M_PI); } diff --git a/src/shell.c.in b/src/shell.c.in index d183c7842f..20109e0cd3 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5423,6 +5423,8 @@ static char *readline_completion_generator(const char *text, int state){ return zRet; } static char **readline_completion(const char *zText, int iStart, int iEnd){ + (void)iStart; + (void)iEnd; rl_attempted_completion_over = 1; return rl_completion_matches(zText, readline_completion_generator); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fda99428d8..838c6e7b57 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -973,9 +973,9 @@ typedef INT16_TYPE LogEst; ** pointers. In that case, only verify 4-byte alignment. */ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC -# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) #else -# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif /* diff --git a/src/vdbe.c b/src/vdbe.c index f1cb093e5a..7705b68ec6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -133,6 +133,9 @@ int sqlite3_found_count = 0; */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ static int n = 0; + (void)pc; + (void)pOp; + (void)v; n++; } #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4ce2e9ec9e..ca9e5112a4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -212,6 +212,8 @@ static int growOpArray(Vdbe *v, int nOp){ */ static void test_addop_breakpoint(int pc, Op *pOp){ static int n = 0; + (void)pc; + (void)pOp; n++; } #endif diff --git a/src/vdbevtab.c b/src/vdbevtab.c index e9bafd450f..6557d8cb01 100644 --- a/src/vdbevtab.c +++ b/src/vdbevtab.c @@ -83,6 +83,9 @@ static int bytecodevtabConnect( ");" }; + (void)argc; + (void)argv; + (void)pzErr; rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); if( rc==SQLITE_OK ){ pNew = sqlite3_malloc( sizeof(*pNew) ); @@ -318,6 +321,7 @@ static int bytecodevtabFilter( bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; int rc = SQLITE_OK; + (void)idxStr; bytecodevtabCursorClear(pCur); pCur->iRowid = 0; From b5915699d0404bcd3b502e18af3d889d0bf581dc Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 18:14:36 +0000 Subject: [PATCH 012/165] Internal cleanups and minor speed optimizations in the sqlite3.wasm.xWrap() infrastructure. FossilOrigin-Name: c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a --- ext/wasm/common/whwasmutil.js | 205 +++++++++++++++++++--------------- ext/wasm/tester1.c-pp.js | 64 ++++++++++- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 182 insertions(+), 103 deletions(-) diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index c99e36041b..4b1026e4cd 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -359,7 +359,8 @@ self.WhWasmUtilInstaller = function(target){ /** Given a function pointer, returns the WASM function table entry - if found, else returns a falsy value. + if found, else returns a falsy value: undefined if fptr is out of + range or null if it's in range but the table entry is empty. */ target.functionEntry = function(fptr){ const ft = target.functionTable(); @@ -552,13 +553,12 @@ self.WhWasmUtilInstaller = function(target){ cache.scopedAlloc[cache.scopedAlloc.length-1].push(ptr); } }catch(e){ - if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); - throw e; + if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); + throw e; } - return ptr; + return ptr; }; - /** Expects a JS function and signature, exactly as for this.jsFuncToWasm(). It uses that function to create a @@ -612,8 +612,13 @@ self.WhWasmUtilInstaller = function(target){ installFunction() has been called and results are undefined if ptr was not returned by that function. The returned function may be passed back to installFunction() to reinstall it. + + To simplify certain use cases, if passed a falsy non-0 value + (noting that 0 is a valid function table index), this function + has no side effects and returns undefined. */ target.uninstallFunction = function(ptr){ + if(!ptr && 0!==ptr) return undefined; const fi = cache.freeFuncIndexes; const ft = target.functionTable(); fi.push(ptr); @@ -730,7 +735,7 @@ self.WhWasmUtilInstaller = function(target){ ? cache : heapWrappers(); for(const p of (Array.isArray(ptr) ? ptr : [ptr])){ switch (type) { - case 'i1': + case 'i1': case 'i8': c.HEAP8[p>>0] = value; continue; case 'i16': c.HEAP16[p>>1] = value; continue; case 'i32': c.HEAP32[p>>2] = value; continue; @@ -803,7 +808,6 @@ self.WhWasmUtilInstaller = function(target){ /** f64 variant of poke8(). */ target.poke64f = (ptr, value)=>target.poke(ptr, value, 'f64'); - /** Deprecated alias for getMemValue() */ target.getMemValue = target.peek; /** Deprecated alias for peekPtr() */ @@ -1351,7 +1355,7 @@ self.WhWasmUtilInstaller = function(target){ const __argcMismatch = (f,n)=>toss(f+"() requires",n,"argument(s)."); - + /** Looks up a WASM-exported function named fname from target.exports. If found, it is called, passed all remaining @@ -1390,18 +1394,25 @@ self.WhWasmUtilInstaller = function(target){ if(target.bigIntEnabled){ xArg.set('i64', (i)=>BigInt(i)); } - xArg.set('i32', (i)=>(i | 0)); - xArg.set('i16', (i)=>((i | 0) & 0xFFFF)); - xArg.set('i8', (i)=>((i | 0) & 0xFF)); - xArg.set('f32', (i)=>Number(i).valueOf()); - xArg.set('float', xArg.get('f32')); - xArg.set('f64', xArg.get('f32')); - xArg.set('double', xArg.get('f64')); - xArg.set('int', xArg.get('i32')); - xResult.set('*', xArg.get(ptrIR)); - xResult.set('pointer', xArg.get(ptrIR)); - xArg.set('**', xArg.get(ptrIR)); - xResult.set('number', (v)=>Number(v)); + const __xArgPtr = 'i32' === ptrIR + ? ((i)=>(i | 0)) : ((i)=>(BigInt(i) | BigInt(0))); + xArg.set('i32', __xArgPtr ) + .set('i16', (i)=>((i | 0) & 0xFFFF)) + .set('i8', (i)=>((i | 0) & 0xFF)) + .set('f32', (i)=>Number(i).valueOf()) + .set('float', xArg.get('f32')) + .set('f64', xArg.get('f32')) + .set('double', xArg.get('f64')) + .set('int', xArg.get('i32')) + .set('null', (i)=>i) + .set(null, xArg.get('null')) + .set('**', __xArgPtr); + xResult.set('*', __xArgPtr) + .set('pointer', __xArgPtr) + .set('number', (v)=>Number(v)) + .set('void', (v)=>undefined) + .set('null', (v)=>v) + .set(null, xResult.get('null')); { /* Copy certain xArg[...] handlers to xResult[...] and add pointer-style variants of them. */ @@ -1430,15 +1441,17 @@ self.WhWasmUtilInstaller = function(target){ TODO? Permit an Int8Array/Uint8Array and convert it to a string? Would that be too much magic concentrated in one place, ready to - backfire? + backfire? We handle that at the client level in sqlite3 with a + custom argument converter. */ - xArg.set('string', function(v){ + const __xArgString = function(v){ if('string'===typeof v) return target.scopedAllocCString(v); - return v ? xArg.get(ptrIR)(v) : null; - }); - xArg.set('utf8', xArg.get('string')); - xArg.set('pointer', xArg.get('string')); - xArg.set('*', xArg.get('string')); + return v ? __xArgPtr(v) : null; + }; + xArg.set('string', __xArgString); + xArg.set('utf8', __xArgString); + xArg.set('pointer', __xArgString); + xArg.set('*', __xArgString); xResult.set('string', (i)=>target.cstrToJs(i)); xResult.set('utf8', xResult.get('string')); @@ -1452,25 +1465,6 @@ self.WhWasmUtilInstaller = function(target){ try{ return i ? JSON.parse(target.cstrToJs(i)) : null } finally{ target.dealloc(i) } }); - xResult.set('void', (v)=>undefined); - xResult.set('null', (v)=>v); - - if(0){ - /*** - This idea can't currently work because we don't know the - signature for the func and don't have a way for the user to - convey it. To do this we likely need to be able to match - arg/result handlers by a regex, but that would incur an O(N) - cost as we check the regex one at a time. Another use case for - such a thing would be pseudotypes like "int:-1" to say that - the value will always be treated like -1 (which has a useful - case in the sqlite3 bindings). - */ - xArg.set('func-ptr', function(v){ - if(!(v instanceof Function)) return xArg.get(ptrIR); - const f = target.jsFuncToWasm(v, WHAT_SIGNATURE); - }); - } /** Internal-use-only base class for FuncPtrAdapter and potentially @@ -1537,8 +1531,8 @@ self.WhWasmUtilInstaller = function(target){ value. This is only useful for use with "global" functions which do not rely on any state other than this function pointer. If the being-converted function pointer is intended - to be mapped to some sort of state object (e.g. an sqlite3*) - then "context" (see below) is the proper mode. + to be mapped to some sort of state object (e.g. an + `sqlite3*`) then "context" (see below) is the proper mode. - 'context': similar to singleton mode but for a given "context", where the context is a key provided by the user @@ -1698,35 +1692,41 @@ self.WhWasmUtilInstaller = function(target){ (t)=>xResult.get(t) || toss("Result adapter not found:",t); cache.xWrap.convertArg = (t,...args)=>__xArgAdapterCheck(t)(...args); + cache.xWrap.convertArgNoCheck = (t,...args)=>xArg.get(t)(...args); + cache.xWrap.convertResult = (t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined)); + cache.xWrap.convertResultNoCheck = + (t,v)=>(null===t ? v : (t ? xResult.get(t)(v) : undefined)); /** - Creates a wrapper for the WASM-exported function fname. Uses - xGet() to fetch the exported function (which throws on - error) and returns either that function or a wrapper for that + Creates a wrapper for another function which converts the arguments + of the wrapper to argument types accepted by the wrapped function, + then converts the wrapped function's result to another form + for the wrapper. + + The first argument must be one of: + + - A JavaScript function. + - The name of a WASM-exported function. In the latter case xGet() + is used to fetch the exported function, which throws if it's not + found. + - A pointer into the indirect function table. e.g. a pointer + returned from target.installFunction(). + + It returns either the passed-in function or a wrapper for that function which converts the JS-side argument types into WASM-side - types and converts the result type. If the function takes no - arguments and resultType is `null` then the function is returned - as-is, else a wrapper is created for it to adapt its arguments - and result value, as described below. + types and converts the result type. - (If you're familiar with Emscripten's ccall() and cwrap(), this - function is essentially cwrap() on steroids.) - - This function's arguments are: - - - fname: the exported function's name. xGet() is used to fetch - this, so will throw if no exported function is found with that - name. - - - resultType: the name of the result type. A literal `null` means - to return the original function's value as-is (mnemonic: there - is "null" conversion going on). Literal `undefined` or the - string `"void"` mean to ignore the function's result and return - `undefined`. Aside from those two special cases, it may be one - of the values described below or any mapping installed by the - client using xWrap.resultAdapter(). + The second argument, `resultType`, describes the conversion for + the wrapped functions result. A literal `null` or the string + `'null'` both mean to return the original function's value as-is + (mnemonic: there is "null" conversion going on). Literal + `undefined` or the string `"void"` both mean to ignore the + function's result and return `undefined`. Aside from those two + special cases, the `resultType` value may be one of the values + described below or any mapping installed by the client using + xWrap.resultAdapter(). If passed 3 arguments and the final one is an array, that array must contain a list of type names (see below) for adapting the @@ -1740,6 +1740,12 @@ self.WhWasmUtilInstaller = function(target){ xWrap('funcname', 'i32', ['string', 'f64']); ``` + This function enforces that the given list of arguments has the + same arity as the being-wrapped function (as defined by its + `length` property) and it will throw if that is not the case. + Similarly, the created wrapper will throw if passed a differing + argument count. + Type names are symbolic names which map the arguments to an adapter function to convert, if needed, the value before passing it on to WASM or to convert a return result from WASM. The list @@ -1776,6 +1782,10 @@ self.WhWasmUtilInstaller = function(target){ Non-numeric conversions include: + - `null` literal or `"null"` string (args and results): perform + no translation and pass the arg on as-is. This is primarily + useful for results but may have a use or two for arguments. + - `string` or `utf8` (args): has two different semantics in order to accommodate various uses of certain C APIs (e.g. output-style strings)... @@ -1790,9 +1800,9 @@ self.WhWasmUtilInstaller = function(target){ client has already allocated and it's passed on as a WASM pointer. - - `string` or `utf8` (results): treats the result value as a - const C-string, encoded as UTF-8, copies it to a JS string, - and returns that JS string. + - `string` or `utf8` (results): treats the result value as a + const C-string, encoded as UTF-8, copies it to a JS string, + and returns that JS string. - `string:dealloc` or `utf8:dealloc) (results): treats the result value as a non-const UTF-8 C-string, ownership of which has just been @@ -1829,6 +1839,11 @@ self.WhWasmUtilInstaller = function(target){ type conversions are valid for both arguments _and_ result types as they often have different memory ownership requirements. + Design note: the ability to pass in a JS function as the first + argument is of relatively limited use, primarily for testing + argument and result converters. JS functions, by and large, will + not want to deal with C-type arguments. + TODOs: - Figure out how/whether we can (semi-)transparently handle @@ -1849,14 +1864,21 @@ self.WhWasmUtilInstaller = function(target){ abstracting it into this API (and taking on the associated costs) may well not make good sense. */ - target.xWrap = function(fname, resultType, ...argTypes){ + target.xWrap = function(fArg, resultType, ...argTypes){ if(3===arguments.length && Array.isArray(arguments[2])){ argTypes = arguments[2]; } - const xf = target.xGet(fname); - if(argTypes.length!==xf.length) __argcMismatch(fname, xf.length); + if(target.isPtr(fArg)){ + fArg = target.functionEntry(fArg) + || toss("Function pointer not found in WASM function table."); + } + const fIsFunc = (fArg instanceof Function); + const xf = fIsFunc ? fArg : target.xGet(fArg); + if(fIsFunc) fArg = xf.name || 'unnamed function'; + if(argTypes.length!==xf.length) __argcMismatch(fArg, xf.length); if((null===resultType) && 0===xf.length){ - /* Func taking no args with an as-is return. We don't need a wrapper. */ + /* Func taking no args with an as-is return. We don't need a wrapper. + We forego the argc check here, though. */ return xf; } /*Verify the arg type conversions are valid...*/; @@ -1869,11 +1891,11 @@ self.WhWasmUtilInstaller = function(target){ if(0===xf.length){ // No args to convert, so we can create a simpler wrapper... return (...args)=>(args.length - ? __argcMismatch(fname, xf.length) + ? __argcMismatch(fArg, xf.length) : cxw.convertResult(resultType, xf.call(null))); } return function(...args){ - if(args.length!==xf.length) __argcMismatch(fname, xf.length); + if(args.length!==xf.length) __argcMismatch(fArg, xf.length); const scope = target.scopedAllocPush(); try{ /* @@ -1891,8 +1913,8 @@ self.WhWasmUtilInstaller = function(target){ and what those arguments are, is _not_ part of the public interface and is _not_ stable. */ - for(const i in args) args[i] = cxw.convertArg(argTypes[i], args[i], i, args); - return cxw.convertResult(resultType, xf.apply(null,args)); + for(const i in args) args[i] = cxw.convertArgNoCheck(argTypes[i], args[i], i, args); + return cxw.convertResultNoCheck(resultType, xf.apply(null,args)); }finally{ target.scopedAllocPop(scope); } @@ -1984,14 +2006,13 @@ self.WhWasmUtilInstaller = function(target){ /** Functions like xCall() but performs argument and result type - conversions as for xWrap(). The first argument is the name of the - exported function to call. The 2nd its the name of its result - type, as documented for xWrap(). The 3rd is an array of argument - type name, as documented for xWrap() (use a falsy value or an - empty array for nullary functions). The 4th+ arguments are - arguments for the call, with the special case that if the 4th - argument is an array, it is used as the arguments for the - call. Returns the converted result of the call. + conversions as for xWrap(). The first, second, and third + arguments are as documented for xWrap(), except that the 3rd + argument may be either a falsy value or empty array to represent + nullary functions. The 4th+ arguments are arguments for the call, + with the special case that if the 4th argument is an array, it is + used as the arguments for the call. Returns the converted result + of the call. This is just a thin wrapper around xWrap(). If the given function is to be called more than once, it's more efficient to use @@ -2000,9 +2021,9 @@ self.WhWasmUtilInstaller = function(target){ arguably more efficient because it will hypothetically free the wrapper function quickly. */ - target.xCallWrapped = function(fname, resultType, argTypes, ...args){ + target.xCallWrapped = function(fArg, resultType, argTypes, ...args){ if(Array.isArray(arguments[3])) args = arguments[3]; - return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]); + return target.xWrap(fArg, resultType, argTypes||[]).apply(null, args||[]); }; /** diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index bef34a0ba5..eb014d7b51 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -539,7 +539,7 @@ self.sqlite3InitModule = sqlite3InitModule; } w.dealloc(m); } - + // isPtr32() { const ip = w.isPtr32; @@ -743,6 +743,65 @@ self.sqlite3InitModule = sqlite3InitModule; .assert('HI' === cj(new Uint8Array([72, 73]))); }); + // jsFuncToWasm() + { + const fsum3 = (x,y,z)=>x+y+z; + fw = w.jsFuncToWasm('i(iii)', fsum3); + T.assert(fw instanceof Function) + .assert( fsum3 !== fw ) + .assert( 3 === fw.length ) + .assert( 6 === fw(1,2,3) ); + T.mustThrowMatching( ()=>w.jsFuncToWasm('x()', function(){}), + 'Invalid signature letter: x'); + } + + // xWrap(Function,...) + { + let fp; + try { + const fmy = function fmy(i,s,d){ + if(fmy.debug) log("fmy(",...arguments,")"); + T.assert( 3 === i ) + .assert( w.isPtr(s) ) + .assert( w.cstrToJs(s) === 'a string' ) + .assert( T.eqApprox(1.2, d) ); + return w.allocCString("hi"); + }; + fmy.debug = false; + const xwArgs = ['string:dealloc', ['i32', 'string', 'f64']]; + fw = w.xWrap(fmy, ...xwArgs); + const fmyArgs = [3, 'a string', 1.2]; + let rc = fw(...fmyArgs); + T.assert( 'hi' === rc ); + if(0){ + /* Retain this as a "reminder to self"... + + This extra level of indirection does not work: the + string argument is ending up as a null in fmy() but + the numeric arguments are making their ways through + + What's happening is: installFunction() is creating a + WASM-compatible function instance. When we pass a JS string + into there it's getting coerced into `null` before being passed + on to the lower-level wrapper. + */ + fmy.debug = true; + fp = wasm.installFunction('i(isd)', fw); + fw = w.functionEntry(fp); + rc = fw(...fmyArgs); + log("rc =",rc); + T.assert( 'hi' === rc ); + // Similarly, this does not work: + //let fpw = w.xWrap(fp, null, [null,null,null]); + //rc = fpw(...fmyArgs); + //log("rc =",rc); + //T.assert( 'hi' === rc ); + } + }finally{ + wasm.uninstallFunction(fp); + } + } + if(haveWasmCTests()){ if(!sqlite3.config.useStdAlloc){ fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']); @@ -768,7 +827,7 @@ self.sqlite3InitModule = sqlite3InitModule; }); } } - } + }/*xWrap()*/ }/*WhWasmUtil*/) //////////////////////////////////////////////////////////////////// @@ -997,7 +1056,6 @@ self.sqlite3InitModule = sqlite3InitModule; P.restore(stack); } }/*pstack tests*/) - //////////////////////////////////////////////////////////////////// ;/*end of C/WASM utils checks*/ diff --git a/manifest b/manifest index eacaf992fb..a0be8ba9e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3.capi\sJS\sbindings\sfor\sthe\ssqlite3session_...(),\ssqlite3changeset_...()\sand\ssqlite3changegroup_...()\sAPIs,\snoting\sthat\sthey\sare\scompletely\suntested.\sAside\sfrom\smissing\stests,\sthese\sbindings\sreveal\sa\sslight\sstring-argument-type\sshortcoming\sin\sthe\scallback\sfunction\spointer\s"reverse\sbinding"\swhich\sshould\sideally\sbe\sresolved\sbefore\spublishing\sthem. -D 2022-12-23T14:11:54.508 +C Internal\scleanups\sand\sminor\sspeed\soptimizations\sin\sthe\ssqlite3.wasm.xWrap()\sinfrastructure. +D 2022-12-23T18:14:36.766 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js af85d9a09fa79847d08279be0f61978ecc3bed893c88003f4a85d8bd204e6b5a +F ext/wasm/common/whwasmutil.js ccfd4addd60f0c3f02ee1669c4e5c8935ca770ed7b737ea3e9e82cc6505576c8 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js c45c46cdae1949d426ee12a736087ab180beacc2a20cd829f9052b957adf9ac9 +F ext/wasm/tester1.c-pp.js 4202e7ec525445386f29612ddf1365348edd1f6002b8b21721c954b9569b756a F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cd8c100808da1043fcf63555f48f30c90272c48c6627321ceb0a0995b34733d1 -R 042a575edf17a004d3f3655705629da7 +P 0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d +R 01a5a3416aa00dbf975dac1dad0558b8 U stephan -Z 81bf3460fe50c1e6a01aac07ed8bed30 +Z fd750e2a8255c013dd9faba040bbeb23 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aa150a668b..8d218fa6ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a39172ee134816f5ce17a403b960e9c22bb56efd5bcf77ecde465efe0d88b1d \ No newline at end of file +c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a \ No newline at end of file From a9e1d96cd8d8105f878e60065820f3316a2cd410 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 18:19:28 +0000 Subject: [PATCH 013/165] Cherry-pick [c4dab53b8ea3401abd] for sqlite3.wasm.xWrap() optimizations. FossilOrigin-Name: 9b97412d3aa791870016ab3c6f565b6a6afa1764f98e969833aec093b9b29919 --- ext/wasm/common/whwasmutil.js | 205 +++++++++++++++++++--------------- ext/wasm/tester1.c-pp.js | 64 ++++++++++- manifest | 17 +-- manifest.uuid | 2 +- 4 files changed, 184 insertions(+), 104 deletions(-) diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 87cc100f33..ecd08327f4 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -359,7 +359,8 @@ self.WhWasmUtilInstaller = function(target){ /** Given a function pointer, returns the WASM function table entry - if found, else returns a falsy value. + if found, else returns a falsy value: undefined if fptr is out of + range or null if it's in range but the table entry is empty. */ target.functionEntry = function(fptr){ const ft = target.functionTable(); @@ -552,13 +553,12 @@ self.WhWasmUtilInstaller = function(target){ cache.scopedAlloc[cache.scopedAlloc.length-1].push(ptr); } }catch(e){ - if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); - throw e; + if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); + throw e; } - return ptr; + return ptr; }; - /** Expects a JS function and signature, exactly as for this.jsFuncToWasm(). It uses that function to create a @@ -612,8 +612,13 @@ self.WhWasmUtilInstaller = function(target){ installFunction() has been called and results are undefined if ptr was not returned by that function. The returned function may be passed back to installFunction() to reinstall it. + + To simplify certain use cases, if passed a falsy non-0 value + (noting that 0 is a valid function table index), this function + has no side effects and returns undefined. */ target.uninstallFunction = function(ptr){ + if(!ptr && 0!==ptr) return undefined; const fi = cache.freeFuncIndexes; const ft = target.functionTable(); fi.push(ptr); @@ -730,7 +735,7 @@ self.WhWasmUtilInstaller = function(target){ ? cache : heapWrappers(); for(const p of (Array.isArray(ptr) ? ptr : [ptr])){ switch (type) { - case 'i1': + case 'i1': case 'i8': c.HEAP8[p>>0] = value; continue; case 'i16': c.HEAP16[p>>1] = value; continue; case 'i32': c.HEAP32[p>>2] = value; continue; @@ -803,7 +808,6 @@ self.WhWasmUtilInstaller = function(target){ /** f64 variant of poke8(). */ target.poke64f = (ptr, value)=>target.poke(ptr, value, 'f64'); - /** Deprecated alias for getMemValue() */ target.getMemValue = target.peek; /** Deprecated alias for peekPtr() */ @@ -1351,7 +1355,7 @@ self.WhWasmUtilInstaller = function(target){ const __argcMismatch = (f,n)=>toss(f+"() requires",n,"argument(s)."); - + /** Looks up a WASM-exported function named fname from target.exports. If found, it is called, passed all remaining @@ -1390,18 +1394,25 @@ self.WhWasmUtilInstaller = function(target){ if(target.bigIntEnabled){ xArg.set('i64', (i)=>BigInt(i)); } - xArg.set('i32', (i)=>(i | 0)); - xArg.set('i16', (i)=>((i | 0) & 0xFFFF)); - xArg.set('i8', (i)=>((i | 0) & 0xFF)); - xArg.set('f32', (i)=>Number(i).valueOf()); - xArg.set('float', xArg.get('f32')); - xArg.set('f64', xArg.get('f32')); - xArg.set('double', xArg.get('f64')); - xArg.set('int', xArg.get('i32')); - xResult.set('*', xArg.get(ptrIR)); - xResult.set('pointer', xArg.get(ptrIR)); - xArg.set('**', xArg.get(ptrIR)); - xResult.set('number', (v)=>Number(v)); + const __xArgPtr = 'i32' === ptrIR + ? ((i)=>(i | 0)) : ((i)=>(BigInt(i) | BigInt(0))); + xArg.set('i32', __xArgPtr ) + .set('i16', (i)=>((i | 0) & 0xFFFF)) + .set('i8', (i)=>((i | 0) & 0xFF)) + .set('f32', (i)=>Number(i).valueOf()) + .set('float', xArg.get('f32')) + .set('f64', xArg.get('f32')) + .set('double', xArg.get('f64')) + .set('int', xArg.get('i32')) + .set('null', (i)=>i) + .set(null, xArg.get('null')) + .set('**', __xArgPtr); + xResult.set('*', __xArgPtr) + .set('pointer', __xArgPtr) + .set('number', (v)=>Number(v)) + .set('void', (v)=>undefined) + .set('null', (v)=>v) + .set(null, xResult.get('null')); { /* Copy certain xArg[...] handlers to xResult[...] and add pointer-style variants of them. */ @@ -1430,15 +1441,17 @@ self.WhWasmUtilInstaller = function(target){ TODO? Permit an Int8Array/Uint8Array and convert it to a string? Would that be too much magic concentrated in one place, ready to - backfire? + backfire? We handle that at the client level in sqlite3 with a + custom argument converter. */ - xArg.set('string', function(v){ + const __xArgString = function(v){ if('string'===typeof v) return target.scopedAllocCString(v); - return v ? xArg.get(ptrIR)(v) : null; - }); - xArg.set('utf8', xArg.get('string')); - xArg.set('pointer', xArg.get('string')); - xArg.set('*', xArg.get('string')); + return v ? __xArgPtr(v) : null; + }; + xArg.set('string', __xArgString); + xArg.set('utf8', __xArgString); + xArg.set('pointer', __xArgString); + xArg.set('*', __xArgString); xResult.set('string', (i)=>target.cstrToJs(i)); xResult.set('utf8', xResult.get('string')); @@ -1452,25 +1465,6 @@ self.WhWasmUtilInstaller = function(target){ try{ return i ? JSON.parse(target.cstrToJs(i)) : null } finally{ target.dealloc(i) } }); - xResult.set('void', (v)=>undefined); - xResult.set('null', (v)=>v); - - if(0){ - /*** - This idea can't currently work because we don't know the - signature for the func and don't have a way for the user to - convey it. To do this we likely need to be able to match - arg/result handlers by a regex, but that would incur an O(N) - cost as we check the regex one at a time. Another use case for - such a thing would be pseudotypes like "int:-1" to say that - the value will always be treated like -1 (which has a useful - case in the sqlite3 bindings). - */ - xArg.set('func-ptr', function(v){ - if(!(v instanceof Function)) return xArg.get(ptrIR); - const f = target.jsFuncToWasm(v, WHAT_SIGNATURE); - }); - } /** Internal-use-only base class for FuncPtrAdapter and potentially @@ -1537,8 +1531,8 @@ self.WhWasmUtilInstaller = function(target){ value. This is only useful for use with "global" functions which do not rely on any state other than this function pointer. If the being-converted function pointer is intended - to be mapped to some sort of state object (e.g. an sqlite3*) - then "context" (see below) is the proper mode. + to be mapped to some sort of state object (e.g. an + `sqlite3*`) then "context" (see below) is the proper mode. - 'context': similar to singleton mode but for a given "context", where the context is a key provided by the user @@ -1688,35 +1682,41 @@ self.WhWasmUtilInstaller = function(target){ (t)=>xResult.get(t) || toss("Result adapter not found:",t); cache.xWrap.convertArg = (t,...args)=>__xArgAdapterCheck(t)(...args); + cache.xWrap.convertArgNoCheck = (t,...args)=>xArg.get(t)(...args); + cache.xWrap.convertResult = (t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined)); + cache.xWrap.convertResultNoCheck = + (t,v)=>(null===t ? v : (t ? xResult.get(t)(v) : undefined)); /** - Creates a wrapper for the WASM-exported function fname. Uses - xGet() to fetch the exported function (which throws on - error) and returns either that function or a wrapper for that + Creates a wrapper for another function which converts the arguments + of the wrapper to argument types accepted by the wrapped function, + then converts the wrapped function's result to another form + for the wrapper. + + The first argument must be one of: + + - A JavaScript function. + - The name of a WASM-exported function. In the latter case xGet() + is used to fetch the exported function, which throws if it's not + found. + - A pointer into the indirect function table. e.g. a pointer + returned from target.installFunction(). + + It returns either the passed-in function or a wrapper for that function which converts the JS-side argument types into WASM-side - types and converts the result type. If the function takes no - arguments and resultType is `null` then the function is returned - as-is, else a wrapper is created for it to adapt its arguments - and result value, as described below. + types and converts the result type. - (If you're familiar with Emscripten's ccall() and cwrap(), this - function is essentially cwrap() on steroids.) - - This function's arguments are: - - - fname: the exported function's name. xGet() is used to fetch - this, so will throw if no exported function is found with that - name. - - - resultType: the name of the result type. A literal `null` means - to return the original function's value as-is (mnemonic: there - is "null" conversion going on). Literal `undefined` or the - string `"void"` mean to ignore the function's result and return - `undefined`. Aside from those two special cases, it may be one - of the values described below or any mapping installed by the - client using xWrap.resultAdapter(). + The second argument, `resultType`, describes the conversion for + the wrapped functions result. A literal `null` or the string + `'null'` both mean to return the original function's value as-is + (mnemonic: there is "null" conversion going on). Literal + `undefined` or the string `"void"` both mean to ignore the + function's result and return `undefined`. Aside from those two + special cases, the `resultType` value may be one of the values + described below or any mapping installed by the client using + xWrap.resultAdapter(). If passed 3 arguments and the final one is an array, that array must contain a list of type names (see below) for adapting the @@ -1730,6 +1730,12 @@ self.WhWasmUtilInstaller = function(target){ xWrap('funcname', 'i32', ['string', 'f64']); ``` + This function enforces that the given list of arguments has the + same arity as the being-wrapped function (as defined by its + `length` property) and it will throw if that is not the case. + Similarly, the created wrapper will throw if passed a differing + argument count. + Type names are symbolic names which map the arguments to an adapter function to convert, if needed, the value before passing it on to WASM or to convert a return result from WASM. The list @@ -1766,6 +1772,10 @@ self.WhWasmUtilInstaller = function(target){ Non-numeric conversions include: + - `null` literal or `"null"` string (args and results): perform + no translation and pass the arg on as-is. This is primarily + useful for results but may have a use or two for arguments. + - `string` or `utf8` (args): has two different semantics in order to accommodate various uses of certain C APIs (e.g. output-style strings)... @@ -1780,9 +1790,9 @@ self.WhWasmUtilInstaller = function(target){ client has already allocated and it's passed on as a WASM pointer. - - `string` or `utf8` (results): treats the result value as a - const C-string, encoded as UTF-8, copies it to a JS string, - and returns that JS string. + - `string` or `utf8` (results): treats the result value as a + const C-string, encoded as UTF-8, copies it to a JS string, + and returns that JS string. - `string:dealloc` or `utf8:dealloc) (results): treats the result value as a non-const UTF-8 C-string, ownership of which has just been @@ -1819,6 +1829,11 @@ self.WhWasmUtilInstaller = function(target){ type conversions are valid for both arguments _and_ result types as they often have different memory ownership requirements. + Design note: the ability to pass in a JS function as the first + argument is of relatively limited use, primarily for testing + argument and result converters. JS functions, by and large, will + not want to deal with C-type arguments. + TODOs: - Figure out how/whether we can (semi-)transparently handle @@ -1839,14 +1854,21 @@ self.WhWasmUtilInstaller = function(target){ abstracting it into this API (and taking on the associated costs) may well not make good sense. */ - target.xWrap = function(fname, resultType, ...argTypes){ + target.xWrap = function(fArg, resultType, ...argTypes){ if(3===arguments.length && Array.isArray(arguments[2])){ argTypes = arguments[2]; } - const xf = target.xGet(fname); - if(argTypes.length!==xf.length) __argcMismatch(fname, xf.length); + if(target.isPtr(fArg)){ + fArg = target.functionEntry(fArg) + || toss("Function pointer not found in WASM function table."); + } + const fIsFunc = (fArg instanceof Function); + const xf = fIsFunc ? fArg : target.xGet(fArg); + if(fIsFunc) fArg = xf.name || 'unnamed function'; + if(argTypes.length!==xf.length) __argcMismatch(fArg, xf.length); if((null===resultType) && 0===xf.length){ - /* Func taking no args with an as-is return. We don't need a wrapper. */ + /* Func taking no args with an as-is return. We don't need a wrapper. + We forego the argc check here, though. */ return xf; } /*Verify the arg type conversions are valid...*/; @@ -1859,11 +1881,11 @@ self.WhWasmUtilInstaller = function(target){ if(0===xf.length){ // No args to convert, so we can create a simpler wrapper... return (...args)=>(args.length - ? __argcMismatch(fname, xf.length) + ? __argcMismatch(fArg, xf.length) : cxw.convertResult(resultType, xf.call(null))); } return function(...args){ - if(args.length!==xf.length) __argcMismatch(fname, xf.length); + if(args.length!==xf.length) __argcMismatch(fArg, xf.length); const scope = target.scopedAllocPush(); try{ /* @@ -1881,8 +1903,8 @@ self.WhWasmUtilInstaller = function(target){ and what those arguments are, is _not_ part of the public interface and is _not_ stable. */ - for(const i in args) args[i] = cxw.convertArg(argTypes[i], args[i], i, args); - return cxw.convertResult(resultType, xf.apply(null,args)); + for(const i in args) args[i] = cxw.convertArgNoCheck(argTypes[i], args[i], i, args); + return cxw.convertResultNoCheck(resultType, xf.apply(null,args)); }finally{ target.scopedAllocPop(scope); } @@ -1974,14 +1996,13 @@ self.WhWasmUtilInstaller = function(target){ /** Functions like xCall() but performs argument and result type - conversions as for xWrap(). The first argument is the name of the - exported function to call. The 2nd its the name of its result - type, as documented for xWrap(). The 3rd is an array of argument - type name, as documented for xWrap() (use a falsy value or an - empty array for nullary functions). The 4th+ arguments are - arguments for the call, with the special case that if the 4th - argument is an array, it is used as the arguments for the - call. Returns the converted result of the call. + conversions as for xWrap(). The first, second, and third + arguments are as documented for xWrap(), except that the 3rd + argument may be either a falsy value or empty array to represent + nullary functions. The 4th+ arguments are arguments for the call, + with the special case that if the 4th argument is an array, it is + used as the arguments for the call. Returns the converted result + of the call. This is just a thin wrapper around xWrap(). If the given function is to be called more than once, it's more efficient to use @@ -1990,9 +2011,9 @@ self.WhWasmUtilInstaller = function(target){ arguably more efficient because it will hypothetically free the wrapper function quickly. */ - target.xCallWrapped = function(fname, resultType, argTypes, ...args){ + target.xCallWrapped = function(fArg, resultType, argTypes, ...args){ if(Array.isArray(arguments[3])) args = arguments[3]; - return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]); + return target.xWrap(fArg, resultType, argTypes||[]).apply(null, args||[]); }; /** diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index bef34a0ba5..eb014d7b51 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -539,7 +539,7 @@ self.sqlite3InitModule = sqlite3InitModule; } w.dealloc(m); } - + // isPtr32() { const ip = w.isPtr32; @@ -743,6 +743,65 @@ self.sqlite3InitModule = sqlite3InitModule; .assert('HI' === cj(new Uint8Array([72, 73]))); }); + // jsFuncToWasm() + { + const fsum3 = (x,y,z)=>x+y+z; + fw = w.jsFuncToWasm('i(iii)', fsum3); + T.assert(fw instanceof Function) + .assert( fsum3 !== fw ) + .assert( 3 === fw.length ) + .assert( 6 === fw(1,2,3) ); + T.mustThrowMatching( ()=>w.jsFuncToWasm('x()', function(){}), + 'Invalid signature letter: x'); + } + + // xWrap(Function,...) + { + let fp; + try { + const fmy = function fmy(i,s,d){ + if(fmy.debug) log("fmy(",...arguments,")"); + T.assert( 3 === i ) + .assert( w.isPtr(s) ) + .assert( w.cstrToJs(s) === 'a string' ) + .assert( T.eqApprox(1.2, d) ); + return w.allocCString("hi"); + }; + fmy.debug = false; + const xwArgs = ['string:dealloc', ['i32', 'string', 'f64']]; + fw = w.xWrap(fmy, ...xwArgs); + const fmyArgs = [3, 'a string', 1.2]; + let rc = fw(...fmyArgs); + T.assert( 'hi' === rc ); + if(0){ + /* Retain this as a "reminder to self"... + + This extra level of indirection does not work: the + string argument is ending up as a null in fmy() but + the numeric arguments are making their ways through + + What's happening is: installFunction() is creating a + WASM-compatible function instance. When we pass a JS string + into there it's getting coerced into `null` before being passed + on to the lower-level wrapper. + */ + fmy.debug = true; + fp = wasm.installFunction('i(isd)', fw); + fw = w.functionEntry(fp); + rc = fw(...fmyArgs); + log("rc =",rc); + T.assert( 'hi' === rc ); + // Similarly, this does not work: + //let fpw = w.xWrap(fp, null, [null,null,null]); + //rc = fpw(...fmyArgs); + //log("rc =",rc); + //T.assert( 'hi' === rc ); + } + }finally{ + wasm.uninstallFunction(fp); + } + } + if(haveWasmCTests()){ if(!sqlite3.config.useStdAlloc){ fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']); @@ -768,7 +827,7 @@ self.sqlite3InitModule = sqlite3InitModule; }); } } - } + }/*xWrap()*/ }/*WhWasmUtil*/) //////////////////////////////////////////////////////////////////// @@ -997,7 +1056,6 @@ self.sqlite3InitModule = sqlite3InitModule; P.restore(stack); } }/*pstack tests*/) - //////////////////////////////////////////////////////////////////// ;/*end of C/WASM utils checks*/ diff --git a/manifest b/manifest index 9863dbab45..bc2050511c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\slots\sof\sharmless,\snuisance\scompiler\swarnings,\smostly\sunused\sparameter\nwarnings\sin\sextensions. -D 2022-12-23T14:49:24.143 +C Cherry-pick\s[c4dab53b8ea3401abd]\sfor\ssqlite3.wasm.xWrap()\soptimizations. +D 2022-12-23T18:19:28.093 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js ba1a8db1f32124e43e24b3d890102b6552b2c0b5a202185041a55887692df328 +F ext/wasm/common/whwasmutil.js ff43d28d04e60068ecb3e9a2550581f36be5867ad5ffc00d8479580a12cf9b0f F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js c45c46cdae1949d426ee12a736087ab180beacc2a20cd829f9052b957adf9ac9 +F ext/wasm/tester1.c-pp.js 4202e7ec525445386f29612ddf1365348edd1f6002b8b21721c954b9569b756a F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7d3772f0bd0e2602fe919573b49001da4e2b9f3874cb0183dea675204afa7abd -R 16338e89b5ec3a31b67202fe13704742 -U drh -Z 80509b64f86f8701ef91d19f5ff36290 +P c14bbe1606c1450b709970f922b94a641dfc8f9bd09126501d7dc4db99ea4772 +Q +c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a +R 584560ad77984d30d6316ac32176cf60 +U stephan +Z ff71cfe8de9cd6a3b2f8b5e767f940f3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f42d26d9c5..a270ba7305 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c14bbe1606c1450b709970f922b94a641dfc8f9bd09126501d7dc4db99ea4772 \ No newline at end of file +9b97412d3aa791870016ab3c6f565b6a6afa1764f98e969833aec093b9b29919 \ No newline at end of file From 7298c2e09958baccfb3233d71c32611f28e84dc0 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 18:25:48 +0000 Subject: [PATCH 014/165] Add SQLITE_ENABLE_MATH_FUNCTIONS to the list of feature flags in sqlite3-wasm.c. FossilOrigin-Name: 58503cd148c9613abfaf7c1386c34806150bd521966864ccbb821ea7dede8e5a --- ext/wasm/api/sqlite3-wasm.c | 3 +++ manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index a42ea68d42..ed3b96dea1 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -102,6 +102,9 @@ #ifndef SQLITE_ENABLE_OFFSET_SQL_FUNC # define SQLITE_ENABLE_OFFSET_SQL_FUNC 1 #endif +#ifndef SQLITE_ENABLE_MATH_FUNCTIONS +# define SQLITE_ENABLE_MATH_FUNCTIONS 1 +#endif #ifndef SQLITE_ENABLE_RTREE # define SQLITE_ENABLE_RTREE 1 #endif diff --git a/manifest b/manifest index bc2050511c..d89ca1ddac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cherry-pick\s[c4dab53b8ea3401abd]\sfor\ssqlite3.wasm.xWrap()\soptimizations. -D 2022-12-23T18:19:28.093 +C Add\sSQLITE_ENABLE_MATH_FUNCTIONS\sto\sthe\slist\sof\sfeature\sflags\sin\ssqlite3-wasm.c. +D 2022-12-23T18:25:48.377 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 44ce4cf12318b0577d8222cf59132617ab9925ca3cf5fbb8c7b30d1e947c13b5 +F ext/wasm/api/sqlite3-wasm.c b114bb85cdf8be7b2939ddcc2bbc2f30c190c44b993c34a77b017c978345efb1 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -2067,9 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c14bbe1606c1450b709970f922b94a641dfc8f9bd09126501d7dc4db99ea4772 -Q +c4dab53b8ea3401abd57671b8f3cb39fa4431b864d4c4e14ae24592f8d4cba0a -R 584560ad77984d30d6316ac32176cf60 +P 9b97412d3aa791870016ab3c6f565b6a6afa1764f98e969833aec093b9b29919 +R 6b3cc75a9db734dd2c62324fc8b3cb47 U stephan -Z ff71cfe8de9cd6a3b2f8b5e767f940f3 +Z 73682351de194d18be93f357238f8b87 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a270ba7305..9502e899d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b97412d3aa791870016ab3c6f565b6a6afa1764f98e969833aec093b9b29919 \ No newline at end of file +58503cd148c9613abfaf7c1386c34806150bd521966864ccbb821ea7dede8e5a \ No newline at end of file From ace682e149ea98304fce7babeea3c0cbd496f403 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 18:38:14 +0000 Subject: [PATCH 015/165] Explicitly omit threading and extension loading from the ext/wasm/c-pp binary build to avoid a link error on some systems. FossilOrigin-Name: 5d9a14715c25efcd81cadafabf03aad7213251bd1b3dc181939c2dba8d942fb6 --- ext/wasm/GNUmakefile | 5 ++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index db18b283e6..92e552c766 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -213,7 +213,10 @@ DISTCLEAN_FILES += $(bin.stripccomments) # https://fossil.wanderinghorse.net/r/c-pp bin.c-pp := ./c-pp $(bin.c-pp): c-pp.c $(sqlite3.c) $(MAKEFILE) - $(CC) -O0 -o $@ c-pp.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) + $(CC) -O0 -o $@ c-pp.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \ + -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ + -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \ + -DSQLITE_TEMP_STORE=3 define C-PP.FILTER # Create $2 from $1 using $(bin.c-pp) # $1 = Input file: c-pp -f $(1).js diff --git a/manifest b/manifest index d89ca1ddac..2e6714e1d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sSQLITE_ENABLE_MATH_FUNCTIONS\sto\sthe\slist\sof\sfeature\sflags\sin\ssqlite3-wasm.c. -D 2022-12-23T18:25:48.377 +C Explicitly\somit\sthreading\sand\sextension\sloading\sfrom\sthe\sext/wasm/c-pp\sbinary\sbuild\sto\savoid\sa\slink\serror\son\ssome\ssystems. +D 2022-12-23T18:38:14.809 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -491,7 +491,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 06d385b51bfb206cf779cf1bb816862f77df97fff97a6df9baf05b98c027067a +F ext/wasm/GNUmakefile ffe0e9818a3b6b36c85a1d10dab76b220a8f5cd83439c62e50223a7970b3d68a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 4c7788042196cecab32f87d8e4965c183fea59037603888059f244b1752babcc @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9b97412d3aa791870016ab3c6f565b6a6afa1764f98e969833aec093b9b29919 -R 6b3cc75a9db734dd2c62324fc8b3cb47 +P 58503cd148c9613abfaf7c1386c34806150bd521966864ccbb821ea7dede8e5a +R 074fed6133dc78bb8d0d984f37c88d73 U stephan -Z 73682351de194d18be93f357238f8b87 +Z 7a321f6978c55ea122099ade7e707faf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9502e899d5..55e133b567 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58503cd148c9613abfaf7c1386c34806150bd521966864ccbb821ea7dede8e5a \ No newline at end of file +5d9a14715c25efcd81cadafabf03aad7213251bd1b3dc181939c2dba8d942fb6 \ No newline at end of file From 0953c5354acc29479eda7b8ff3c5f7a88d482c5a Mon Sep 17 00:00:00 2001 From: larrybr Date: Fri, 23 Dec 2022 19:04:59 +0000 Subject: [PATCH 016/165] Add base64() and base85() text/blob conversions to the CLI. FossilOrigin-Name: 4bc98a2d9520efa9b80142163cbfab72a5f2fe9854cd6ba8291dcefdb872e657 --- Makefile.in | 5 +- ext/misc/base64.c | 28 +++---- ext/misc/base85.c | 30 ++++--- ext/misc/basexx.c | 3 + manifest | 26 +++--- manifest.uuid | 2 +- src/shell.c.in | 203 +++++++++++++++++++++++++--------------------- test/shell1.test | 12 +++ tool/mkshellc.tcl | 2 +- 9 files changed, 170 insertions(+), 141 deletions(-) diff --git a/Makefile.in b/Makefile.in index f808312c69..e1cc5293f4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -437,7 +437,7 @@ TESTSRC = \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/test_recover.c \ - $(TOP)/ext/rbu/test_rbu.c + $(TOP)/ext/rbu/test_rbu.c # Statically linked extensions # @@ -1118,6 +1118,9 @@ SHELL_SRC = \ $(TOP)/ext/misc/appendvfs.c \ $(TOP)/ext/misc/completion.c \ $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/basexx.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/ieee754.c \ $(TOP)/ext/misc/regexp.c \ diff --git a/ext/misc/base64.c b/ext/misc/base64.c index 81767379b1..20297367eb 100755 --- a/ext/misc/base64.c +++ b/ext/misc/base64.c @@ -53,9 +53,7 @@ #include -#ifndef SQLITE_SHELL_EXTFUNCS /* Guard for #include as built-in extension. */ #include "sqlite3ext.h" -#endif SQLITE_EXTENSION_INIT1; @@ -64,12 +62,12 @@ SQLITE_EXTENSION_INIT1; #define ND 0x82 /* Not above or digit-value */ #define PAD_CHAR '=' -#ifndef UBYTE_TYPEDEF -typedef unsigned char ubyte; -# define UBYTE_TYPEDEF +#ifndef U8_TYPEDEF +typedef unsigned char u8; +#define U8_TYPEDEF #endif -static const ubyte b64DigitValues[128] = { +static const u8 b64DigitValues[128] = { /* HT LF VT FF CR */ ND,ND,ND,ND, ND,ND,ND,ND, ND,WS,WS,WS, WS,WS,ND,ND, /* US */ @@ -92,18 +90,18 @@ static const char b64Numerals[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #define BX_DV_PROTO(c) \ - ((((ubyte)(c))<0x80)? (ubyte)(b64DigitValues[(ubyte)(c)]) : 0x80) -#define IS_BX_DIGIT(bdp) (((ubyte)(bdp))<0x80) + ((((u8)(c))<0x80)? (u8)(b64DigitValues[(u8)(c)]) : 0x80) +#define IS_BX_DIGIT(bdp) (((u8)(bdp))<0x80) #define IS_BX_WS(bdp) ((bdp)==WS) #define IS_BX_PAD(bdp) ((bdp)==PC) -#define BX_NUMERAL(dv) (b64Numerals[(ubyte)(dv)]) +#define BX_NUMERAL(dv) (b64Numerals[(u8)(dv)]) /* Width of base64 lines. Should be an integer multiple of 4. */ #define B64_DARK_MAX 72 /* Encode a byte buffer into base64 text with linefeeds appended to limit ** encoded group lengths to B64_DARK_MAX or to terminate the last group. */ -static char* toBase64( ubyte *pIn, int nbIn, char *pOut ){ +static char* toBase64( u8 *pIn, int nbIn, char *pOut ){ int nCol = 0; while( nbIn >= 3 ){ /* Do the bit-shuffle, exploiting unsigned input to avoid masking. */ @@ -128,7 +126,7 @@ static char* toBase64( ubyte *pIn, int nbIn, char *pOut ){ if( nbe=0; --nbe ){ - char ce = (nbe>= 6; pOut[nbe] = ce; } @@ -147,7 +145,7 @@ static char * skipNonB64( char *s ){ } /* Decode base64 text into a byte buffer. */ -static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){ +static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){ if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn; while( ncIn>0 && *pIn!=PAD_CHAR ){ static signed char nboi[] = { 0, 0, 1, 2, 3 }; @@ -162,7 +160,7 @@ static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){ if( nbo==0 ) break; for( nac=0; nac<4; ++nac ){ char c = (nac='#')+((c)>'&')+((c)>='*')+((c)>'z')) /* Provide digitValue to b85Numeral offset as a function of above class. */ -static ubyte b85_cOffset[] = { 0, '#', 0, '*'-4, 0 }; +static u8 b85_cOffset[] = { 0, '#', 0, '*'-4, 0 }; #define B85_DNOS( c ) b85_cOffset[B85_CLASS(c)] /* Say whether c is a base85 numeral. */ #define IS_B85( c ) (B85_CLASS(c) & 1) #if 0 /* Not used, */ -static ubyte base85DigitValue( char c ){ - ubyte dv = (ubyte)(c - '#'); +static u8 base85DigitValue( char c ){ + u8 dv = (u8)(c - '#'); if( dv>87 ) return 0xff; return (dv > 3)? dv-3 : dv; } @@ -151,7 +149,7 @@ static char * skipNonB85( char *s ){ /* Convert small integer, known to be in 0..84 inclusive, to base85 numeral. * Do not use the macro form with argument expression having a side-effect.*/ #if 0 -static char base85Numeral( ubyte b ){ +static char base85Numeral( u8 b ){ return (b < 4)? (char)(b + '#') : (char)(b - 4 + '*'); } #else @@ -169,7 +167,7 @@ static char *putcs(char *pc, char *s){ ** to be appended to encoded groups to limit their length to B85_DARK_MAX ** or to terminate the last group (to aid concatenation.) */ -static char* toBase85( ubyte *pIn, int nbIn, char *pOut, char *pSep ){ +static char* toBase85( u8 *pIn, int nbIn, char *pOut, char *pSep ){ int nCol = 0; while( nbIn >= 4 ){ int nco = 5; @@ -197,7 +195,7 @@ static char* toBase85( ubyte *pIn, int nbIn, char *pOut, char *pSep ){ } nCol += nco; while( nco > 0 ){ - ubyte dv = (ubyte)(qv % 85); + u8 dv = (u8)(qv % 85); qv /= 85; pOut[--nco] = base85Numeral(dv); } @@ -209,7 +207,7 @@ static char* toBase85( ubyte *pIn, int nbIn, char *pOut, char *pSep ){ } /* Decode base85 text into a byte buffer. */ -static ubyte* fromBase85( char *pIn, int ncIn, ubyte *pOut ){ +static u8* fromBase85( char *pIn, int ncIn, u8 *pOut ){ if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn; while( ncIn>0 ){ static signed char nboi[] = { 0, 0, 1, 2, 3, 4 }; @@ -223,7 +221,7 @@ static ubyte* fromBase85( char *pIn, int ncIn, ubyte *pOut ){ if( nbo==0 ) break; while( nti>0 ){ char c = *pIn++; - ubyte cdo = B85_DNOS(c); + u8 cdo = B85_DNOS(c); --ncIn; if( cdo==0 ) break; qv = 85 * qv + (c - cdo); @@ -287,7 +285,7 @@ static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), SQLITE_LIMIT_LENGTH, -1); char *cBuf; - ubyte *bBuf; + u8 *bBuf; assert(na==1); switch( sqlite3_value_type(av[0]) ){ case SQLITE_BLOB: @@ -300,7 +298,7 @@ static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ } cBuf = sqlite3_malloc(nc); if( !cBuf ) goto memFail; - bBuf = (ubyte*)sqlite3_value_blob(av[0]); + bBuf = (u8*)sqlite3_value_blob(av[0]); nc = (int)(toBase85(bBuf, nb, cBuf, "\n") - cBuf); sqlite3_result_text(context, cBuf, nc, sqlite3_free); break; @@ -370,7 +368,7 @@ static int sqlite3_base85_init int main(int na, char *av[]){ int cin; int rc = 0; - ubyte bBuf[4*(B85_DARK_MAX/5)]; + u8 bBuf[4*(B85_DARK_MAX/5)]; char cBuf[5*(sizeof(bBuf)/4)+2]; size_t nio; # ifndef OMIT_BASE85_CHECKER diff --git a/ext/misc/basexx.c b/ext/misc/basexx.c index 2ca2906fae..c1808aa70f 100644 --- a/ext/misc/basexx.c +++ b/ext/misc/basexx.c @@ -49,6 +49,9 @@ static void init_api_ptr(const sqlite3_api_routines *pApi){ #undef SQLITE_EXTENSION_INIT2 #define SQLITE_EXTENSION_INIT2(v) (void)v +typedef unsigned char u8; +#define U8_TYPEDEF + /* These next 2 undef's are only needed because the entry point names * collide when formulated per the rules stated for loadable extension * entry point names that will be deduced from the file basenames. diff --git a/manifest b/manifest index 2e6714e1d2..756fdd39c9 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Explicitly\somit\sthreading\sand\sextension\sloading\sfrom\sthe\sext/wasm/c-pp\sbinary\sbuild\sto\savoid\sa\slink\serror\son\ssome\ssystems. -D 2022-12-23T18:38:14.809 +C Add\sbase64()\sand\sbase85()\stext/blob\sconversions\sto\sthe\sCLI. +D 2022-12-23T19:04:59.875 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c223963d7b0828f26cb62ea3e0f583d26839b7d3ef0d1cca87f35c4b222ff01b +F Makefile.in 341f02570d220695100004c447773ecb6c082e24178fc45dcbc0a212abaa0655 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc e86ec21328921721dd6f777da435c62a5469cda1a654f5ecefacf87ddb3dfeb3 F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e @@ -289,9 +289,9 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23 F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 -F ext/misc/base64.c 1ad313d38dc081abe5a87fa51e44f07ec6cfb618aa9606a77e42bd2fe706a67f x -F ext/misc/base85.c ace591246855806a70e63eb6705ce8736f4b782da2137bdbb5d39cc337346e0d -F ext/misc/basexx.c 58f72b3c159e875bfd2d30a56254e7f2098961c31dc733773a9270de7066aa4c +F ext/misc/base64.c d9bcb499d4edf42d1d981cc49af0a084532af288f982facb83e23c2e46f7c009 x +F ext/misc/base85.c 4b53d66c50e120e8697dd2a8ea6ddbc8750a4a1f6bcc6e0b7202a3998b0852bc +F ext/misc/basexx.c 5e859e1820620aa8080fb9145eb47089de426ae808f6abb01a8e12921c3a8e67 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 F ext/misc/carray.c b752f46411e4e47e34dce6f0c88bc8e51bb821ba9e49bfcd882506451c928f69 @@ -646,7 +646,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 83de67e4857be2866d048c98e93f65461d8a0408ca4ce88fec68ebfe030997ae -F src/shell.c.in fb29e3fb40c84a453b5f5d7bf32b5c2fb9f2207b1a97ff76490c5d8a2ec22575 +F src/shell.c.in 01816a1e0eb3a2e9a9a4b11570d68058969c88b2ec5ecaf80c57d6ca1b8d46a4 F src/sqlite.h.in e752f82b9d71f1d42b259b1900e4b1caf0965e844d756cd5cc91cc2cf45ed925 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f @@ -1501,7 +1501,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test e4b4de56f454708e0747b52915135baa2cbfec4965406d6eaf02a4a5c22a9880 +F test/shell1.test ab88e763854ea4734796067e20e258589b4d5bb9e77d70d8c4c8e99cf77c8b64 F test/shell2.test 1190b951373fdfe719bc6ac16962bc743dfa4355db8ae546c0bb9bf559a28d4a F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a F test/shell4.test 9abd0c12a7e20a4c49e84d5be208d2124fa6c09e728f56f1f4bee0f02853935f @@ -1999,7 +1999,7 @@ F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61 F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl bd07bd59d45d0f3448e123d6937e9811195f9908a51e09d774609883055bfd3d -F tool/mkshellc.tcl 02d0de8349ef830c0fb20d29680320bde2466e2ec422e5bd94c4317a7a7e8cc9 +F tool/mkshellc.tcl b7adf08b82de60811d2cb6af05ff59fc17e5cd6f3e98743c14eaaa3f8971fed0 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58503cd148c9613abfaf7c1386c34806150bd521966864ccbb821ea7dede8e5a -R 074fed6133dc78bb8d0d984f37c88d73 -U stephan -Z 7a321f6978c55ea122099ade7e707faf +P 5d9a14715c25efcd81cadafabf03aad7213251bd1b3dc181939c2dba8d942fb6 +R f473ce0dc90c010b804e2b9eefdd163f +U larrybr +Z 3ee7c528f374ab6814608dd44133cc19 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 55e133b567..936b19aef9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d9a14715c25efcd81cadafabf03aad7213251bd1b3dc181939c2dba8d942fb6 \ No newline at end of file +4bc98a2d9520efa9b80142163cbfab72a5f2fe9854cd6ba8291dcefdb872e657 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 20109e0cd3..d247fa6c22 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -21,7 +21,7 @@ typedef unsigned short int u16; /* ** Optionally #include a user-defined header, whereby compilation options -** may be set prior to where they take effect, but after platform setup. +** may be set prior to where they take effect, but after platform setup. ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include ** file. Note that this macro has a like effect on sqlite3.c compilation. */ @@ -535,7 +535,8 @@ static char *dynamicContinuePrompt(void){ return continuePrompt; }else{ if( dynPrompt.zScannerAwaits ){ - size_t ncp = strlen(continuePrompt), ndp = strlen(dynPrompt.zScannerAwaits); + size_t ncp = strlen(continuePrompt); + size_t ndp = strlen(dynPrompt.zScannerAwaits); if( ndp > ncp-3 ) return continuePrompt; strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' '; @@ -1033,7 +1034,7 @@ static void shellModuleSchema( char *zFake; UNUSED_PARAMETER(nVal); zName = (const char*)sqlite3_value_text(apVal[0]); - zFake = zName ? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0; + zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0; if( zFake ){ sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), -1, sqlite3_free); @@ -1132,6 +1133,13 @@ INCLUDE ../ext/misc/memtrace.c INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/uint.c INCLUDE ../ext/misc/decimal.c +#undef sqlite3_base_init +#define sqlite3_base_init sqlite3_base64_init +INCLUDE ../ext/misc/base64.c +#undef sqlite3_base_init +#define sqlite3_base_init sqlite3_base85_init +#define OMIT_BASE85_CHECKER +INCLUDE ../ext/misc/base85.c INCLUDE ../ext/misc/ieee754.c INCLUDE ../ext/misc/series.c INCLUDE ../ext/misc/regexp.c @@ -1588,7 +1596,7 @@ static void editFunc( } sz = j; p[sz] = 0; - } + } sqlite3_result_text64(context, (const char*)p, sz, sqlite3_free, SQLITE_UTF8); } @@ -2763,9 +2771,9 @@ static char *shell_error_context(const char *zSql, sqlite3 *db){ shell_check_oom(zCode); for(i=0; zCode[i]; i++){ if( IsSpace(zSql[i]) ) zCode[i] = ' '; } if( iOffset<25 ){ - zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here", zCode, iOffset, ""); + zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here", zCode,iOffset,""); }else{ - zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^", zCode, iOffset-14, ""); + zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^", zCode,iOffset-14,""); } return zMsg; } @@ -2953,7 +2961,7 @@ static int display_stats( if( pArg->statsOn==3 ){ if( pArg->pStmt ){ - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset); raw_printf(pArg->out, "VM-steps: %d\n", iCur); } return 0; @@ -3034,8 +3042,10 @@ static int display_stats( raw_printf(pArg->out, "Sort Operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); - iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset); - iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset); + iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, + bReset); + iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, + bReset); if( iHit || iMiss ){ raw_printf(pArg->out, "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); @@ -3064,7 +3074,7 @@ static int display_stats( static int scanStatsHeight(sqlite3_stmt *p, int iEntry){ int iPid = 0; int ret = 1; - sqlite3_stmt_scanstatus_v2(p, iEntry, + sqlite3_stmt_scanstatus_v2(p, iEntry, SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid ); while( iPid!=0 ){ @@ -3072,12 +3082,12 @@ static int scanStatsHeight(sqlite3_stmt *p, int iEntry){ for(ii=0; 1; ii++){ int iId; int res; - res = sqlite3_stmt_scanstatus_v2(p, ii, + res = sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId ); if( res ) break; if( iId==iPid ){ - sqlite3_stmt_scanstatus_v2(p, ii, + sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid ); } @@ -3409,7 +3419,7 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ ** characters */ static void print_box_line(FILE *out, int N){ - const char zDash[] = + const char zDash[] = BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; const int nDash = sizeof(zDash) - 1; @@ -3538,7 +3548,7 @@ static char *translateForDisplayAndDup( break; } zOut[j] = 0; - return (char*)zOut; + return (char*)zOut; } /* Extract the value of the i-th current column for pStmt as an SQL literal @@ -3899,8 +3909,8 @@ static void exec_prepared_stmt( ** caller to eventually free this buffer using sqlite3_free(). */ static int expertHandleSQL( - ShellState *pState, - const char *zSql, + ShellState *pState, + const char *zSql, char **pzErr ){ assert( pState->expert.pExpert ); @@ -3910,7 +3920,7 @@ static int expertHandleSQL( /* ** This function is called either to silently clean up the object -** created by the ".expert" command (if bCancel==1), or to generate a +** created by the ".expert" command (if bCancel==1), or to generate a ** report from it and then clean it up (if bCancel==0). ** ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error @@ -4005,7 +4015,8 @@ static int expertDotCommand( if( rc==SQLITE_OK ){ pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); if( pState->expert.pExpert==0 ){ - raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); + raw_printf(stderr, "sqlite3_expert_new: %s\n", + zErr ? zErr : "out of memory"); rc = SQLITE_ERROR; }else{ sqlite3_expert_config( @@ -4966,7 +4977,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){ } } fclose(f); - return rc; + return rc; } #ifndef SQLITE_OMIT_DESERIALIZE @@ -5065,8 +5076,8 @@ readHexDb_error: ** offset (4*) of the blob. */ static void shellInt32( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const unsigned char *pBlob; @@ -5093,8 +5104,8 @@ static void shellInt32( ** using "..." with internal double-quote characters doubled. */ static void shellIdQuote( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const char *zName = (const char*)sqlite3_value_text(argv[0]); @@ -5109,8 +5120,8 @@ static void shellIdQuote( ** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X. */ static void shellUSleepFunc( - sqlite3_context *context, - int argcUnused, + sqlite3_context *context, + int argcUnused, sqlite3_value **argv ){ int sleep = sqlite3_value_int(argv[0]); @@ -5122,7 +5133,7 @@ static void shellUSleepFunc( /* ** Scalar function "shell_escape_crnl" used by the .recover command. ** The argument passed to this function is the output of built-in -** function quote(). If the first character of the input is "'", +** function quote(). If the first character of the input is "'", ** indicating that the value passed to quote() was a text value, ** then this function searches the input for "\n" and "\r" characters ** and adds a wrapper similar to the following: @@ -5133,8 +5144,8 @@ static void shellUSleepFunc( ** of the input is returned. */ static void shellEscapeCrnl( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const char *zText = (const char*)sqlite3_value_text(argv[0]); @@ -5234,13 +5245,13 @@ static void open_db(ShellState *p, int openFlags){ if( zDbFilename==0 || zDbFilename[0]==0 ){ p->openMode = SHELL_OPEN_NORMAL; }else{ - p->openMode = (u8)deduceDatabaseType(zDbFilename, + p->openMode = (u8)deduceDatabaseType(zDbFilename, (openFlags & OPEN_DB_ZIPFILE)!=0); } } switch( p->openMode ){ case SHELL_OPEN_APPENDVFS: { - sqlite3_open_v2(zDbFilename, &p->db, + sqlite3_open_v2(zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); break; } @@ -5282,6 +5293,8 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_shathree_init(p->db, 0, 0); sqlite3_uint_init(p->db, 0, 0); sqlite3_decimal_init(p->db, 0, 0); + sqlite3_base64_init(p->db, 0, 0); + sqlite3_base85_init(p->db, 0, 0); sqlite3_regexp_init(p->db, 0, 0); sqlite3_ieee_init(p->db, 0, 0); sqlite3_series_init(p->db, 0, 0); @@ -5393,7 +5406,7 @@ void close_db(sqlite3 *db){ if( rc ){ utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); - } + } } #if HAVE_READLINE || HAVE_EDITLINE @@ -6636,16 +6649,16 @@ static int lintDotCommand( #if !defined SQLITE_OMIT_VIRTUALTABLE static void shellPrepare( - sqlite3 *db, - int *pRc, - const char *zSql, + sqlite3 *db, + int *pRc, + const char *zSql, sqlite3_stmt **ppStmt ){ *ppStmt = 0; if( *pRc==SQLITE_OK ){ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); if( rc!=SQLITE_OK ){ - raw_printf(stderr, "sql error: %s (%d)\n", + raw_printf(stderr, "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db) ); *pRc = rc; @@ -6661,10 +6674,10 @@ static void shellPrepare( ** nuisance compiler warnings about "defined but not used". */ void shellPreparePrintf( - sqlite3 *db, - int *pRc, + sqlite3 *db, + int *pRc, sqlite3_stmt **ppStmt, - const char *zFmt, + const char *zFmt, ... ){ *ppStmt = 0; @@ -6690,7 +6703,7 @@ void shellPreparePrintf( ** nuisance compiler warnings about "defined but not used". */ void shellFinalize( - int *pRc, + int *pRc, sqlite3_stmt *pStmt ){ if( pStmt ){ @@ -6712,7 +6725,7 @@ void shellFinalize( ** nuisance compiler warnings about "defined but not used". */ void shellReset( - int *pRc, + int *pRc, sqlite3_stmt *pStmt ){ int rc = sqlite3_reset(pStmt); @@ -6760,7 +6773,7 @@ static int arUsage(FILE *f){ } /* -** Print an error message for the .ar command to stderr and return +** Print an error message for the .ar command to stderr and return ** SQLITE_ERROR. */ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ @@ -6841,7 +6854,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ /* ** Parse the command line for an ".ar" command. The results are written into ** structure (*pAr). SQLITE_OK is returned if the command line is parsed -** successfully, otherwise an error message is written to stderr and +** successfully, otherwise an error message is written to stderr and ** SQLITE_ERROR returned. */ static int arParseCommand( @@ -7037,7 +7050,7 @@ static int arCheckEntries(ArCommand *pAr){ ** when pAr->bGlob is false and GLOB match when pAr->bGlob is true. */ static void arWhereClause( - int *pRc, + int *pRc, ArCommand *pAr, char **pzWhere /* OUT: New WHERE clause */ ){ @@ -7052,7 +7065,7 @@ static void arWhereClause( for(i=0; inArg; i++){ const char *z = pAr->azArg[i]; zWhere = sqlite3_mprintf( - "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'", + "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'", zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z ); if( zWhere==0 ){ @@ -7067,10 +7080,10 @@ static void arWhereClause( } /* -** Implementation of .ar "lisT" command. +** Implementation of .ar "lisT" command. */ static int arListCommand(ArCommand *pAr){ - const char *zSql = "SELECT %s FROM %s WHERE %s"; + const char *zSql = "SELECT %s FROM %s WHERE %s"; const char *azCols[] = { "name", "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" @@ -7092,7 +7105,7 @@ static int arListCommand(ArCommand *pAr){ if( pAr->bVerbose ){ utf8_printf(pAr->p->out, "%s % 10d %s %s\n", sqlite3_column_text(pSql, 0), - sqlite3_column_int(pSql, 1), + sqlite3_column_int(pSql, 1), sqlite3_column_text(pSql, 2), sqlite3_column_text(pSql, 3) ); @@ -7149,17 +7162,17 @@ static int arRemoveCommand(ArCommand *pAr){ } /* -** Implementation of .ar "eXtract" command. +** Implementation of .ar "eXtract" command. */ static int arExtractCommand(ArCommand *pAr){ - const char *zSql1 = + const char *zSql1 = "SELECT " " ($dir || name)," " writefile(($dir || name), %s, mode, mtime) " "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" " AND name NOT GLOB '*..[/\\]*'"; - const char *azExtraArg[] = { + const char *azExtraArg[] = { "sqlar_uncompress(data, sz)", "data" }; @@ -7185,7 +7198,7 @@ static int arExtractCommand(ArCommand *pAr){ if( zDir==0 ) rc = SQLITE_NOMEM; } - shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, + shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere ); @@ -7263,7 +7276,7 @@ static int arCreateOrUpdateCommand( int bUpdate, /* true for a --create. */ int bOnlyIfChanged /* Only update if file has changed */ ){ - const char *zCreate = + const char *zCreate = "CREATE TABLE IF NOT EXISTS sqlar(\n" " name TEXT PRIMARY KEY, -- name of the file\n" " mode INT, -- access permissions\n" @@ -7305,7 +7318,7 @@ static int arCreateOrUpdateCommand( arExecSql(pAr, "PRAGMA page_size=512"); rc = arExecSql(pAr, "SAVEPOINT ar;"); if( rc!=SQLITE_OK ) return rc; - zTemp[0] = 0; + zTemp[0] = 0; if( pAr->bZip ){ /* Initialize the zipfile virtual table, if necessary */ if( pAr->zFile ){ @@ -7399,7 +7412,7 @@ static int arDotCommand( }else if( cmd.zFile ){ int flags; if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS; - if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT + if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){ flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; }else{ @@ -7410,10 +7423,10 @@ static int arDotCommand( utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile, eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); } - rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, + rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "cannot open file: %s (%s)\n", + utf8_printf(stderr, "cannot open file: %s (%s)\n", cmd.zFile, sqlite3_errmsg(cmd.db) ); goto end_ar_command; @@ -7529,7 +7542,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ bRowids = 0; } else{ - utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); + utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); showHelp(pState->out, azArg[0]); return 1; } @@ -7892,7 +7905,7 @@ static int do_meta_command(char *zLine, ShellState *p){ return 1; } if( zDb==0 ) zDb = "main"; - rc = sqlite3_open_v2(zDestFile, &pDest, + rc = sqlite3_open_v2(zDestFile, &pDest, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); if( rc!=SQLITE_OK ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile); @@ -8142,7 +8155,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg>1 && ii==ArraySize(aDbConfig) ){ utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]); utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n"); - } + } }else #if SQLITE_SHELL_HAVE_RECOVER @@ -8209,7 +8222,7 @@ static int do_meta_command(char *zLine, ShellState *p){ " substr(o.name, 1, length(name)+1) == (name||'_')" ")", azArg[i], azArg[i] ); - + if( zLike ){ zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr); }else{ @@ -8342,7 +8355,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ if( p->bSafeMode ){ - raw_printf(stderr, + raw_printf(stderr, "Cannot run experimental commands such as \"%s\" in safe mode\n", azArg[0]); rc = 1; @@ -8361,7 +8374,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } aCtrl[] = { { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, - { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, + { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ @@ -8382,7 +8395,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); zCmd = nArg>=2 ? azArg[1] : "help"; - if( zCmd[0]=='-' + if( zCmd[0]=='-' && (cli_strcmp(zCmd,"--schema")==0 || cli_strcmp(zCmd,"-schema")==0) && nArg>=4 ){ @@ -9760,7 +9773,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( zName==0 ){ zName = azArg[ii]; }else{ - raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n"); + raw_printf(stderr, + "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } @@ -9876,7 +9890,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace", n)==0) || (c=='t' && n==9 && cli_strncmp(azArg[0], "treetrace", n)==0) ){ - unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else @@ -10061,7 +10075,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ - raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); + raw_printf(stderr, + "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); goto meta_command_exit; } pSession = &pAuxDb->aSession[pAuxDb->nSession]; @@ -10622,28 +10637,28 @@ static int do_meta_command(char *zLine, ShellState *p){ int unSafe; /* Not valid for --safe mode */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, - { "assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, - /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ - /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ - { "byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, - { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, - /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ - { "imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, - { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, - { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, - { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" }, + {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, + {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, + /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ + /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ + {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, + {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, + /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ + {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, + {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, + {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, + {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" }, + {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" }, #ifdef YYCOVERAGE - { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" }, + {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" }, #endif - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, - { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, - { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, - { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, - { "tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, + {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " }, + {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, + {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, + {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, + {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, + {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, + {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, }; int testctrl = -1; int iCtrl = -1; @@ -11068,7 +11083,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='w' && cli_strncmp(azArg[0], "wheretrace", n)==0 ){ - unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); }else @@ -11296,9 +11311,9 @@ static void echo_group_input(ShellState *p, const char *zDo){ #ifdef SQLITE_SHELL_FIDDLE /* -** Alternate one_input_line() impl for wasm mode. This is not in the primary impl -** because we need the global shellState and cannot access it from that function -** without moving lots of code around (creating a larger/messier diff). +** Alternate one_input_line() impl for wasm mode. This is not in the primary +** impl because we need the global shellState and cannot access it from that +** function without moving lots of code around (creating a larger/messier diff). */ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ /* Parse the next line from shellState.wasm.zInput. */ @@ -12117,12 +12132,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ data.openFlags |= SQLITE_OPEN_NOFOLLOW; }else if( cli_strcmp(z,"-ascii")==0 ){ data.mode = MODE_Ascii; - sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit); - sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record); + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); }else if( cli_strcmp(z,"-tabs")==0 ){ data.mode = MODE_List; - sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab); - sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row); + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab); + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row); }else if( cli_strcmp(z,"-separator")==0 ){ sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, "%s",cmdline_option_value(argc,argv,++i)); diff --git a/test/shell1.test b/test/shell1.test index 26426535b7..fbbda0348d 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -1257,4 +1257,16 @@ select 2,1; select 3,4; 2,1 3,4}} +#---------------------------------------------------------------------------- +# Test cases shell1-10.*: Test that certain static extensions are there. +# +do_test shell1-10.1 { + catchcmd :memory: { +.mode list +.header off +select base64(base64(cast('digity-doo' as blob))), + base85(base85(cast('digity-doo' as blob))); +} +} {0 digity-doo|digity-doo} + finish_test diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 35b4800719..4f16a772e3 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -55,7 +55,7 @@ while {1} { fconfigure $in2 -translation binary while {![eof $in2]} { set lx [omit_redundant_typedefs [gets $in2]] - if {[regexp {^#include "sqlite} $lx]} { + if {[regexp {^# *include "sqlite} $lx]} { set lx "/* $lx */" } if {[regexp {^# *include "test_windirent.h"} $lx]} { From 19d14f9717f0289a630f23c4b10e7ac2604bea4d Mon Sep 17 00:00:00 2001 From: larrybr Date: Fri, 23 Dec 2022 19:11:57 +0000 Subject: [PATCH 017/165] Add base64() and base85() to shell sources for the non-configured makefiles, too. FossilOrigin-Name: ac136925a6453d3e53c7a380911dfeac5706d49f936294289f6ea0b74e26e18a --- Makefile.msc | 2 ++ main.mk | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 0312b0dbaf..acf9b7d589 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2232,6 +2232,8 @@ SHELL_SRC = \ $(TOP)\src\shell.c.in \ $(TOP)\ext\misc\appendvfs.c \ $(TOP)\ext\misc\completion.c \ + $(TOP)\ext\misc\base64.c \ + $(TOP)\ext\misc\base85.c \ $(TOP)\ext\misc\decimal.c \ $(TOP)\ext\misc\fileio.c \ $(TOP)\ext\misc\ieee754.c \ diff --git a/main.mk b/main.mk index ccd5b6f5b0..2b80b55aee 100644 --- a/main.mk +++ b/main.mk @@ -758,6 +758,8 @@ SHELL_SRC = \ $(TOP)/src/shell.c.in \ $(TOP)/ext/misc/appendvfs.c \ $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ $(TOP)/ext/misc/decimal.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/ieee754.c \ diff --git a/manifest b/manifest index 756fdd39c9..739632e034 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Add\sbase64()\sand\sbase85()\stext/blob\sconversions\sto\sthe\sCLI. -D 2022-12-23T19:04:59.875 +C Add\sbase64()\sand\sbase85()\sto\sshell\ssources\sfor\sthe\snon-configured\smakefiles,\stoo. +D 2022-12-23T19:11:57.957 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 341f02570d220695100004c447773ecb6c082e24178fc45dcbc0a212abaa0655 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc e86ec21328921721dd6f777da435c62a5469cda1a654f5ecefacf87ddb3dfeb3 +F Makefile.msc 5a13f784bd91c246673648f056e7f3193c45d53dff874eecde547ec854c292b8 F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e F VERSION 413ec94920a487ae32c9a2a8819544d690662d6f7c7ce025c0d0b8a1e74fa9db F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -564,7 +564,7 @@ F ext/wasm/wasmfs.make cf9a68162d92ca2bcb0b9528b244cb36d5cc2d84ccc9c2d398461927d F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 5ce166d63fb99df9821f262fb1777fd5eb7b6c9396e867a6b0b2761f35f8238a +F main.mk ed4950f3e1d03687e6c94c0f9aa26373ddab628030480d1e298097cfe0b9a5cf F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5d9a14715c25efcd81cadafabf03aad7213251bd1b3dc181939c2dba8d942fb6 -R f473ce0dc90c010b804e2b9eefdd163f +P 4bc98a2d9520efa9b80142163cbfab72a5f2fe9854cd6ba8291dcefdb872e657 +R 29c37bd5c082a5ba7585171eea4f1caa U larrybr -Z 3ee7c528f374ab6814608dd44133cc19 +Z 2e2497f2640ef121f1aa2ea0415c2016 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 936b19aef9..cf3a045e73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4bc98a2d9520efa9b80142163cbfab72a5f2fe9854cd6ba8291dcefdb872e657 \ No newline at end of file +ac136925a6453d3e53c7a380911dfeac5706d49f936294289f6ea0b74e26e18a \ No newline at end of file From 3705f38ab0a22187fd019e431c280cb82eca1165 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 19:16:45 +0000 Subject: [PATCH 018/165] Consolidate/unify how the JS bindings of the create_function/collation family of functions react to a non-UTF8 encoding: they now treat a falsy value as SQLITE_UTF8 and fail with SQLITE_FORMAT for an invalid encoding. FossilOrigin-Name: deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb --- ext/wasm/api/sqlite3-api-glue.js | 29 ++++++++++++++++++++++++----- ext/wasm/tester1.c-pp.js | 15 ++++++++++++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 59b40786ec..f1f93da73e 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -460,6 +460,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ (1===n?"":'s')+"."); }; + /** Code duplication reducer for functions which take an encoding + argument and require SQLITE_UTF8. Sets the db error code to + SQLITE_FORMAT and returns that code. */ + const __errEncoding = (pDb)=>{ + return util.sqlite3_wasm_db_error( + pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding." + ); + }; + if(1){/* Bindings for sqlite3_create_collation() */ const __collationContextKey = (argIndex,argv)=>{ @@ -495,7 +504,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ them. 2) It returns capi.SQLITE_FORMAT if the 3rd argument is not - capi.SQLITE_UTF8. No other encodings are supported. + capi.SQLITE_UTF8. No other encodings are supported. To simplify + usage, any falsy value of eTextRep is treated as SQLITE_UTF8. Returns 0 on success, non-0 on error, in which case the error state of pDb (of type `sqlite3*` or argument-convertible to it) @@ -503,10 +513,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ capi.sqlite3_create_collation_v2 = function(pDb,zName,eTextRep,pArg,xCompare,xDestroy){ if(6!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_create_collation_v2', 6); - else if(capi.SQLITE_UTF8!==eTextRep){ - return util.sqlite3_wasm_db_error( - pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding." - ); + else if(!eTextRep){ + eTextRep = capi.SQLITE_UTF8; + }else if(capi.SQLITE_UTF8!==eTextRep){ + return __errEncoding(pDb); } let rc, pfCompare, pfDestroy; try{ @@ -580,6 +590,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "int"/*eTextRep*/, "*"/*pApp*/, "*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, "*"/*xDestroy*/] ); + // TODO: reimplement these using FuncPtrAdapter. const sqlite3CreateWindowFunction = wasm.xWrap( "sqlite3_create_window_function", "int", ["sqlite3*", "string"/*funcName*/, "int"/*nArg*/, @@ -657,6 +668,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ){ if(f.length!==arguments.length){ return __dbArgcMismatch(pDb,"sqlite3_create_function_v2",f.length); + }else if(!eTextRep){ + eTextRep = capi.SQLITE_UTF8; + }else if(capi.SQLITE_UTF8!==eTextRep){ + return __errEncoding(pDb); } /* Wrap the callbacks in a WASM-bound functions... */ const uninstall = [/*funcs to uninstall on error*/]; @@ -698,6 +713,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ){ if(f.length!==arguments.length){ return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length); + }else if(!eTextRep){ + eTextRep = capi.SQLITE_UTF8; + }else if(capi.SQLITE_UTF8!==eTextRep){ + return __errEncoding(pDb); } /* Wrap the callbacks in a WASM-bound functions... */ const uninstall = [/*funcs to uninstall on error*/]; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index eb014d7b51..a285f8d4f5 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1650,6 +1650,19 @@ self.sqlite3InitModule = sqlite3InitModule; assert(2 === blobRc.length); //debug("blobRc=",blobRc); T.assert(0x68==blobRc[0] && 0x69==blobRc[1]); + + let rc = sqlite3.capi.sqlite3_create_function_v2( + this.db, "foo", 0, -1, 0, 0, 0, 0, 0 + ); + T.assert( + sqlite3.capi.SQLITE_FORMAT === rc, + "For invalid eTextRep argument." + ); + rc = sqlite3.capi.sqlite3_create_function_v2(this.db, "foo", 0); + T.assert( + sqlite3.capi.SQLITE_MISUSE === rc, + "For invalid arg count." + ); } }) @@ -2333,7 +2346,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(0===rc).assert(3===collationCounter); rc = capi.sqlite3_create_collation(this.db,"hi",capi.SQLITE_UTF8/*not enough args*/); T.assert(capi.SQLITE_MISUSE === rc); - rc = capi.sqlite3_create_collation_v2(this.db,"hi",0/*wrong encoding*/,0,0,0); + rc = capi.sqlite3_create_collation_v2(this.db,"hi",capi.SQLITE_UTF8+1/*invalid encoding*/,0,0,0); T.assert(capi.SQLITE_FORMAT === rc) .mustThrowMatching(()=>this.db.checkRc(rc), /SQLITE_UTF8 is the only supported encoding./); diff --git a/manifest b/manifest index 739632e034..b197045b1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sbase64()\sand\sbase85()\sto\sshell\ssources\sfor\sthe\snon-configured\smakefiles,\stoo. -D 2022-12-23T19:11:57.957 +C Consolidate/unify\show\sthe\sJS\sbindings\sof\sthe\screate_function/collation\sfamily\sof\sfunctions\sreact\sto\sa\snon-UTF8\sencoding:\sthey\snow\streat\sa\sfalsy\svalue\sas\sSQLITE_UTF8\sand\sfail\swith\sSQLITE_FORMAT\sfor\san\sinvalid\sencoding. +D 2022-12-23T19:16:45.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 63daa4b9c36faa4c338a32a06eb142869b9ae4885a3e01aad473e1b45357089f +F ext/wasm/api/sqlite3-api-glue.js 72e63574caaf94aca36b40fa18bd76a267dd43ac6e7b5bd7293bc33ecb52230d F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 4202e7ec525445386f29612ddf1365348edd1f6002b8b21721c954b9569b756a +F ext/wasm/tester1.c-pp.js 10db3bd0415d3b39a75db3bfdef2dbabcad8d1168148708bc7f1718b6f36cefd F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4bc98a2d9520efa9b80142163cbfab72a5f2fe9854cd6ba8291dcefdb872e657 -R 29c37bd5c082a5ba7585171eea4f1caa -U larrybr -Z 2e2497f2640ef121f1aa2ea0415c2016 +P ac136925a6453d3e53c7a380911dfeac5706d49f936294289f6ea0b74e26e18a +R 9d755119137074f847904c767813a68a +U stephan +Z b32b2adc949da16fb78be22c10d5b0a1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cf3a045e73..91be7497c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac136925a6453d3e53c7a380911dfeac5706d49f936294289f6ea0b74e26e18a \ No newline at end of file +deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb \ No newline at end of file From ab9c2d571e5927060c65d7bfd3132348f6240159 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 21:10:49 +0000 Subject: [PATCH 019/165] Internal JS cleanups. Correct part of [ac136925a645] to account for the eTextRep flag being able to hold flags other than the encoding. FossilOrigin-Name: 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f --- ext/wasm/api/sqlite3-api-glue.js | 103 +++++++++++++++------------ ext/wasm/api/sqlite3-api-oo1.js | 31 +++----- ext/wasm/api/sqlite3-api-prologue.js | 8 ++- ext/wasm/common/whwasmutil.js | 5 +- ext/wasm/tester1.c-pp.js | 2 +- manifest | 20 +++--- manifest.uuid | 2 +- 7 files changed, 90 insertions(+), 81 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index f1f93da73e..a760e921fe 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -53,7 +53,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"], ["sqlite3_bind_pointer", "int", "sqlite3_stmt*", "int", "*", "string:static", "*"], - ["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "int" + ["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "*" /* We should arguably create a hand-written binding of bind_text() which does more flexible text conversion, along the lines of sqlite3_prepare_v3(). The slightly problematic @@ -292,9 +292,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ {/* Convert Arrays and certain TypedArrays to strings for 'string:flexible'-type arguments */ - const xString = wasm.xWrap.argAdapter('string'); + const __xString = wasm.xWrap.argAdapter('string'); wasm.xWrap.argAdapter( - 'string:flexible', (v)=>xString(util.flexibleString(v)) + 'string:flexible', (v)=>__xString(util.flexibleString(v)) ); /** @@ -324,12 +324,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(wasm.isPtr(v)) return v; v = ''+v; let rc = this[v]; - return rc || (rc = this[v] = wasm.allocCString(v)); + return rc || (this[v] = wasm.allocCString(v)); }.bind(Object.create(null)) ); }/* special-case string-type argument conversions */ - - if(1){// WhWasmUtil.xWrap() bindings... + + if(1){// wasm.xWrap() bindings... /** Add some descriptive xWrap() aliases for '*' intended to (A) initially improve readability/correctness of capi.signatures @@ -369,19 +369,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ VFS in many contexts. We specifically do not want that behavior here. */ return capi.sqlite3_vfs_find(v) - || sqlite3.SQLite3Error.toss("Unknown sqlite3_vfs name:",v); + || sqlite3.SQLite3Error.toss( + capi.SQLITE_NOTFOUND, + "Unknown sqlite3_vfs name:", v + ); } return aPtr((v instanceof (capi.sqlite3_vfs || nilType)) ? v.pointer : v); }); - const rPtr = wasm.xWrap.resultAdapter('*'); - wasm.xWrap.resultAdapter('sqlite3*', rPtr) - ('sqlite3_context*', rPtr) - ('sqlite3_stmt*', rPtr) - ('sqlite3_value*', rPtr) - ('sqlite3_vfs*', rPtr) - ('void*', rPtr); + const __xRcPtr = wasm.xWrap.resultAdapter('*'); + wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr) + ('sqlite3_context*', __xRcPtr) + ('sqlite3_stmt*', __xRcPtr) + ('sqlite3_value*', __xRcPtr) + ('sqlite3_vfs*', __xRcPtr) + ('void*', __xRcPtr); /** Populate api object with sqlite3_...() by binding the "raw" wasm @@ -395,10 +398,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } /* For C API functions which cannot work properly unless - wasm.bigIntEnabled is true, install a bogus impl which - throws if called when bigIntEnabled is false. */ + wasm.bigIntEnabled is true, install a bogus impl which throws + if called when bigIntEnabled is false. The alternative would be + to elide these functions altogether, which seems likely to + cause more confusion. */ const fI64Disabled = function(fname){ - return ()=>toss(fname+"() disabled due to lack", + return ()=>toss(fname+"() is unavailable due to lack", "of BigInt support in this build."); }; for(const e of wasm.bindingSignatures.int64){ @@ -421,7 +426,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - (sqlite3*, int code, string msg) - (sqlite3*, Error e [,string msg = ''+e]) - If passed a WasmAllocError, the message is ingored and the + If passed a WasmAllocError, the message is ignored and the result code is SQLITE_NOMEM. If passed any other Error type, the result code defaults to SQLITE_ERROR unless the Error object has a resultCode property, in which case that is used @@ -469,8 +474,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); }; - if(1){/* Bindings for sqlite3_create_collation() */ - + if(1){/* Bindings for sqlite3_create_collation[_v2]() */ const __collationContextKey = (argIndex,argv)=>{ return 'argv['+argIndex+']:sqlite3@'+argv[0]+ ':'+wasm.cstrToJs(argv[1]).toLowerCase() @@ -497,15 +501,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Works exactly like C's sqlite3_create_collation_v2() except that: - 1) It accepts JS functions for its function-pointer arguments, + 1) It returns capi.SQLITE_FORMAT if the 3rd argument contains + any encoding-related value other than capi.SQLITE_UTF8. No + other encodings are supported. As a special case, if the + bottom 4 bits of that argument are 0, SQLITE_UTF8 is + assumed. + + 2) It accepts JS functions for its function-pointer arguments, for which it will install WASM-bound proxies. The bindings are "permanent," in that they will stay in the WASM environment - until it shuts down unless the client somehow finds and removes - them. + until it shuts down unless the client calls this again with the + same collation name and a value of 0 or null for the + the function pointer(s). - 2) It returns capi.SQLITE_FORMAT if the 3rd argument is not - capi.SQLITE_UTF8. No other encodings are supported. To simplify - usage, any falsy value of eTextRep is treated as SQLITE_UTF8. + For consistency with the C API, it requires the same number of + arguments. It returns capi.SQLITE_MISUSE if passed any other + argument count. Returns 0 on success, non-0 on error, in which case the error state of pDb (of type `sqlite3*` or argument-convertible to it) @@ -513,9 +524,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ capi.sqlite3_create_collation_v2 = function(pDb,zName,eTextRep,pArg,xCompare,xDestroy){ if(6!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_create_collation_v2', 6); - else if(!eTextRep){ - eTextRep = capi.SQLITE_UTF8; - }else if(capi.SQLITE_UTF8!==eTextRep){ + else if( 0 === (eTextRep & 0xf) ){ + eTextRep |= capi.SQLITE_UTF8; + }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } let rc, pfCompare, pfDestroy; @@ -584,13 +595,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(1){/* Special-case handling of sqlite3_create_function_v2() and sqlite3_create_window_function() */ + /* Maintenance reminder: FuncPtrAdapter is not expressive enough + to be able to perform these mappings. */ const sqlite3CreateFunction = wasm.xWrap( "sqlite3_create_function_v2", "int", ["sqlite3*", "string"/*funcName*/, "int"/*nArg*/, "int"/*eTextRep*/, "*"/*pApp*/, "*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, "*"/*xDestroy*/] ); - // TODO: reimplement these using FuncPtrAdapter. + const sqlite3CreateWindowFunction = wasm.xWrap( "sqlite3_create_window_function", "int", ["sqlite3*", "string"/*funcName*/, "int"/*nArg*/, @@ -643,13 +656,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ xDestroy: {sig:'v(p)', f:__xDestroy} }); - const __xWrapFuncs = function(theFuncs, tgtUninst){ + /* Internal helper for sqlite3_create_function() and friends. */ + const __xWrapFuncs = function(theKeys, theFuncs, tgtUninst){ const rc = [] - let k; - for(k in theFuncs){ + for(const k of theKeys){ let fArg = theFuncs[k]; if('function'===typeof fArg){ - const w = __xMap[k]; + const w = __xMap[k] || toss3("Internal error in __xWrapFuncs: invalid key:",k); fArg = wasm.installFunction(w.sig, w.f(fArg)); tgtUninst.push(fArg); } @@ -666,18 +679,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ xFinal, //void (*xFinal)(sqlite3_context*) xDestroy //void (*xDestroy)(void*) ){ - if(f.length!==arguments.length){ + if( f.length!==arguments.length ){ return __dbArgcMismatch(pDb,"sqlite3_create_function_v2",f.length); - }else if(!eTextRep){ - eTextRep = capi.SQLITE_UTF8; - }else if(capi.SQLITE_UTF8!==eTextRep){ + }else if( 0 === (eTextRep & 0xf) ){ + eTextRep |= capi.SQLITE_UTF8; + }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } /* Wrap the callbacks in a WASM-bound functions... */ const uninstall = [/*funcs to uninstall on error*/]; let rc; try{ - const funcArgs = __xWrapFuncs({xFunc, xStep, xFinal, xDestroy}, + const funcArgs = __xWrapFuncs(['xFunc','xStep','xFinal','xDestroy'], + {xFunc, xStep, xFinal, xDestroy}, uninstall); rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep, pApp, ...funcArgs); @@ -711,18 +725,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ xInverse,//void (*xStep)(sqlite3_context*,int,sqlite3_value**) xDestroy //void (*xDestroy)(void*) ){ - if(f.length!==arguments.length){ + if( f.length!==arguments.length ){ return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length); - }else if(!eTextRep){ - eTextRep = capi.SQLITE_UTF8; - }else if(capi.SQLITE_UTF8!==eTextRep){ + }else if( 0 === (eTextRep & 0xf) ){ + eTextRep |= capi.SQLITE_UTF8; + }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } /* Wrap the callbacks in a WASM-bound functions... */ const uninstall = [/*funcs to uninstall on error*/]; let rc; try{ - const funcArgs = __xWrapFuncs({xStep, xFinal, xValue, xInverse, xDestroy}, + const funcArgs = __xWrapFuncs(['xStep','xFinal','xValue','xInverse','xDestroy'], + {xStep, xFinal, xValue, xInverse, xDestroy}, uninstall); rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep, pApp, ...funcArgs); diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 59ecf56b96..1776cb327e 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1277,28 +1277,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ so we have no range checking. */ f._ = { string: function(stmt, ndx, val, asBlob){ - if(1){ - /* _Hypothetically_ more efficient than the impl in the 'else' block. */ - const stack = wasm.scopedAllocPush(); - try{ - const n = wasm.jstrlen(val); - const pStr = wasm.scopedAlloc(n); - wasm.jstrcpy(val, wasm.heap8u(), pStr, n, false); - const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text; - return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT); - }finally{ - wasm.scopedAllocPop(stack); - } - }else{ - const bytes = wasm.jstrToUintArray(val,false); - const pStr = wasm.alloc(bytes.length || 1); - wasm.heap8u().set(bytes.length ? bytes : [0], pStr); - try{ - const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text; - return f(stmt.pointer, ndx, pStr, bytes.length, capi.SQLITE_TRANSIENT); - }finally{ - wasm.dealloc(pStr); - } + const stack = wasm.scopedAllocPush(); + try{ + const [pStr, n] = wasm.scopedAllocCString(val, true); + const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text; + return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT); + }finally{ + wasm.scopedAllocPop(stack); } } }; @@ -1354,7 +1339,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const pBlob = wasm.scopedAlloc(val.byteLength || 1); wasm.heap8().set(val.byteLength ? val : [0], pBlob) rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, - capi.SQLITE_TRANSIENT); + capi.SQLITE_TRANSIENT); }finally{ wasm.scopedAllocPop(stack); } diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 94514e4770..6c50e99b0a 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -425,7 +425,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( any encoding other than sqlite3.SQLITE_UTF8. The JS API does not currently support any other encoding and likely never will. This function does not replace that argument on its own - because it may contain other flags. + because it may contain other flags. As a special case, if + the bottom 4 bits of that argument are 0, SQLITE_UTF8 is + assumed. 2) Any of the four final arguments may be either WASM pointers (assumed to be function pointers) or JS Functions. In the @@ -433,6 +435,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( sqlite3.capi.wasm.installFunction() and that wrapper is passed on to the native implementation. + For consistency with the C API, it requires the same number of + arguments. It returns capi.SQLITE_MISUSE if passed any other + argument count. + The semantics of JS functions are: xFunc: is passed `(pCtx, ...values)`. Its return value becomes diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index ecd08327f4..880ef4ab4e 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -2026,9 +2026,12 @@ self.WhWasmUtilInstaller = function(target){ It throws if no adapter is found. ACHTUNG: the adapter may require that a scopedAllocPush() is - active and it may allocate memory within that scope. + active and it may allocate memory within that scope. It may also + require additional arguments, depending on the type of + conversion. */ target.xWrap.testConvertArg = cache.xWrap.convertArg; + /** This function is ONLY exposed in the public API to facilitate testing. It should not be used in application-level code, only diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index a285f8d4f5..5411c064ce 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -2557,7 +2557,7 @@ self.sqlite3InitModule = sqlite3InitModule; capi.sqlite3_js_vfs_create_file( "no-such-vfs", filename, ba ); - }, "Unknown sqlite3_vfs name: no-such-vfs"); + }, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs"); }finally{ if(sh) await sh.close(); unlink(); diff --git a/manifest b/manifest index b197045b1a..0476b9eced 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Consolidate/unify\show\sthe\sJS\sbindings\sof\sthe\screate_function/collation\sfamily\sof\sfunctions\sreact\sto\sa\snon-UTF8\sencoding:\sthey\snow\streat\sa\sfalsy\svalue\sas\sSQLITE_UTF8\sand\sfail\swith\sSQLITE_FORMAT\sfor\san\sinvalid\sencoding. -D 2022-12-23T19:16:45.370 +C Internal\sJS\scleanups.\sCorrect\spart\sof\s[ac136925a645]\sto\saccount\sfor\sthe\seTextRep\sflag\sbeing\sable\sto\shold\sflags\sother\sthan\sthe\sencoding. +D 2022-12-23T21:10:49.493 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 72e63574caaf94aca36b40fa18bd76a267dd43ac6e7b5bd7293bc33ecb52230d -F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6 -F ext/wasm/api/sqlite3-api-prologue.js 1767dfcd94bb4fa9dd4bd9ff6327117783d3656faf1058dcc1369db320d871fc +F ext/wasm/api/sqlite3-api-glue.js f50211dc11f1debf972cdaea87cb4df9772022828072e7100cf5025d1dca2a78 +F ext/wasm/api/sqlite3-api-oo1.js 4cce9671e8a31ac9b76bd8559e7827ccc2b121734e460fa9c7d243735a771ec8 +F ext/wasm/api/sqlite3-api-prologue.js 789639d256e3134563c5c9be25ade28b40e06e783885d26cccc01cd1ed4b820d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js ff43d28d04e60068ecb3e9a2550581f36be5867ad5ffc00d8479580a12cf9b0f +F ext/wasm/common/whwasmutil.js 97807770ec452fdcaa48509c5decd3a2c1e3001164a62a3223a347f66967533e F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 10db3bd0415d3b39a75db3bfdef2dbabcad8d1168148708bc7f1718b6f36cefd +F ext/wasm/tester1.c-pp.js 50b51af2b5466de0cba8ebc97b86bc886c32f937d8f4b36d3b3936ef9748e534 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ac136925a6453d3e53c7a380911dfeac5706d49f936294289f6ea0b74e26e18a -R 9d755119137074f847904c767813a68a +P deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb +R 537077e8e7a576993086a957d5c52d05 U stephan -Z b32b2adc949da16fb78be22c10d5b0a1 +Z 379d99233453fc912eb71dcbaf16b8ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 91be7497c9..a091b64a43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb \ No newline at end of file +1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f \ No newline at end of file From 027afccdcd6e9077b7043545a3f8bd32cfb5a397 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 23 Dec 2022 23:46:33 +0000 Subject: [PATCH 020/165] Reimplement JS's sqlite3_bind_text/blob() with hand-written bindings to permit more flexible inputs. Add automated JS-to-C function conversion to sqlite3_busy_handler(). sqlite3.wasm.xWrap()'s '*' argument conversion no longer treats JS strings as C-strings: those conversions require explicit opt-in via the 'string' converter (or equivalent). FossilOrigin-Name: 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6 --- ext/wasm/api/sqlite3-api-glue.js | 153 ++++++++++++++++++++------- ext/wasm/api/sqlite3-api-oo1.js | 11 +- ext/wasm/api/sqlite3-api-prologue.js | 100 +++++++++++++++-- ext/wasm/common/whwasmutil.js | 44 ++++---- manifest | 18 ++-- manifest.uuid | 2 +- 6 files changed, 240 insertions(+), 88 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index a760e921fe..dd80963f3e 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -42,10 +42,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.bindingSignatures = [ // Please keep these sorted by function name! ["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"], - ["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*" - /* TODO: we should arguably write a custom wrapper which knows - how to handle Blob, TypedArrays, and JS strings. */ - ], + /* sqlite3_bind_blob() and sqlite3_bind_text() have hand-written + bindings to permit more flexible inputs. */ ["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"], ["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"], ["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"], @@ -53,16 +51,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"], ["sqlite3_bind_pointer", "int", "sqlite3_stmt*", "int", "*", "string:static", "*"], - ["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "*" - /* We should arguably create a hand-written binding of - bind_text() which does more flexible text conversion, along - the lines of sqlite3_prepare_v3(). The slightly problematic - part is the final argument (text destructor). */ - ], - //["sqlite3_busy_handler","int", "sqlite3*", "*", "*"], - // ^^^^ TODO: custom binding which auto-converts JS function arg - // to a WASM function, noting that calling it multiple times - // would introduce a leak. + ["sqlite3_busy_handler","int", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + signature: 'i(pi)', + contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] + }), + "*" + ]], ["sqlite3_busy_timeout","int", "sqlite3*", "int"], ["sqlite3_close_v2", "int", "sqlite3*"], ["sqlite3_changes", "int", "sqlite3*"], @@ -779,6 +775,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(1){/* Special-case handling of sqlite3_prepare_v2() and sqlite3_prepare_v3() */ + /** Helper for string:flexible conversions which require a byte-length counterpart argument. Passed a value and its @@ -802,32 +799,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Scope-local holder of the two impls of sqlite3_prepare_v2/v3(). */ - const __prepare = Object.create(null); - /** - This binding expects a JS string as its 2nd argument and - null as its final argument. In order to compile multiple - statements from a single string, the "full" impl (see - below) must be used. - */ - __prepare.basic = wasm.xWrap('sqlite3_prepare_v3', - "int", ["sqlite3*", "string", - "int"/*ignored for this impl!*/, - "int", "**", - "**"/*MUST be 0 or null or undefined!*/]); - /** - Impl which requires that the 2nd argument be a pointer - to the SQL string, instead of being converted to a - string. This variant is necessary for cases where we - require a non-NULL value for the final argument - (exec()'ing multiple statements from one input - string). For simpler cases, where only the first - statement in the SQL string is required, the wrapper - named sqlite3_prepare_v2() is sufficient and easier to - use because it doesn't require dealing with pointers. - */ - __prepare.full = wasm.xWrap('sqlite3_prepare_v3', - "int", ["sqlite3*", "*", "int", "int", - "**", "**"]); + const __prepare = { + /** + This binding expects a JS string as its 2nd argument and + null as its final argument. In order to compile multiple + statements from a single string, the "full" impl (see + below) must be used. + */ + basic: wasm.xWrap('sqlite3_prepare_v3', + "int", ["sqlite3*", "string", + "int"/*ignored for this impl!*/, + "int", "**", + "**"/*MUST be 0 or null or undefined!*/]), + /** + Impl which requires that the 2nd argument be a pointer + to the SQL string, instead of being converted to a + string. This variant is necessary for cases where we + require a non-NULL value for the final argument + (exec()'ing multiple statements from one input + string). For simpler cases, where only the first + statement in the SQL string is required, the wrapper + named sqlite3_prepare_v2() is sufficient and easier to + use because it doesn't require dealing with pointers. + */ + full: wasm.xWrap('sqlite3_prepare_v3', + "int", ["sqlite3*", "*", "int", "int", + "**", "**"]) + }; /* Documented in the capi object's initializer. */ capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){ @@ -852,7 +850,80 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail) : __dbArgcMismatch(pDb,"sqlite3_prepare_v2",f.length); }; - }/*sqlite3_prepare_v2/v3()*/; + + }/*sqlite3_prepare_v2/v3()*/ + + {/*sqlite3_bind_text/blob()*/ + const __bindText = wasm.xWrap("sqlite3_bind_text", "int", [ + "sqlite3_stmt*", "int", "string", "int", "*" + ]); + const __bindBlob = wasm.xWrap("sqlite3_bind_blob", "int", [ + "sqlite3_stmt*", "int", "*", "int", "*" + ]); + + /** Documented in the capi object's initializer. */ + capi.sqlite3_bind_text = function f(pStmt, iCol, text, nText, xDestroy){ + if(f.length!==arguments.length){ + return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt), + "sqlite3_bind_text", f.length); + }else if(wasm.isPtr(text) || null===text){ + return __bindText(pStmt, iCol, text, nText, xDestroy); + }else if(text instanceof ArrayBuffer){ + text = new Uint8Array(text); + }else if(Array.isArray(pMem)){ + text = pMem.join(''); + } + let p, n; + try { + if(util.isSQLableTypedArray(text)){ + p = wasm.allocFromTypedArray(text); + n = text.byteLength; + }else if('string'===typeof text){ + [p, n] = wasm.allocCString(text); + }else{ + return util.sqlite3_wasm_db_error( + capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE, + "Invalid 3rd argument type for sqlite3_bind_text()." + ); + } + return __bindText(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT); + }finally{ + wasm.dealloc(p); + } + }/*sqlite3_bind_text()*/; + + /** Documented in the capi object's initializer. */ + capi.sqlite3_bind_blob = function f(pStmt, iCol, pMem, nMem, xDestroy){ + if(f.length!==arguments.length){ + return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt), + "sqlite3_bind_blob", f.length); + }else if(wasm.isPtr(pMem) || null===pMem){ + return __bindBlob(pStmt, iCol, pMem, nMem, xDestroy); + }else if(pMem instanceof ArrayBuffer){ + pMem = new Uint8Array(pMem); + }else if(Array.isArray(pMem)){ + pMem = pMem.join(''); + } + let p, n; + try{ + if(util.isBindableTypedArray(pMem)){ + p = wasm.allocFromTypedArray(pMem); + n = nMem>=0 ? nMem : pMem.byteLength; + }else if('string'===typeof pMem){ + [p, n] = wasm.allocCString(pMem); + }else{ + return util.sqlite3_wasm_db_error( + capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE, + "Invalid 3rd argument type for sqlite3_bind_blob()." + ); + } + return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT); + }finally{ + wasm.dealloc(p); + } + }/*sqlite3_bind_blob()*/; + + }/*sqlite3_bind_text/blob()*/ {/* sqlite3_set_authorizer() */ const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [ diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 1776cb327e..ddb346e545 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1332,8 +1332,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if(!util.isBindableTypedArray(val)){ toss3("Binding a value as a blob requires", "that it be a string, Uint8Array, or Int8Array."); - }else if(1){ - /* _Hypothetically_ more efficient than the impl in the 'else' block. */ + }else{ const stack = wasm.scopedAllocPush(); try{ const pBlob = wasm.scopedAlloc(val.byteLength || 1); @@ -1343,14 +1342,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }finally{ wasm.scopedAllocPop(stack); } - }else{ - const pBlob = wasm.allocFromTypedArray(val); - try{ - rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, - capi.SQLITE_TRANSIENT); - }finally{ - wasm.dealloc(pBlob); - } } break; } diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 6c50e99b0a..c3533a4767 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -417,6 +417,92 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( }; Object.assign(capi, { + /** + sqlite3_bind_blob() works exactly like its C counterpart unless + its 3rd argument is one of: + + - JS string: the 3rd argument is converted to a C string, the + 4th argument is ignored, and the C-string's length is used + in its place. + + - Array: converted to a string as defined for "flexible + strings" and then it's treated as a JS string. + + - Int8Array or Uint8Array: wasm.allocFromTypedArray() is used to + conver the memory to the WASM heap. If the 4th argument is + 0 or greater, it is used as-is, otherwise the array's byteLength + value is used. This is an exception to the C API's undefined + behavior for a negative 4th argument, but results are undefined + if the given 4th argument value is greater than the byteLength + of the input array. + + - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and + treated as that type. + + In all of those cases, the final argument (text destructor) is + ignored and capi.SQLITE_TRANSIENT is assumed. + + A 3rd argument of `null` is treated as if it were a WASM pointer + of 0. + + If the 3rd argument is neither a WASM pointer nor one of the + above-described types, capi.SQLITE_MISUSE is returned. + + The first argument may be either an `sqlite3_stmt*` WASM + pointer or an sqlite3.oo1.Stmt instance. + + For consistency with the C API, it requires the same number of + arguments. It returns capi.SQLITE_MISUSE if passed any other + argument count. + */ + sqlite3_bind_blob: undefined/*installed later*/, + + /** + sqlite3_bind_text() works exactly like its C counterpart unless + its 3rd argument is one of: + + - JS string: the 3rd argument is converted to a C string, the + 4th argument is ignored, and the C-string's length is used + in its place. + + - Array: converted to a string as defined for "flexible + strings". The 4th argument is ignored and a value of -1 + is assumed. + + - Int8Array or Uint8Array: is assumed to contain UTF-8 text, is + converted to a string. The 4th argument is ignored, replaced + by the array's byteLength value. + + - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and + treated as that type. + + In each of those cases, the final argument (text destructor) is + ignored and capi.SQLITE_TRANSIENT is assumed. + + A 3rd argument of `null` is treated as if it were a WASM pointer + of 0. + + If the 3rd argument is neither a WASM pointer nor one of the + above-described types, capi.SQLITE_MISUSE is returned. + + The first argument may be either an `sqlite3_stmt*` WASM + pointer or an sqlite3.oo1.Stmt instance. + + For consistency with the C API, it requires the same number of + arguments. It returns capi.SQLITE_MISUSE if passed any other + argument count. + + If client code needs to bind partial strings, it needs to + either parcel the string up before passing it in here or it + must pass in a WASM pointer for the 3rd argument and a valid + 4th-argument value, taking care not to pass a value which + truncates a multi-byte UTF-8 character. When passing + WASM-format strings, it is important that the final argument be + valid or unexpected content can result can result, or even a + crash if the application reads past the WASM heap bounds. + */ + sqlite3_bind_text: undefined/*installed later*/, + /** sqlite3_create_function_v2() differs from its native counterpart only in the following ways: @@ -525,18 +611,18 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH` flag. */ - sqlite3_create_function_v2: function( + sqlite3_create_function_v2: ( pDb, funcName, nArg, eTextRep, pApp, xFunc, xStep, xFinal, xDestroy - ){/*installed later*/}, + )=>{/*installed later*/}, /** Equivalent to passing the same arguments to sqlite3_create_function_v2(), with 0 as the final argument. */ - sqlite3_create_function:function( + sqlite3_create_function: ( pDb, funcName, nArg, eTextRep, pApp, xFunc, xStep, xFinal - ){/*installed later*/}, + )=>{/*installed later*/}, /** The sqlite3_create_window_function() JS wrapper differs from its native implementation in the exact same way that @@ -544,10 +630,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( xInverse(), is treated identically to xStep() by the wrapping layer. */ - sqlite3_create_window_function: function( + sqlite3_create_window_function: ( pDb, funcName, nArg, eTextRep, pApp, xStep, xFinal, xValue, xInverse, xDestroy - ){/*installed later*/}, + )=>{/*installed later*/}, /** The sqlite3_prepare_v3() binding handles two different uses with differing JS/WASM semantics: @@ -669,7 +755,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( toss3, typedArrayPart }; - + Object.assign(wasm, { /** Emscripten APIs have a deep-seated assumption that all pointers diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 880ef4ab4e..de7500a020 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1406,7 +1406,8 @@ self.WhWasmUtilInstaller = function(target){ .set('int', xArg.get('i32')) .set('null', (i)=>i) .set(null, xArg.get('null')) - .set('**', __xArgPtr); + .set('**', __xArgPtr) + .set('*', __xArgPtr); xResult.set('*', __xArgPtr) .set('pointer', __xArgPtr) .set('number', (v)=>Number(v)) @@ -1448,23 +1449,23 @@ self.WhWasmUtilInstaller = function(target){ if('string'===typeof v) return target.scopedAllocCString(v); return v ? __xArgPtr(v) : null; }; - xArg.set('string', __xArgString); - xArg.set('utf8', __xArgString); - xArg.set('pointer', __xArgString); - xArg.set('*', __xArgString); + xArg.set('string', __xArgString) + .set('utf8', __xArgString) + .set('pointer', __xArgString); + //xArg.set('*', __xArgString); - xResult.set('string', (i)=>target.cstrToJs(i)); - xResult.set('utf8', xResult.get('string')); - xResult.set('string:dealloc', (i)=>{ - try { return i ? target.cstrToJs(i) : null } - finally{ target.dealloc(i) } - }); - xResult.set('utf8:dealloc', xResult.get('string:dealloc')); - xResult.set('json', (i)=>JSON.parse(target.cstrToJs(i))); - xResult.set('json:dealloc', (i)=>{ - try{ return i ? JSON.parse(target.cstrToJs(i)) : null } - finally{ target.dealloc(i) } - }); + xResult.set('string', (i)=>target.cstrToJs(i)) + .set('utf8', xResult.get('string')) + .set('string:dealloc', (i)=>{ + try { return i ? target.cstrToJs(i) : null } + finally{ target.dealloc(i) } + }) + .set('utf8:dealloc', xResult.get('string:dealloc')) + .set('json', (i)=>JSON.parse(target.cstrToJs(i))) + .set('json:dealloc', (i)=>{ + try{ return i ? JSON.parse(target.cstrToJs(i)) : null } + finally{ target.dealloc(i) } + }); /** Internal-use-only base class for FuncPtrAdapter and potentially @@ -1748,10 +1749,13 @@ self.WhWasmUtilInstaller = function(target){ - `N*` (args): a type name in the form `N*`, where N is a numeric type name, is treated the same as WASM pointer. - - `*` and `pointer` (args): have multple semantics. They - behave exactly as described below for `string` args. + - `*` and `pointer` (args): are assumed to be WASM pointer values + and are returned coerced to an appropriately-sized pointer + value (i32 or i64). Non-numeric values will coerce to 0 and + out-of-range values will have undefined results (just as with + any pointer misuse). - - `*` and `pointer` (results): are aliases for the current + - `*` and `pointer` (results): aliases for the current WASM pointer numeric type. - `**` (args): is simply a descriptive alias for the WASM pointer diff --git a/manifest b/manifest index 0476b9eced..9fa7ef3ea9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Internal\sJS\scleanups.\sCorrect\spart\sof\s[ac136925a645]\sto\saccount\sfor\sthe\seTextRep\sflag\sbeing\sable\sto\shold\sflags\sother\sthan\sthe\sencoding. -D 2022-12-23T21:10:49.493 +C Reimplement\sJS's\ssqlite3_bind_text/blob()\swith\shand-written\sbindings\sto\spermit\smore\sflexible\sinputs.\sAdd\sautomated\sJS-to-C\sfunction\sconversion\sto\ssqlite3_busy_handler().\ssqlite3.wasm.xWrap()'s\s'*'\sargument\sconversion\sno\slonger\streats\sJS\sstrings\sas\sC-strings:\sthose\sconversions\srequire\sexplicit\sopt-in\svia\sthe\s'string'\sconverter\s(or\sequivalent). +D 2022-12-23T23:46:33.608 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js f50211dc11f1debf972cdaea87cb4df9772022828072e7100cf5025d1dca2a78 -F ext/wasm/api/sqlite3-api-oo1.js 4cce9671e8a31ac9b76bd8559e7827ccc2b121734e460fa9c7d243735a771ec8 -F ext/wasm/api/sqlite3-api-prologue.js 789639d256e3134563c5c9be25ade28b40e06e783885d26cccc01cd1ed4b820d +F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 +F ext/wasm/api/sqlite3-api-oo1.js c2a3e310f993a632b6c5da0c49b0635863a73df60c4f9fc0a30648f25e4ec32a +F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 97807770ec452fdcaa48509c5decd3a2c1e3001164a62a3223a347f66967533e +F ext/wasm/common/whwasmutil.js 700fb1b702986522d2177fe8247bfbab3040e82cb4f6c35e929c4c85fbd7ffc5 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb -R 537077e8e7a576993086a957d5c52d05 +P 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f +R 0557f08bf576b7be78ec588d2742348d U stephan -Z 379d99233453fc912eb71dcbaf16b8ce +Z 4e12d5aedea06f895991428eb871a6d7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a091b64a43..83020f5c61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f \ No newline at end of file +96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6 \ No newline at end of file From 0cdc01d01a288a83327aaa3ed9d29966ffe7b81f Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 24 Dec 2022 01:59:42 +0000 Subject: [PATCH 021/165] If sqlite3.oo1.DB.exec()'s callback returns a literal false, stop step()ing over results as if the end of the result set had been reached. Unrelated minor code-adjacent cleanups. FossilOrigin-Name: 33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30 --- ext/wasm/api/sqlite3-api-oo1.js | 45 ++++++++++++++++++++++----------- ext/wasm/tester1.c-pp.js | 8 ++++++ manifest | 14 +++++----- manifest.uuid | 2 +- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index ddb346e545..10f0ebc181 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -447,7 +447,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if('$'===opt.rowMode[0]){ out.cbArg = function(stmt){ const rc = stmt.get(this.obj)[this.colName]; - return (undefined===rc) ? toss3("exec(): unknown result column:",this.colName) : rc; + return (undefined===rc) + ? toss3("exec(): unknown result column:",this.colName) + : rc; }.bind({ obj:Object.create(null), colName: opt.rowMode.substr(1) @@ -608,7 +610,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ try{ rc = wasm.cstrToJs(v.$zName) } finally { v.dispose() } } - return rc; + return rc; }, /** Compiles the given SQL and returns a prepared Stmt. This is @@ -697,21 +699,27 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ unchanged. Achtung: an SQL result may have multiple columns with identical names. - - `callback` = a function which gets called for each row of - the result set, but only if that statement has any result + - `callback` = a function which gets called for each row of the + result set, but only if that statement has any result _rows_. The callback's "this" is the options object, noting that this function synthesizes one if the caller does not pass one to exec(). The second argument passed to the callback is always the current Stmt object, as it's needed if the caller wants to fetch the column names or some such (noting that they could also be fetched via `this.columnNames`, if the client - provides the `columnNames` option). + provides the `columnNames` option). If the callback returns a + literal `false` (as opposed to any other falsy value, e.g. an + implicit `undefined` return), any ongoing statement-`step()` + iteration stops without an error. The return value of the + callback is otherwise ignored. ACHTUNG: The callback MUST NOT modify the Stmt object. Calling any of the Stmt.get() variants, Stmt.getColumnName(), or similar, is legal, but calling step() or finalize() is not. Member methods which are illegal in this context will - trigger an exception. + trigger an exception, but clients must also refrain from using + any lower-level (C-style) APIs which might modify the + statement. The first argument passed to the callback defaults to an array of values from the current result row but may be changed with ... @@ -799,7 +807,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Array.isArray(opt.resultRows) ? opt.resultRows : undefined; let stmt; let bind = opt.bind; - let evalFirstResult = !!(arg.cbArg || opt.columnNames) /* true to evaluate the first result-returning query */; + let evalFirstResult = !!( + arg.cbArg || opt.columnNames || resultRows + ) /* true to step through the first result-returning statement */; const stack = wasm.scopedAllocPush(); const saveSql = Array.isArray(opt.saveSql) ? opt.saveSql : undefined; try{ @@ -810,9 +820,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ space for the SQL (pSql). When prepare_v2() returns, pzTail will point to somewhere in pSql. */ let sqlByteLen = isTA ? arg.sql.byteLength : wasm.jstrlen(arg.sql); - const ppStmt = wasm.scopedAlloc(/* output (sqlite3_stmt**) arg and pzTail */ - (2 * wasm.ptrSizeof) - + (sqlByteLen + 1/* SQL + NUL */)); + const ppStmt = wasm.scopedAlloc( + /* output (sqlite3_stmt**) arg and pzTail */ + (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */) + ); const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */; let pSql = pzTail + wasm.ptrSizeof; const pSqlEnd = pSql + sqlByteLen; @@ -848,11 +859,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(Array.isArray(opt.columnNames)){ stmt.getColumnNames(opt.columnNames); } - while(!!arg.cbArg && stmt.step()){ - stmt._isLocked = true; - const row = arg.cbArg(stmt); - if(resultRows) resultRows.push(row); - if(callback) callback.call(opt, row, stmt); + if(arg.cbArg || resultRows){ + for(; stmt.step(); stmt._isLocked = false){ + stmt._isLocked = true; + const row = arg.cbArg(stmt); + if(resultRows) resultRows.push(row); + if(callback && false === callback.call(opt, row, stmt)){ + break; + } + } stmt._isLocked = false; } }else{ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 5411c064ce..82dd73e23b 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1391,6 +1391,14 @@ self.sqlite3InitModule = sqlite3InitModule; db.selectValue("SELECT "+Number.MIN_SAFE_INTEGER)). assert(Number.MAX_SAFE_INTEGER === db.selectValue("SELECT "+Number.MAX_SAFE_INTEGER)); + + counter = 0; + db.exec({ + sql: "SELECT a FROM t", + callback: ()=>(1===++counter), + }); + T.assert(2===counter, + "Expecting exec step() loop to stop if callback returns false."); if(wasm.bigIntEnabled && haveWasmCTests()){ const mI = wasm.xCall('sqlite3_wasm_test_int64_max'); const b = BigInt(Number.MAX_SAFE_INTEGER * 2); diff --git a/manifest b/manifest index 9fa7ef3ea9..63b0ff62c9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reimplement\sJS's\ssqlite3_bind_text/blob()\swith\shand-written\sbindings\sto\spermit\smore\sflexible\sinputs.\sAdd\sautomated\sJS-to-C\sfunction\sconversion\sto\ssqlite3_busy_handler().\ssqlite3.wasm.xWrap()'s\s'*'\sargument\sconversion\sno\slonger\streats\sJS\sstrings\sas\sC-strings:\sthose\sconversions\srequire\sexplicit\sopt-in\svia\sthe\s'string'\sconverter\s(or\sequivalent). -D 2022-12-23T23:46:33.608 +C If\ssqlite3.oo1.DB.exec()'s\scallback\sreturns\sa\sliteral\sfalse,\sstop\sstep()ing\sover\sresults\sas\sif\sthe\send\sof\sthe\sresult\sset\shad\sbeen\sreached.\sUnrelated\sminor\scode-adjacent\scleanups. +D 2022-12-24T01:59:42.190 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 -F ext/wasm/api/sqlite3-api-oo1.js c2a3e310f993a632b6c5da0c49b0635863a73df60c4f9fc0a30648f25e4ec32a +F ext/wasm/api/sqlite3-api-oo1.js 06fcaf4007b68b39db20c83b2620d5c04322bcbe2abb9bde7941b191257b6d43 F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 50b51af2b5466de0cba8ebc97b86bc886c32f937d8f4b36d3b3936ef9748e534 +F ext/wasm/tester1.c-pp.js 99d6dc920d0c379c78053edb89a870666cfb9d4d4548b31c94427f9135a1c0a2 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f -R 0557f08bf576b7be78ec588d2742348d +P 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6 +R 7ef916e9c75ca3398704313fbddc267b U stephan -Z 4e12d5aedea06f895991428eb871a6d7 +Z c6e787d4dc5ffd60ed702bf77e978ab3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 83020f5c61..4cbd4b8876 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6 \ No newline at end of file +33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30 \ No newline at end of file From 4b4ae86445c621a3eb6b67b96c67a3eb29d9751a Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 24 Dec 2022 11:16:49 +0000 Subject: [PATCH 022/165] oo1.DB.exec() rowMode="$columnName": a minor optimization and a preemtive fix for a hypothetical corner-case bug. FossilOrigin-Name: 0b2df22bd92914708ad0851d0401ad2cf3edb1968b88b2c07fe40792a731c5ba --- ext/wasm/api/sqlite3-api-oo1.js | 25 ++++++++++++------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 10f0ebc181..5404fc52d8 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -439,23 +439,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(util.isInt32(opt.rowMode)){ out.cbArg = (stmt)=>stmt.get(opt.rowMode); break; - }else if('string'===typeof opt.rowMode && opt.rowMode.length>1){ + }else if('string'===typeof opt.rowMode + && opt.rowMode.length>1 + && '$'===opt.rowMode[0]){ /* "$X": fetch column named "X" (case-sensitive!). Prior to 2022-12-14 ":X" and "@X" were also permitted, but having so many options is unnecessary and likely to cause confusion. */ - if('$'===opt.rowMode[0]){ - out.cbArg = function(stmt){ - const rc = stmt.get(this.obj)[this.colName]; - return (undefined===rc) - ? toss3("exec(): unknown result column:",this.colName) - : rc; - }.bind({ - obj:Object.create(null), - colName: opt.rowMode.substr(1) - }); - break; - } + const $colName = opt.rowMode.substr(1); + out.cbArg = (stmt)=>{ + const rc = stmt.get(Object.create(null))[$colName]; + return (undefined===rc) + ? toss3(capi.SQLITE_NOTFOUND, + "exec(): unknown result column:",$colName) + : rc; + }; + break; } toss3("Invalid rowMode:",opt.rowMode); } diff --git a/manifest b/manifest index 63b0ff62c9..da21b211c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\ssqlite3.oo1.DB.exec()'s\scallback\sreturns\sa\sliteral\sfalse,\sstop\sstep()ing\sover\sresults\sas\sif\sthe\send\sof\sthe\sresult\sset\shad\sbeen\sreached.\sUnrelated\sminor\scode-adjacent\scleanups. -D 2022-12-24T01:59:42.190 +C oo1.DB.exec()\srowMode="$columnName":\sa\sminor\soptimization\sand\sa\spreemtive\sfix\sfor\sa\shypothetical\scorner-case\sbug. +D 2022-12-24T11:16:49.554 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 -F ext/wasm/api/sqlite3-api-oo1.js 06fcaf4007b68b39db20c83b2620d5c04322bcbe2abb9bde7941b191257b6d43 +F ext/wasm/api/sqlite3-api-oo1.js 7ae49f6d9dcbc268d6fc9bce6bd070c72884d544bd0c6f12fa682d51027bf4d3 F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6 -R 7ef916e9c75ca3398704313fbddc267b +P 33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30 +R d15205afc8348e399a5e2c3665229d17 U stephan -Z c6e787d4dc5ffd60ed702bf77e978ab3 +Z 3c00734fbb2a03c4e427540c406cdc55 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4cbd4b8876..41002f02ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30 \ No newline at end of file +0b2df22bd92914708ad0851d0401ad2cf3edb1968b88b2c07fe40792a731c5ba \ No newline at end of file From 0db1c901378e29fd576e93d16a1305c6269d411d Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 24 Dec 2022 13:46:27 +0000 Subject: [PATCH 023/165] Add a test for the (failure) case of client-level code calling the oo1.Stmt constructor directly. FossilOrigin-Name: 6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a --- ext/wasm/api/sqlite3-api-oo1.js | 19 +++++++++++-------- ext/wasm/tester1.c-pp.js | 8 +++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 5404fc52d8..87509b59a3 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -337,7 +337,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ const Stmt = function(){ if(BindTypes!==arguments[2]){ - toss3("Do not call the Stmt constructor directly. Use DB.prepare()."); + toss3(capi.SQLITE_MISUSE, "Do not call the Stmt constructor directly. Use DB.prepare()."); } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); @@ -887,10 +887,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } return arg.returnVal(); }/*exec()*/, + /** - Creates a new scalar UDF (User-Defined Function) which is - accessible via SQL code. This function may be called in any - of the following forms: + Creates a new UDF (User-Defined Function) which is accessible + via SQL code. This function may be called in any of the + following forms: - (name, function) - (name, function, optionsObject) @@ -906,10 +907,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ functions. Creating an aggregate or window function requires the options-object form (see below for details). - UDFs cannot currently be removed from a DB handle after they're - added. More correctly, they can be removed as documented for - sqlite3_create_function_v2(), but doing so will "leak" the - JS-created WASM binding of those functions. + UDFs can be removed as documented for + sqlite3_create_function_v2() and + sqlite3_create_window_function(), but doing so will "leak" the + JS-created WASM binding of those functions (meaning that their + entries in the WASM indirect function table still + exist). Eliminating that potential leak is a pending TODO. On success, returns this object. Throws on error. diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 82dd73e23b..8b80d4d88d 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1219,7 +1219,7 @@ self.sqlite3InitModule = sqlite3InitModule; }) //////////////////////////////////////////////////////////////////// - .t('DB.Stmt', function(S){ + .t('DB.Stmt', function(sqlite3){ let st = this.db.prepare( new TextEncoder('utf-8').encode("select 3 as a") ); @@ -1274,6 +1274,12 @@ self.sqlite3InitModule = sqlite3InitModule; } T.assert(!st.pointer) .assert(0===this.db.openStatementCount()); + + T.mustThrowMatching(()=>new sqlite3.oo1.Stmt("hi"), function(err){ + return (err instanceof sqlite3.SQLite3Error) + && capi.SQLITE_MISUSE === err.resultCode + && 0 < err.message.indexOf("Do not call the Stmt constructor directly.") + }); }) //////////////////////////////////////////////////////////////////////// diff --git a/manifest b/manifest index da21b211c7..f7f283894f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C oo1.DB.exec()\srowMode="$columnName":\sa\sminor\soptimization\sand\sa\spreemtive\sfix\sfor\sa\shypothetical\scorner-case\sbug. -D 2022-12-24T11:16:49.554 +C Add\sa\stest\sfor\sthe\s(failure)\scase\sof\sclient-level\scode\scalling\sthe\soo1.Stmt\sconstructor\sdirectly. +D 2022-12-24T13:46:27.601 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 -F ext/wasm/api/sqlite3-api-oo1.js 7ae49f6d9dcbc268d6fc9bce6bd070c72884d544bd0c6f12fa682d51027bf4d3 +F ext/wasm/api/sqlite3-api-oo1.js 485f43129b25b939209effcec635e801bad75bf0a534c7ca327a7cd934744163 F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 99d6dc920d0c379c78053edb89a870666cfb9d4d4548b31c94427f9135a1c0a2 +F ext/wasm/tester1.c-pp.js d395eb6aaf4de79bf2c027f7c4b5e4ae007ee1822d6e064e946d0305672a9761 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30 -R d15205afc8348e399a5e2c3665229d17 +P 0b2df22bd92914708ad0851d0401ad2cf3edb1968b88b2c07fe40792a731c5ba +R 56f356985466274ad72950f0668d6b94 U stephan -Z 3c00734fbb2a03c4e427540c406cdc55 +Z bfd3bc98ed13225718cba2333de93b83 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 41002f02ab..696b648cc0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b2df22bd92914708ad0851d0401ad2cf3edb1968b88b2c07fe40792a731c5ba \ No newline at end of file +6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a \ No newline at end of file From cede6384fde313cd346c341e6088cb4c8a34f5c5 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 24 Dec 2022 14:16:02 +0000 Subject: [PATCH 024/165] Extend oo1.Stmt.bind() to accept ArrayBuffer instances to bind as blobs. FossilOrigin-Name: f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d --- ext/wasm/api/sqlite3-api-oo1.js | 42 ++++++++++++++++++--------------- ext/wasm/tester1.c-pp.js | 5 +++- manifest | 14 +++++------ manifest.uuid | 2 +- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 87509b59a3..e3c90271b1 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1230,7 +1230,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /* else fall through */ default: //console.log("isSupportedBindType",t,v); - return util.isBindableTypedArray(v) ? BindTypes.blob : undefined; + return (util.isBindableTypedArray(v) || (v instanceof ArrayBuffer)) + ? BindTypes.blob : undefined; } }; @@ -1346,19 +1347,21 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case BindTypes.blob: { if('string'===typeof val){ rc = f._.string(stmt, ndx, val, true); + break; + }else if(val instanceof ArrayBuffer){ + val = new Uint8Array(val); }else if(!util.isBindableTypedArray(val)){ toss3("Binding a value as a blob requires", - "that it be a string, Uint8Array, or Int8Array."); - }else{ - const stack = wasm.scopedAllocPush(); - try{ - const pBlob = wasm.scopedAlloc(val.byteLength || 1); - wasm.heap8().set(val.byteLength ? val : [0], pBlob) - rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, - capi.SQLITE_TRANSIENT); - }finally{ - wasm.scopedAllocPop(stack); - } + "that it be a string, Uint8Array, Int8Array, or ArrayBuffer."); + } + const stack = wasm.scopedAllocPush(); + try{ + const pBlob = wasm.scopedAlloc(val.byteLength || 1); + wasm.heap8().set(val.byteLength ? val : [0], pBlob) + rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, + capi.SQLITE_TRANSIENT); + }finally{ + wasm.scopedAllocPop(stack); } break; } @@ -1367,6 +1370,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ toss3("Unsupported bind() argument type: "+(typeof val)); } if(rc) DB.checkRc(stmt.db.pointer, rc); + stmt._mayGet = false; return stmt; }; @@ -1454,8 +1458,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - Strings are bound as strings (use bindAsBlob() to force blob binding). - - Uint8Array and Int8Array instances are bound as blobs. - (TODO: binding the other TypedArray types.) + - Uint8Array, Int8Array, and ArrayBuffer instances are bound as + blobs. (TODO? binding the other TypedArray types.) If passed an array, each element of the array is bound at the parameter index equal to the array index plus 1 @@ -1510,8 +1514,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } arg.forEach((v,i)=>bindOne(this, i+1, affirmSupportedBindType(v), v)); return this; + }else if(arg instanceof ArrayBuffer){ + arg = new Uint8Array(arg); } - else if('object'===typeof arg/*null was checked above*/ + if('object'===typeof arg/*null was checked above*/ && !util.isBindableTypedArray(arg)){ /* Treat each property of arg as a named bound parameter. */ if(1!==arguments.length){ @@ -1533,7 +1539,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ the value. The ndx may be a numbered or named bind index. The value must be of type string, null/undefined (both get treated as null), or a TypedArray of a type supported by the bind() - API. + API. This API cannot bind numbers as blobs. If passed a single argument, a bind index of 1 is assumed and the first argument is the value. @@ -1549,9 +1555,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ && BindTypes.null !== t){ toss3("Invalid value type for bindAsBlob()"); } - bindOne(this, ndx, BindTypes.blob, arg); - this._mayGet = false; - return this; + return bindOne(this, ndx, BindTypes.blob, arg); }, /** Steps the statement one time. If the result indicates that a diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 8b80d4d88d..a87532e18b 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1648,7 +1648,10 @@ self.sqlite3InitModule = sqlite3InitModule; assert(T.eqApprox(1.3,db.selectValue("select asis(1 + 0.3)"))); let blobArg = new Uint8Array([0x68, 0x69]); - let blobRc = db.selectValue("select asis(?1)", blobArg); + let blobRc = db.selectValue( + "select asis(?1)", + blobArg.buffer/*confirm that ArrayBuffer is handled as a Uint8Array*/ + ); T.assert(blobRc instanceof Uint8Array). assert(2 === blobRc.length). assert(0x68==blobRc[0] && 0x69==blobRc[1]); diff --git a/manifest b/manifest index f7f283894f..713880bc5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sfor\sthe\s(failure)\scase\sof\sclient-level\scode\scalling\sthe\soo1.Stmt\sconstructor\sdirectly. -D 2022-12-24T13:46:27.601 +C Extend\soo1.Stmt.bind()\sto\saccept\sArrayBuffer\sinstances\sto\sbind\sas\sblobs. +D 2022-12-24T14:16:02.217 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 -F ext/wasm/api/sqlite3-api-oo1.js 485f43129b25b939209effcec635e801bad75bf0a534c7ca327a7cd934744163 +F ext/wasm/api/sqlite3-api-oo1.js 1312eaf2776c957e41a6fd63c31e7487502bf71745805c41f72429e0925802a5 F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js d395eb6aaf4de79bf2c027f7c4b5e4ae007ee1822d6e064e946d0305672a9761 +F ext/wasm/tester1.c-pp.js 145c493221727eb40194280bb2852da49f857e850d8394c31b7bd4caeb5d7bed F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0b2df22bd92914708ad0851d0401ad2cf3edb1968b88b2c07fe40792a731c5ba -R 56f356985466274ad72950f0668d6b94 +P 6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a +R b07f6a4d9e30a3f649f5decc82bdf7ef U stephan -Z bfd3bc98ed13225718cba2333de93b83 +Z 934cef85bd1b053ac09da3261d128afb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 696b648cc0..bc46d13f05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a \ No newline at end of file +f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d \ No newline at end of file From 4099b3cab3c3451a2d9643738308be0b2d9e44b1 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 24 Dec 2022 15:28:45 +0000 Subject: [PATCH 025/165] Replace JS-side use of SQLITE_TRANSIENT with the new SQLITE_WASM_DEALLOC, reducing the amount allocation/copying required by sqlite3_bind_blob/text() and sqlite3_result_blob/text(). Remove the 'experimental' log message from the virtual table tests. FossilOrigin-Name: ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1 --- ext/wasm/api/sqlite3-api-glue.js | 43 ++++++++++++++++++++++++---- ext/wasm/api/sqlite3-api-oo1.js | 26 ++++++----------- ext/wasm/api/sqlite3-api-prologue.js | 38 +++++++++++++----------- ext/wasm/api/sqlite3-wasm.c | 5 ++++ ext/wasm/tester1.c-pp.js | 2 -- manifest | 20 ++++++------- manifest.uuid | 2 +- 7 files changed, 84 insertions(+), 52 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index dd80963f3e..7b5fa11816 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -24,6 +24,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ self.WhWasmUtilInstaller(wasm); delete self.WhWasmUtilInstaller; + { + /** + Find a mapping for SQLITE_WASM_DEALLOC, which the API + guarantees is a WASM pointer to the same underlying function as + wasm.dealloc() (noting that wasm.dealloc() is permitted to be a + JS wrapper around the WASM function). There is unfortunately no + O(1) algorithm for finding this pointer: we have to walk the + WASM indirect function table to find it. However, experience + indicates that that particular function is always very close to + the front of the table (it's been entry #3 in all relevant + tests). + */ + const dealloc = wasm.exports[sqlite3.config.deallocExportName]; + const nFunc = wasm.functionTable().length; + let i; + for(i = 0; i < nFunc; ++i){ + const e = wasm.functionEntry(i); + if(dealloc === e){ + capi.SQLITE_WASM_DEALLOC = i; + break; + } + } + if(dealloc !== wasm.functionEntry(capi.SQLITE_WASM_DEALLOC)){ + toss("Internal error: cannot find function pointer for SQLITE_WASM_DEALLOC."); + } + } + /** Signatures for the WASM-exported C-side functions. Each entry is an array with 2+ elements: @@ -874,7 +901,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ text = pMem.join(''); } let p, n; - try { + try{ if(util.isSQLableTypedArray(text)){ p = wasm.allocFromTypedArray(text); n = text.byteLength; @@ -886,9 +913,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "Invalid 3rd argument type for sqlite3_bind_text()." ); } - return __bindText(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT); - }finally{ + return __bindText(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC); + }catch(e){ wasm.dealloc(p); + return util.sqlite3_wasm_db_error( + capi.sqlite3_db_handle(pStmt), e + ); } }/*sqlite3_bind_text()*/; @@ -917,9 +947,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "Invalid 3rd argument type for sqlite3_bind_blob()." ); } - return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT); - }finally{ + return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC); + }catch(e){ wasm.dealloc(p); + return util.sqlite3_wasm_db_error( + capi.sqlite3_db_handle(pStmt), e + ); } }/*sqlite3_bind_blob()*/; diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index e3c90271b1..16f5f00b15 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1285,7 +1285,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ success. */ const bindOne = function f(stmt,ndx,bindType,val){ - affirmUnlocked(stmt, 'bind()'); + affirmUnlocked(affirmStmtOpen(stmt), 'bind()'); if(!f._){ f._tooBigInt = (v)=>toss3( "BigInt value is too big to store without precision loss:", v @@ -1295,14 +1295,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ so we have no range checking. */ f._ = { string: function(stmt, ndx, val, asBlob){ - const stack = wasm.scopedAllocPush(); - try{ - const [pStr, n] = wasm.scopedAllocCString(val, true); - const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text; - return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT); - }finally{ - wasm.scopedAllocPop(stack); - } + const [pStr, n] = wasm.allocCString(val, true); + const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text; + return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_WASM_DEALLOC); } }; }/* static init */ @@ -1354,15 +1349,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ toss3("Binding a value as a blob requires", "that it be a string, Uint8Array, Int8Array, or ArrayBuffer."); } - const stack = wasm.scopedAllocPush(); - try{ - const pBlob = wasm.scopedAlloc(val.byteLength || 1); - wasm.heap8().set(val.byteLength ? val : [0], pBlob) - rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, - capi.SQLITE_TRANSIENT); - }finally{ - wasm.scopedAllocPop(stack); - } + const pBlob = wasm.alloc(val.byteLength || 1); + wasm.heap8().set(val.byteLength ? val : [0], pBlob) + rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength, + capi.SQLITE_WASM_DEALLOC); break; } default: diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index c3533a4767..faa2dbbbf4 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -321,14 +321,17 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( }; /** - Returns true if v appears to be one of our bind()-able TypedArray - types: Uint8Array or Int8Array. Support for TypedArrays with - element sizes >1 is a potential TODO just waiting on a use case - to justify them. + Returns v if v appears to be one of our bind()-able TypedArray + types: Uint8Array or Int8Array or ArrayBuffer. Support for + TypedArrays with element sizes >1 is a potential TODO just + waiting on a use case to justify them. Until then, their `buffer` + property can be used to pass them as an ArrayBuffer. If it's not + a bindable array type, a falsy value is returned. */ const isBindableTypedArray = (v)=>{ - return v && (v instanceof Uint8Array || v instanceof Int8Array); - //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT); + return v && (v instanceof Uint8Array + || v instanceof Int8Array + || v instanceof ArrayBuffer); }; /** @@ -341,8 +344,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( isSQLableTypedArray() list. */ const isSQLableTypedArray = (v)=>{ - return v && (v instanceof Uint8Array || v instanceof Int8Array); - //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT); + return v && (v instanceof Uint8Array + || v instanceof Int8Array + || v instanceof ArrayBuffer); }; /** Returns true if isBindableTypedArray(v) does, else throws with a message @@ -439,8 +443,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and treated as that type. - In all of those cases, the final argument (text destructor) is - ignored and capi.SQLITE_TRANSIENT is assumed. + In all of those cases, the final argument (destructor) is + ignored and capi.SQLITE_WASM_DEALLOC is assumed. A 3rd argument of `null` is treated as if it were a WASM pointer of 0. @@ -477,7 +481,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( treated as that type. In each of those cases, the final argument (text destructor) is - ignored and capi.SQLITE_TRANSIENT is assumed. + ignored and capi.SQLITE_WASM_DEALLOC is assumed. A 3rd argument of `null` is treated as if it were a WASM pointer of 0. @@ -1645,7 +1649,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( capi.sqlite3_result_error(pCtx, ''+e, -1); } }; - + /** This function passes its 2nd argument to one of the sqlite3_result_xyz() routines, depending on the type of that @@ -1661,7 +1665,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( - `bigint`: similar to `number` but will trigger an error if the value is too big to store in an int64. - `string`: `sqlite3_result_text()` - - Uint8Array or Int8Array: `sqlite3_result_blob()` + - Uint8Array or Int8Array or ArrayBuffer: `sqlite3_result_blob()` - `undefined`: is a no-op provided to simplify certain use cases. Anything else triggers `sqlite3_result_error()` with a @@ -1712,9 +1716,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( f(pCtx, val); break; } - case 'string': - capi.sqlite3_result_text(pCtx, val, -1, capi.SQLITE_TRANSIENT); + case 'string': { + const [p, n] = wasm.allocCString(val,true); + capi.sqlite3_result_text(pCtx, p, n, capi.SQLITE_WASM_DEALLOC); break; + } case 'object': if(null===val/*yes, typeof null === 'object'*/) { capi.sqlite3_result_null(pCtx); @@ -1723,7 +1729,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const pBlob = wasm.allocFromTypedArray(val); capi.sqlite3_result_blob( pCtx, pBlob, val.byteLength, - wasm.exports[sqlite3.config.deallocExportName] + capi.SQLITE_WASM_DEALLOC ); break; } diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index ed3b96dea1..f2bf5fef1e 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -1621,6 +1621,11 @@ int sqlite3_wasm_test_intptr(int * p){ return *p = *p * 2; } +SQLITE_WASM_KEEP +void * sqlite3_wasm_test_voidptr(void * p){ + return p; +} + SQLITE_WASM_KEEP int64_t sqlite3_wasm_test_int64_max(void){ return (int64_t)0x7fffffffffffffff; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index a87532e18b..ae745a28de 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1987,7 +1987,6 @@ self.sqlite3InitModule = sqlite3InitModule; name: 'virtual table #1: eponymous w/ manual exception handling', predicate: ()=>!!capi.sqlite3_index_info, test: function(sqlite3){ - warn("The vtab/module JS bindings are experimental and subject to change."); const VT = sqlite3.vtab; const tmplCols = Object.assign(Object.create(null),{ A: 0, B: 1 @@ -2185,7 +2184,6 @@ self.sqlite3InitModule = sqlite3InitModule; name: 'virtual table #2: non-eponymous w/ automated exception wrapping', predicate: ()=>!!capi.sqlite3_index_info, test: function(sqlite3){ - warn("The vtab/module JS bindings are experimental and subject to change."); const VT = sqlite3.vtab; const tmplCols = Object.assign(Object.create(null),{ A: 0, B: 1 diff --git a/manifest b/manifest index 713880bc5c..85eda685fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\soo1.Stmt.bind()\sto\saccept\sArrayBuffer\sinstances\sto\sbind\sas\sblobs. -D 2022-12-24T14:16:02.217 +C Replace\sJS-side\suse\sof\sSQLITE_TRANSIENT\swith\sthe\snew\sSQLITE_WASM_DEALLOC,\sreducing\sthe\samount\sallocation/copying\srequired\sby\ssqlite3_bind_blob/text()\sand\ssqlite3_result_blob/text().\sRemove\sthe\s'experimental'\slog\smessage\sfrom\sthe\svirtual\stable\stests. +D 2022-12-24T15:28:45.647 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,16 +503,16 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9 -F ext/wasm/api/sqlite3-api-oo1.js 1312eaf2776c957e41a6fd63c31e7487502bf71745805c41f72429e0925802a5 -F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d +F ext/wasm/api/sqlite3-api-glue.js ba532798e577497da9221bf9ac7d286619eec4d16736c927f1d10f3c8d21ada3 +F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b +F ext/wasm/api/sqlite3-api-prologue.js b0302c61abf21966c8cf9788453fea29c790633f7a14a92e05e6db994b590d11 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c b114bb85cdf8be7b2939ddcc2bbc2f30c190c44b993c34a77b017c978345efb1 +F ext/wasm/api/sqlite3-wasm.c 313489816e1733a10ece74a92cbea65d3ee241eb07d98088e96258cc211c9719 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 145c493221727eb40194280bb2852da49f857e850d8394c31b7bd4caeb5d7bed +F ext/wasm/tester1.c-pp.js dec750b65ec33ff267b35370ab746899859beb0a7c695cb9b087663d5b144512 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a -R b07f6a4d9e30a3f649f5decc82bdf7ef +P f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d +R 244f04d134cc6151e3968d82d6c44161 U stephan -Z 934cef85bd1b053ac09da3261d128afb +Z 5d490510463cd36c1f126d30ea32761d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bc46d13f05..cf1529c72f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d \ No newline at end of file +ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1 \ No newline at end of file From 75c04ba89cee1bb6b7b2b599eeacfbd063c84703 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 10:22:27 +0000 Subject: [PATCH 026/165] Simplify the signature for JS functions, as opposed to function pointers, passed to sqlite3_exec(), eliminating the superfluous initial two arguments. Update related tests to demonstrate both function-passing approaches. FossilOrigin-Name: e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b --- ext/wasm/api/sqlite3-api-glue.js | 39 +++++++++--------- ext/wasm/api/sqlite3-api-prologue.js | 6 +-- ext/wasm/tester1.c-pp.js | 59 ++++++++++++++++++++++------ manifest | 16 ++++---- manifest.uuid | 2 +- 5 files changed, 80 insertions(+), 42 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 7b5fa11816..0ef796664a 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -234,7 +234,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ optional features into account. */ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]); } - + /** Functions which require BigInt (int64) support are separated from the others because we need to conditionally bind them or apply @@ -569,7 +569,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_create_collation() and friends*/ - if(1){/* Special-case handling of sqlite3_exec() */ + {/* Special-case handling of sqlite3_exec() */ const __exec = wasm.xWrap("sqlite3_exec", "int", ["sqlite3*", "string:flexible", new wasm.xWrap.FuncPtrAdapter({ @@ -585,23 +585,23 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } /* Wrap the callback in a WASM-bound function and convert the callback's `(char**)` arguments to arrays of strings... */ + let aNames; const cbwrap = function(pVoid, nCols, pColVals, pColNames){ let rc = capi.SQLITE_ERROR; try { - let aVals = [], aNames = [], i = 0, offset = 0; - for( ; i < nCols; offset += (wasm.ptrSizeof * ++i) ){ - aVals.push( wasm.cstrToJs(wasm.peekPtr(pColVals + offset)) ); - aNames.push( wasm.cstrToJs(wasm.peekPtr(pColNames + offset)) ); - } - rc = callback(pVoid, nCols, aVals, aNames) | 0; - /* The first 2 args of the callback are useless for JS but - we want the JS mapping of the C API to be as close to the - C API as possible. */ + const aVals = wasm.cArgvToJs(nCols, pColVals); + if(!aNames) aNames = wasm.cArgvToJs(nCols, pColNames); + rc = callback(aVals, aNames) | 0; }catch(e){ - /* If we set the db error state here, the higher-level exec() call - replaces it with its own, so we have no way of reporting the - exception message except the console. We must not propagate - exceptions through the C API. */ + /* If we set the db error state here, the higher-level + exec() call replaces it with its own, so we have no way + of reporting the exception message except the console. We + must not propagate exceptions through the C API. Though + we make an effort to report OOM here, sqlite3_exec() + translates that into SQLITE_ABORT as well. */ + rc = (e instanceof sqlite3.WasmAllocError) + ? capi.SQLITE_NOMEM + : (e.resultCode || capi.SQLITE_ERROR); } return rc; }; @@ -616,7 +616,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; }/*sqlite3_exec() proxy*/; - if(1){/* Special-case handling of sqlite3_create_function_v2() + {/* Special-case handling of sqlite3_create_function_v2() and sqlite3_create_window_function() */ /* Maintenance reminder: FuncPtrAdapter is not expressive enough to be able to perform these mappings. */ @@ -1041,20 +1041,21 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ toss("Maintenance required: increase sqlite3_wasm_enum_json()'s", "static buffer size!"); } - wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); + wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); + // Groups of SQLITE_xyz macros... const defineGroups = ['access', 'authorizer', 'blobFinalizers', 'config', 'dataTypes', 'dbConfig', 'dbStatus', 'encodings', 'fcntl', 'flock', 'ioCap', 'limits', 'openFlags', 'prepareFlags', 'resultCodes', - 'serialize', 'sqlite3Status', + 'sqlite3Status', 'stmtStatus', 'syncFlags', 'trace', 'txnState', 'udfFlags', 'version' ]; if(wasm.bigIntEnabled){ - defineGroups.push('vtab'); + defineGroups.push('serialize', 'vtab'); } for(const t of defineGroups){ for(const e of Object.entries(wasm.ctype[t])){ diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index faa2dbbbf4..e207fc194d 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -948,7 +948,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const m = f._rx.exec(opt); rv[0] = (m ? m[1] : opt); rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true; - }; + }; } const rc = {}, ov = [0,0]; let i = 0, k; @@ -1749,8 +1749,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( argument of sqlite3_value_to_js(). If the sqlite3_column_value() returns NULL (e.g. because the column index is out of range), this function returns `undefined`, regardless of the 3rd - argument. 3rd argument is falsy and conversion fails, `undefined` - will be returned. + argument. If the 3rd argument is falsy and conversion fails, + `undefined` will be returned. Note that sqlite3_column_value() returns an "unprotected" value object, but in a single-threaded environment (like this one) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index ae745a28de..2314dae2d3 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1882,18 +1882,18 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(3===resultRows.length) .assert(2===resultRows[1]); T.assert(2===db.selectValue('select a from foo.bar where a>1 order by a')); + + /** Demonstrate the JS-simplified form of the sqlite3_exec() callback... */ let colCount = 0, rowCount = 0; - const execCallback = function(pVoid, nCols, aVals, aNames){ - //console.warn("execCallback(",arguments,")"); - colCount = nCols; - ++rowCount; - T.assert(2===aVals.length) - .assert(2===aNames.length) - .assert(+(aVals[1]) === 2 * +(aVals[0])); - }; let rc = capi.sqlite3_exec( - db.pointer, "select a, a*2 from foo.bar", execCallback, - 0, 0 + db, "select a, a*2 from foo.bar", function(aVals, aNames){ + //console.warn("execCallback(",arguments,")"); + colCount = aVals.length; + ++rowCount; + T.assert(2===aVals.length) + .assert(2===aNames.length) + .assert(+(aVals[1]) === 2 * +(aVals[0])); + }, 0, 0 ); T.assert(0===rc).assert(3===rowCount).assert(2===colCount); rc = capi.sqlite3_exec( @@ -1902,8 +1902,45 @@ self.sqlite3InitModule = sqlite3InitModule; }, 0, 0 ); T.assert(capi.SQLITE_ABORT === rc); + + /* Demonstrate how to get access to the "full" callback + signature, as opposed to the simplified JS-specific one... */ + rowCount = colCount = 0; + const pCb = wasm.installFunction('i(pipp)', function(pVoid,nCols,aVals,aCols){ + /* Tip: wasm.cArgvToJs() can be used to convert aVals and + aCols to arrays: const vals = wasm.cArgvToJs(nCols, + aVals); */ + ++rowCount; + colCount = nCols; + T.assert(2 === nCols) + .assert(wasm.isPtr(pVoid)) + .assert(wasm.isPtr(aVals)) + .assert(wasm.isPtr(aCols)) + .assert(+wasm.cstrToJs(wasm.peekPtr(aVals + wasm.ptrSizeof)) + === 2 * +wasm.cstrToJs(wasm.peekPtr(aVals))); + return 0; + }); + try { + T.assert(wasm.isPtr(pCb)); + rc = capi.sqlite3_exec(db, "select a, a*2 from foo.bar", pCb, 0, 0); + T.assert(0===rc) + .assert(3===rowCount) + .assert(2===colCount); + }finally{ + wasm.uninstallFunction(pCb); + } + + // Demonstrate that an OOM result does not propagate through sqlite3_exec()... + rc = capi.sqlite3_exec( + db, "select a, a*2 from foo.bar", function(aVals, aNames){ + sqlite3.WasmAllocError.toss("just testing"); + }, 0, 0 + ); + T.assert(capi.SQLITE_ABORT === rc); + db.exec("detach foo"); - T.mustThrow(()=>db.exec("select * from foo.bar")); + T.mustThrow(()=>db.exec("select * from foo.bar"), + "Because foo is no longer attached."); }) //////////////////////////////////////////////////////////////////// diff --git a/manifest b/manifest index 85eda685fc..f514b0cc1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sJS-side\suse\sof\sSQLITE_TRANSIENT\swith\sthe\snew\sSQLITE_WASM_DEALLOC,\sreducing\sthe\samount\sallocation/copying\srequired\sby\ssqlite3_bind_blob/text()\sand\ssqlite3_result_blob/text().\sRemove\sthe\s'experimental'\slog\smessage\sfrom\sthe\svirtual\stable\stests. -D 2022-12-24T15:28:45.647 +C Simplify\sthe\ssignature\sfor\sJS\sfunctions,\sas\sopposed\sto\sfunction\spointers,\spassed\sto\ssqlite3_exec(),\seliminating\sthe\ssuperfluous\sinitial\stwo\sarguments.\sUpdate\srelated\stests\sto\sdemonstrate\sboth\sfunction-passing\sapproaches. +D 2022-12-25T10:22:27.506 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js ba532798e577497da9221bf9ac7d286619eec4d16736c927f1d10f3c8d21ada3 +F ext/wasm/api/sqlite3-api-glue.js 72f1ed1d60db62e18cf752c5871bc7c21cfef9258d9c81e61c830914c3f7da91 F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b -F ext/wasm/api/sqlite3-api-prologue.js b0302c61abf21966c8cf9788453fea29c790633f7a14a92e05e6db994b590d11 +F ext/wasm/api/sqlite3-api-prologue.js a27762fd1ed2576897026f28a748a69edcdcc53ef79f46cead5e4446dc949763 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js dec750b65ec33ff267b35370ab746899859beb0a7c695cb9b087663d5b144512 +F ext/wasm/tester1.c-pp.js e75daf4e82ce9c9506d165544b6052403802dd1bcf3f4f06fa6084b8520fb549 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d -R 244f04d134cc6151e3968d82d6c44161 +P ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1 +R 57b44198d665feb79b35a3b3cc62df00 U stephan -Z 5d490510463cd36c1f126d30ea32761d +Z fa52e396693ed4ebb322eeecdf80849b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cf1529c72f..aca2994565 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1 \ No newline at end of file +e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b \ No newline at end of file From 485229e14774ef12d31a815b05aee047739086dd Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 12:51:53 +0000 Subject: [PATCH 027/165] Enhance sqlite3.wasm.xWrap.FuncPtrAdapter to be able to handle sqlite3_create_function() and friends and reimplement those bindings to use this feature (this will also simplify certain session API bindings). Interal API changes only with no client-side breakage. FossilOrigin-Name: 7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d --- ext/wasm/api/sqlite3-api-glue.js | 241 ++++++++++++++----------------- ext/wasm/common/whwasmutil.js | 77 ++++++---- manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 169 insertions(+), 165 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 0ef796664a..9066b3431c 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -82,7 +82,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "sqlite3*", new wasm.xWrap.FuncPtrAdapter({ signature: 'i(pi)', - contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] + contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] }), "*" ]], @@ -160,7 +160,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ name: 'xProgressHandler', signature: 'i(p)', bindScope: 'context', - contextKey: (argIndex,argv)=>'sqlite3@'+argv[0] + contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] }), "*" ] ], @@ -200,7 +200,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ new wasm.xWrap.FuncPtrAdapter({ name: 'sqlite3_trace_v2::callback', signature: 'i(ippp)', - contextKey: (argIndex, argv)=>'sqlite3@'+argv[0] + contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] }), "*"], ["sqlite3_txn_state", "int", ["sqlite3*","string"]], /* Note that sqlite3_uri_...() have very specific requirements for @@ -497,28 +497,24 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); }; - if(1){/* Bindings for sqlite3_create_collation[_v2]() */ - const __collationContextKey = (argIndex,argv)=>{ + {/* Bindings for sqlite3_create_collation[_v2]() */ + // contextKey() impl for wasm.xWrap.FuncPtrAdapter + const contextKey = (argv,argIndex)=>{ return 'argv['+argIndex+']:sqlite3@'+argv[0]+ ':'+wasm.cstrToJs(argv[1]).toLowerCase() }; - const __ccv2 = wasm.xWrap( - 'sqlite3_create_collation_v2', 'int', - 'sqlite3*','string','int','*', - new wasm.xWrap.FuncPtrAdapter({ - /* int(*xCompare)(void*,int,const void*,int,const void*) */ - name: 'sqlite3_create_collation_v2::xCompare', - signature: 'i(pipip)', - bindScope: 'context', - contextKey: __collationContextKey - }), - new wasm.xWrap.FuncPtrAdapter({ - /* void(*xDestroy(void*) */ - name: 'sqlite3_create_collation_v2::xDestroy', - signature: 'v(p)', - bindScope: 'context', - contextKey: __collationContextKey - }) + const __sqlite3CreateCollationV2 = wasm.xWrap( + 'sqlite3_create_collation_v2', 'int', [ + 'sqlite3*', 'string', 'int', '*', + new wasm.xWrap.FuncPtrAdapter({ + /* int(*xCompare)(void*,int,const void*,int,const void*) */ + name: 'xCompare', signature: 'i(pipip)', contextKey + }), + new wasm.xWrap.FuncPtrAdapter({ + /* void(*xDestroy(void*) */ + name: 'xDestroy', signature: 'v(p)', contextKey + }) + ] ); /** @@ -552,13 +548,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } - let rc, pfCompare, pfDestroy; - try{ - rc = __ccv2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); + try{ + return __sqlite3CreateCollationV2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); }catch(e){ - rc = util.sqlite3_wasm_db_error(pDb, e); + return util.sqlite3_wasm_db_error(pDb, e); } - return rc; }; capi.sqlite3_create_collation = (pDb,zName,eTextRep,pArg,xCompare)=>{ @@ -617,82 +611,91 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_exec() proxy*/; {/* Special-case handling of sqlite3_create_function_v2() - and sqlite3_create_window_function() */ - /* Maintenance reminder: FuncPtrAdapter is not expressive enough - to be able to perform these mappings. */ - const sqlite3CreateFunction = wasm.xWrap( - "sqlite3_create_function_v2", "int", - ["sqlite3*", "string"/*funcName*/, "int"/*nArg*/, - "int"/*eTextRep*/, "*"/*pApp*/, - "*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, "*"/*xDestroy*/] - ); + and sqlite3_create_window_function(). */ + /** + FuncPtrAdapter for contextKey() for sqlite3_create_function(). + */ + const contextKey = function(argv,argIndex){ + return ( + 'sqlite3@'+argv[0] + +':'+argIndex + +':'+wasm.cstrToJs(argv[1]).toLowerCase() + ) + }; - const sqlite3CreateWindowFunction = wasm.xWrap( - "sqlite3_create_window_function", "int", - ["sqlite3*", "string"/*funcName*/, "int"/*nArg*/, - "int"/*eTextRep*/, "*"/*pApp*/, - "*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, - "*"/*xInverse*/, "*"/*xDestroy*/] - ); - - const __xFunc = function(callback){ - return function(pCtx, argc, pArgv){ - try{ - capi.sqlite3_result_js( - pCtx, - callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) - ); - }catch(e){ - //console.error('xFunc() caught:',e); - capi.sqlite3_result_error_js(pCtx, e); + /** + JS proxies for the various sqlite3_create[_window]_function() + callbacks, structured in a form usable by wasm.xWrap.FuncPtrAdapter. + */ + const __cfProxy = Object.assign(Object.create(null), { + xInverseAndStep: { + signature:'v(pip)', contextKey, + callProxy: (callback)=>{ + return (pCtx, argc, pArgv)=>{ + try{ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) } + catch(e){ capi.sqlite3_result_error_js(pCtx, e) } + }; } - }; - }; - - const __xInverseAndStep = function(callback){ - return function(pCtx, argc, pArgv){ - try{ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) } - catch(e){ capi.sqlite3_result_error_js(pCtx, e) } - }; - }; - - const __xFinalAndValue = function(callback){ - return function(pCtx){ - try{ capi.sqlite3_result_js(pCtx, callback(pCtx)) } - catch(e){ capi.sqlite3_result_error_js(pCtx, e) } - }; - }; - - const __xDestroy = function(callback){ - return function(pVoid){ - try{ callback(pVoid) } - catch(e){ console.error("UDF xDestroy method threw:",e) } - }; - }; - - const __xMap = Object.assign(Object.create(null), { - xFunc: {sig:'v(pip)', f:__xFunc}, - xStep: {sig:'v(pip)', f:__xInverseAndStep}, - xInverse: {sig:'v(pip)', f:__xInverseAndStep}, - xFinal: {sig:'v(p)', f:__xFinalAndValue}, - xValue: {sig:'v(p)', f:__xFinalAndValue}, - xDestroy: {sig:'v(p)', f:__xDestroy} - }); - - /* Internal helper for sqlite3_create_function() and friends. */ - const __xWrapFuncs = function(theKeys, theFuncs, tgtUninst){ - const rc = [] - for(const k of theKeys){ - let fArg = theFuncs[k]; - if('function'===typeof fArg){ - const w = __xMap[k] || toss3("Internal error in __xWrapFuncs: invalid key:",k); - fArg = wasm.installFunction(w.sig, w.f(fArg)); - tgtUninst.push(fArg); + }, + xFinalAndValue: { + signature:'v(p)', contextKey, + callProxy: (callback)=>{ + return (pCtx)=>{ + try{ capi.sqlite3_result_js(pCtx, callback(pCtx)) } + catch(e){ capi.sqlite3_result_error_js(pCtx, e) } + }; + } + }, + xFunc: { + signature:'v(pip)', contextKey, + callProxy: (callback)=>{ + return (pCtx, argc, pArgv)=>{ + try{ + capi.sqlite3_result_js( + pCtx, + callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) + ); + }catch(e){ + //console.error('xFunc() caught:',e); + capi.sqlite3_result_error_js(pCtx, e); + } + }; + } + }, + xDestroy: { + signature:'v(p)', contextKey, + //Arguable: a well-behaved destructor doesn't require a proxy. + callProxy: (callback)=>{ + return (pVoid)=>{ + try{ callback(pVoid) } + catch(e){ console.error("UDF xDestroy method threw:",e) } + }; } - rc.push(fArg); } - return rc; - }; + })/*__cfProxy*/; + + const __sqlite3CreateFunction = wasm.xWrap( + "sqlite3_create_function_v2", "int", [ + "sqlite3*", "string"/*funcName*/, "int"/*nArg*/, + "int"/*eTextRep*/, "*"/*pApp*/, + new wasm.xWrap.FuncPtrAdapter({name: 'xFunc', ...__cfProxy.xFunc}), + new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}), + new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}), + new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy}) + ] + ); + + const __sqlite3CreateWindowFunction = wasm.xWrap( + "sqlite3_create_window_function", "int", [ + "sqlite3*", "string"/*funcName*/, "int"/*nArg*/, + "int"/*eTextRep*/, "*"/*pApp*/, + new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}), + new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}), + new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}), + new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}), + new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy}) + ] + ); /* Documented in the api object's initializer. */ capi.sqlite3_create_function_v2 = function f( @@ -709,26 +712,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } - /* Wrap the callbacks in a WASM-bound functions... */ - const uninstall = [/*funcs to uninstall on error*/]; - let rc; try{ - const funcArgs = __xWrapFuncs(['xFunc','xStep','xFinal','xDestroy'], - {xFunc, xStep, xFinal, xDestroy}, - uninstall); - rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep, - pApp, ...funcArgs); + return __sqlite3CreateFunction(pDb, funcName, nArg, eTextRep, + pApp, xFunc, xStep, xFinal, xDestroy); }catch(e){ console.error("sqlite3_create_function_v2() setup threw:",e); - for(let v of uninstall){ - wasm.uninstallFunction(v); - } - rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR, - "Creation of UDF threw: "+e.message); + return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); } - return rc; }; + /* Documented in the api object's initializer. */ capi.sqlite3_create_function = function f( pDb, funcName, nArg, eTextRep, pApp, xFunc, xStep, xFinal @@ -744,8 +737,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ pDb, funcName, nArg, eTextRep, pApp, xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**) xFinal, //void (*xFinal)(sqlite3_context*) - xValue, //void (*xFinal)(sqlite3_context*) - xInverse,//void (*xStep)(sqlite3_context*,int,sqlite3_value**) + xValue, //void (*xValue)(sqlite3_context*) + xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**) xDestroy //void (*xDestroy)(void*) ){ if( f.length!==arguments.length ){ @@ -755,24 +748,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){ return __errEncoding(pDb); } - /* Wrap the callbacks in a WASM-bound functions... */ - const uninstall = [/*funcs to uninstall on error*/]; - let rc; try{ - const funcArgs = __xWrapFuncs(['xStep','xFinal','xValue','xInverse','xDestroy'], - {xStep, xFinal, xValue, xInverse, xDestroy}, - uninstall); - rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep, - pApp, ...funcArgs); + return __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep, + pApp, xStep, xFinal, xValue, + xInverse, xDestroy); }catch(e){ console.error("sqlite3_create_window_function() setup threw:",e); - for(let v of uninstall){ - wasm.uninstallFunction(v); - } - rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR, - "Creation of UDF threw: "+e.message); + return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); } - return rc; }; /** A _deprecated_ alias for capi.sqlite3_result_js() which diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index de7500a020..26c44cf1a6 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1496,7 +1496,7 @@ self.WhWasmUtilInstaller = function(target){ types are indeterminate, whereas the LHS values will be WASM-compatible values by the time this is called. */ - convertArg(v,argIndex,argv){ + convertArg(v,argv,argIndex){ toss("AbstractArgAdapter must be subclassed."); } }; @@ -1541,24 +1541,38 @@ self.WhWasmUtilInstaller = function(target){ context. This mode is the default if bindScope is _not_ set but a property named contextKey (described below) is. + - callProxy (function): if set, this must be a function which + will act as a proxy for any "converted" JS function. It is + passed the being-converted function value and must return + either that function or a function which acts on its + behalf. The returned function will be the one which gets + installed into the WASM function table. The proxy must perform + any required argument conversion (noting that it will be called + from C code, so will receive C-format arguments) before passing + them on to the being-converted function. Whether or not the + proxy itself must return a value depends on the context. If it + does, it must be a WASM-friendly value, as it will be returning + from a call made from native code. + - contextKey (function): is only used if bindScope is 'context' or if bindScope is not set and this function is, in which case - 'context' is assumed. This function gets passed - (argIndex,argv), where argIndex is the index of _this_ function - pointer in its _wrapping_ function's arguments and argv is the - _current_ still-being-xWrap()-processed args array. All - arguments to the left of argIndex will have been processed by - xWrap() by the time this is called. argv[argIndex] will be the - value the user passed in to the xWrap()'d function for the - argument this FuncPtrAdapter is mapped to. Arguments to the - right of argv[argIndex] will not yet have been converted before - this is called. The function must return a key which uniquely + 'context' is assumed. This function gets bound to this object, + so its "this" is this object. It gets passed (argv,argIndex), + where argIndex is the index of _this_ function pointer in its + _wrapping_ function's arguments and argv is the _current_ + still-being-xWrap()-processed args array. All arguments to the + left of argIndex will have been processed by xWrap() by the + time this is called. argv[argIndex] will be the value the user + passed in to the xWrap()'d function for the argument this + FuncPtrAdapter is mapped to. Arguments to the right of + argv[argIndex] will not yet have been converted before this is + called. The function must return a key which uniquely identifies this function mapping context for _this_ FuncPtrAdapter instance (other instances are not considered), taking into account that C functions often take some sort of state object as one or more of their arguments. As an example, if the xWrap()'d function takes `(int,T*,functionPtr,X*)` and - this FuncPtrAdapter is the argv[2]nd arg, contextKey(2,argv) + this FuncPtrAdapter is the argv[2]nd arg, contextKey(argv,2) might return 'T@'+argv[1], or even just argv[1]. Note, however, that the (X*) argument will not yet have been processed by the time this is called and should not be used as @@ -1570,7 +1584,7 @@ self.WhWasmUtilInstaller = function(target){ use their pointers in the key because most C-strings in this constellation are transient. - Yes, that ^^^ is a bit awkward, but it's what we have. + Yes, that ^^^ is quite awkward, but it's what we have. The constructor only saves the above state for later, and does not actually bind any functions. Its convertArg() method is @@ -1598,6 +1612,8 @@ self.WhWasmUtilInstaller = function(target){ if( ('singleton'===this.bindScope) ) this.singleton = []; else this.singleton = undefined; //console.warn("FuncPtrAdapter()",opt,this); + this.callProxy = (opt.callProxy instanceof Function) + ? opt.callProxy : undefined; } static bindScopes = [ @@ -1605,7 +1621,7 @@ self.WhWasmUtilInstaller = function(target){ ]; /* Dummy impl. Overwritten per-instance as needed. */ - contextKey(argIndex,argv){ + contextKey(argv,argIndex){ return this; } @@ -1638,14 +1654,16 @@ self.WhWasmUtilInstaller = function(target){ See the parent class's convertArg() docs for details on what exactly the 2nd and 3rd arguments are. */ - convertArg(v,argIndex,argv){ + convertArg(v,argv,argIndex){ //console.warn("FuncPtrAdapter.convertArg()",this.signature,this.transient,v); let pair = this.singleton; if(!pair && this.isContext){ - pair = this.contextMap(this.contextKey(argIndex, argv)); + pair = this.contextMap(this.contextKey(argv,argIndex)); } if(pair && pair[0]===v) return pair[1]; if(v instanceof Function){ + /* Install a WASM binding and return its pointer. */ + if(this.callProxy) v = this.callProxy(v); const fp = __installFunction(v, this.signature, this.isTransient); if(pair){ /* Replace existing stashed mapping */ @@ -1660,10 +1678,10 @@ self.WhWasmUtilInstaller = function(target){ }else if(target.isPtr(v) || null===v || undefined===v){ if(pair && pair[1] && pair[1]!==v){ /* uninstall stashed mapping and replace stashed mapping with v. */ - //console.warn("FuncPtrAdapter is uninstalling function", this.contextKey(argIndex,argv),v); + //console.warn("FuncPtrAdapter is uninstalling function", this.contextKey(argv,argIndex),v); try{target.uninstallFunction(pair[1])} catch(e){/*ignored*/} - pair[0] = pair[1] = (v || 0); + pair[0] = pair[1] = (v | 0); } return v || 0; }else{ @@ -1897,17 +1915,20 @@ self.WhWasmUtilInstaller = function(target){ The public interface of argument adapters is that they take ONE argument and return a (possibly) converted result for it. The passing-on of arguments after the first is an - internal impl. detail for the sake of AbstractArgAdapter, and - not to be relied on or documented for other cases. The fact - that this is how AbstractArgAdapter.convertArgs() gets its 2nd+ - arguments, and how FuncPtrAdapter.contextKey() gets its - args, is also an implementation detail and subject to - change. i.e. the public interface of 1 argument is stable. - The fact that any arguments may be passed in after that one, - and what those arguments are, is _not_ part of the public - interface and is _not_ stable. + internal implementation detail for the sake of + AbstractArgAdapter, and not to be relied on or documented + for other cases. The fact that this is how + AbstractArgAdapter.convertArgs() gets its 2nd+ arguments, + and how FuncPtrAdapter.contextKey() gets its args, is also + an implementation detail and subject to change. i.e. the + public interface of 1 argument is stable. The fact that any + arguments may be passed in after that one, and what those + arguments are, is _not_ part of the public interface and is + _not_ stable. */ - for(const i in args) args[i] = cxw.convertArgNoCheck(argTypes[i], args[i], i, args); + for(const i in args) args[i] = cxw.convertArgNoCheck( + argTypes[i], args[i], args, i + ); return cxw.convertResultNoCheck(resultType, xf.apply(null,args)); }finally{ target.scopedAllocPop(scope); diff --git a/manifest b/manifest index f514b0cc1e..2c24cd9701 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\ssignature\sfor\sJS\sfunctions,\sas\sopposed\sto\sfunction\spointers,\spassed\sto\ssqlite3_exec(),\seliminating\sthe\ssuperfluous\sinitial\stwo\sarguments.\sUpdate\srelated\stests\sto\sdemonstrate\sboth\sfunction-passing\sapproaches. -D 2022-12-25T10:22:27.506 +C Enhance\ssqlite3.wasm.xWrap.FuncPtrAdapter\sto\sbe\sable\sto\shandle\ssqlite3_create_function()\sand\sfriends\sand\sreimplement\sthose\sbindings\sto\suse\sthis\sfeature\s(this\swill\salso\ssimplify\scertain\ssession\sAPI\sbindings).\sInteral\sAPI\schanges\sonly\swith\sno\sclient-side\sbreakage. +D 2022-12-25T12:51:53.541 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 72f1ed1d60db62e18cf752c5871bc7c21cfef9258d9c81e61c830914c3f7da91 +F ext/wasm/api/sqlite3-api-glue.js 4114cbd92818eda90bffb9cf3f181a4c1eb50521c95a3ea6d4e0bbc552901ffb F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b F ext/wasm/api/sqlite3-api-prologue.js a27762fd1ed2576897026f28a748a69edcdcc53ef79f46cead5e4446dc949763 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 700fb1b702986522d2177fe8247bfbab3040e82cb4f6c35e929c4c85fbd7ffc5 +F ext/wasm/common/whwasmutil.js 46e1ae432eda14ade6c84318c257917dd86755cb0bfa329d989522e057adff6e F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1 -R 57b44198d665feb79b35a3b3cc62df00 +P e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b +R 942325294903c7f082d03ed59c06bba6 U stephan -Z fa52e396693ed4ebb322eeecdf80849b +Z 9f06406b1eaa13fb27bb0e5cf658bbb6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aca2994565..59d0c24513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b \ No newline at end of file +7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d \ No newline at end of file From 7015aa9f4957c3131c8bc814c81c4c5d2dea8f89 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 14:04:06 +0000 Subject: [PATCH 028/165] Add missing sqlite3_context_db_handle() JS binding. Reimplement sqlite3_set_authorizer() and sqlite3_set_auxdata() JS bindings to take advantage of [7f9ace1b11a67]. Teach FuncPtrAdapter to emit a console.warn() message if it is invoked after the library is bootstrapped, the goal being to inform users that it's an internal API and should not be invoked from client-side code. FossilOrigin-Name: 8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 1 + ext/wasm/api/sqlite3-api-glue.js | 114 ++++++++++---------- ext/wasm/api/sqlite3-api-prologue.js | 1 + ext/wasm/api/sqlite3-wasm.c | 12 ++- ext/wasm/common/whwasmutil.js | 7 ++ ext/wasm/tester1.c-pp.js | 1 + manifest | 22 ++-- manifest.uuid | 2 +- 8 files changed, 83 insertions(+), 77 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 75e5ea3da1..47a7e4a062 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -29,6 +29,7 @@ _sqlite3_column_value _sqlite3_compileoption_get _sqlite3_compileoption_used _sqlite3_complete +_sqlite3_context_db_handle _sqlite3_create_collation _sqlite3_create_collation_v2 _sqlite3_create_function diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 9066b3431c..85c549ae3e 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -82,7 +82,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "sqlite3*", new wasm.xWrap.FuncPtrAdapter({ signature: 'i(pi)', - contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] + contextKey: (argv,argIndex)=>argv[0/* sqlite3* */] }), "*" ]], @@ -103,6 +103,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_compileoption_get", "string", "int"], ["sqlite3_compileoption_used", "int", "string"], ["sqlite3_complete", "int", "string:flexible"], + ["sqlite3_context_db_handle", "sqlite3*", "sqlite3_context*"], + /* sqlite3_create_function(), sqlite3_create_function_v2(), and sqlite3_create_window_function() use hand-written bindings to simplify handling of their function-type arguments. */ @@ -154,16 +156,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ for those, depending on how their SQL argument is provided. */ /* sqlite3_randomness() uses a hand-written wrapper to extend the range of supported argument types. */ - [ - "sqlite3_progress_handler", undefined, [ - "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({ - name: 'xProgressHandler', - signature: 'i(p)', - bindScope: 'context', - contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] - }), "*" - ] - ], + ["sqlite3_progress_handler", undefined, [ + "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({ + name: 'xProgressHandler', + signature: 'i(p)', + bindScope: 'context', + contextKey: (argv,argIndex)=>argv[0/* sqlite3* */] + }), "*" + ]], ["sqlite3_realloc", "*","*","int"], ["sqlite3_reset", "int", "sqlite3_stmt*"], ["sqlite3_result_blob", undefined, "sqlite3_context*", "*", "int", "*"], @@ -179,7 +179,34 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_result_subtype", undefined, "sqlite3_value*", "int"], ["sqlite3_result_text", undefined, "sqlite3_context*", "string", "int", "*"], ["sqlite3_result_zeroblob", undefined, "sqlite3_context*", "int"], - ["sqlite3_set_auxdata", undefined, "sqlite3_context*", "int", "*", "*"/* => v(*) */], + ["sqlite3_set_authorizer", "int", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: "sqlite3_set_authorizer::xAuth", + signature: "i(pi"+"ssss)", + contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/], + callProxy: (callback)=>{ + return (pV, iCode, s0, s1, s2, s3)=>{ + try{ + s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1); + s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3); + return callback(pV, iCode, s0, s1, s2, s3) || 0; + }catch(e){ + return e.resultCode || capi.SQLITE_ERROR; + } + } + } + }), + "*"/*pUserData*/ + ]], + ["sqlite3_set_auxdata", undefined, [ + "sqlite3_context*", "int", "*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'xDestroyAuxData', + signature: 'v(*)', + contextKey: (argv, argIndex)=>argv[0/* sqlite3_context* */] + }) + ]], ["sqlite3_shutdown", undefined], ["sqlite3_sourceid", "string"], ["sqlite3_sql", "string", "sqlite3_stmt*"], @@ -196,12 +223,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "sqlite3*", "string", "string", "string", "**", "**", "*", "*", "*"], ["sqlite3_total_changes", "int", "sqlite3*"], - ["sqlite3_trace_v2", "int", "sqlite3*", "int", - new wasm.xWrap.FuncPtrAdapter({ - name: 'sqlite3_trace_v2::callback', - signature: 'i(ippp)', - contextKey: (argv,argIndex)=>'sqlite3@'+argv[0] - }), "*"], + ["sqlite3_trace_v2", "int", [ + "sqlite3*", "int", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_trace_v2::callback', + signature: 'i(ippp)', + contextKey: (argv,argIndex)=>argv[0/* sqlite3* */] + }), + "*" + ]], ["sqlite3_txn_state", "int", ["sqlite3*","string"]], /* Note that sqlite3_uri_...() have very specific requirements for their first C-string arguments, so we cannot perform any value @@ -267,8 +297,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_result_int64", undefined, "*", "i64"], ["sqlite3_result_zeroblob64", "int", "*", "i64"], ["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"], - /* sqlite3_set_authorizer() requires a hand-written binding for - string conversions, so is defined elsewhere. */ ["sqlite3_set_last_insert_rowid", undefined, ["sqlite3*", "i64"]], ["sqlite3_status64", "int", "int", "*", "*", "int"], ["sqlite3_total_changes64", "i64", ["sqlite3*"]], @@ -500,8 +528,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ {/* Bindings for sqlite3_create_collation[_v2]() */ // contextKey() impl for wasm.xWrap.FuncPtrAdapter const contextKey = (argv,argIndex)=>{ - return 'argv['+argIndex+']:sqlite3@'+argv[0]+ - ':'+wasm.cstrToJs(argv[1]).toLowerCase() + return 'argv['+argIndex+']:'+argv[0/* sqlite3* */]+ + ':'+wasm.cstrToJs(argv[1/* collation name */]).toLowerCase() }; const __sqlite3CreateCollationV2 = wasm.xWrap( 'sqlite3_create_collation_v2', 'int', [ @@ -581,11 +609,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ `(char**)` arguments to arrays of strings... */ let aNames; const cbwrap = function(pVoid, nCols, pColVals, pColNames){ - let rc = capi.SQLITE_ERROR; try { const aVals = wasm.cArgvToJs(nCols, pColVals); if(!aNames) aNames = wasm.cArgvToJs(nCols, pColNames); - rc = callback(aVals, aNames) | 0; + return callback(aVals, aNames) | 0; }catch(e){ /* If we set the db error state here, the higher-level exec() call replaces it with its own, so we have no way @@ -593,11 +620,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ must not propagate exceptions through the C API. Though we make an effort to report OOM here, sqlite3_exec() translates that into SQLITE_ABORT as well. */ - rc = (e instanceof sqlite3.WasmAllocError) - ? capi.SQLITE_NOMEM - : (e.resultCode || capi.SQLITE_ERROR); + return e.resultCode || capi.SQLITE_ERROR; } - return rc; }; let rc; try{ @@ -617,7 +641,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ const contextKey = function(argv,argIndex){ return ( - 'sqlite3@'+argv[0] + argv[0/* sqlite3* */] +':'+argIndex +':'+wasm.cstrToJs(argv[1]).toLowerCase() ) @@ -941,37 +965,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_bind_text/blob()*/ - {/* sqlite3_set_authorizer() */ - const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [ - "sqlite3*", - new wasm.xWrap.FuncPtrAdapter({ - name: "sqlite3_set_authorizer::xAuth", - signature: "i(pi"+"ssss)", - contextKey: (argIndex, argv)=>argv[0/*(sqlite3*)*/] - }), - "*" - ]); - capi.sqlite3_set_authorizer = function(pDb, xAuth, pUserData){ - if(3!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_set_authorizer', 3); - if(xAuth instanceof Function){ - const xProxy = xAuth; - /* Create a proxy which will receive the C-strings from WASM - and convert them to JS strings for the client-supplied - function. */ - xAuth = function(pV, iCode, s0, s1, s2, s3){ - try{ - s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1); - s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3); - return xProxy(pV, iCode, s0, s1, s2, s3) || 0; - }catch(e){ - return util.sqlite3_wasm_db_error(pDb, e); - } - }; - } - return __ssa(pDb, xAuth, pUserData); - }; - }/* sqlite3_set_authorizer() */ - {/* sqlite3_config() */ /** Wraps a small subset of the C API's sqlite3_config() options. @@ -1190,4 +1183,5 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } }/*pKvvfs*/ + wasm.xWrap.FuncPtrAdapter.warnOnUse = true; }); diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index e207fc194d..7804c04589 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -405,6 +405,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( }else{ super("Allocation failed."); } + this.resultCode = capi.SQLITE_NOMEM; this.name = 'WasmAllocError'; } }; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index f2bf5fef1e..5c9b533184 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -323,11 +323,13 @@ SQLITE_WASM_KEEP int sqlite3_wasm_pstack_quota(void){ */ SQLITE_WASM_KEEP int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ - if( 0!=zMsg ){ - const int nMsg = sqlite3Strlen30(zMsg); - sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); - }else{ - sqlite3ErrorWithMsg(db, err_code, NULL); + if( db!=0 ){ + if( 0!=zMsg ){ + const int nMsg = sqlite3Strlen30(zMsg); + sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); + }else{ + sqlite3ErrorWithMsg(db, err_code, NULL); + } } return err_code; } diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 26c44cf1a6..8e18586120 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1598,6 +1598,11 @@ self.WhWasmUtilInstaller = function(target){ xArg.FuncPtrAdapter = class FuncPtrAdapter extends AbstractArgAdapter { constructor(opt) { super(opt); + if(xArg.FuncPtrAdapter.warnOnUse){ + console.warn('xArg.FuncPtrAdapter is an internal-only API', + 'and is not intended to be invoked from', + 'client-level code. Invoked with:',opt); + } this.signature = opt.signature; if(!opt.bindScope && (opt.contextKey instanceof Function)){ opt.bindScope = 'context'; @@ -1616,6 +1621,8 @@ self.WhWasmUtilInstaller = function(target){ ? opt.callProxy : undefined; } + static warnOnUse = false; + static bindScopes = [ 'transient', 'context', 'singleton' ]; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 2314dae2d3..a9b29729b8 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1625,6 +1625,7 @@ self.sqlite3InitModule = sqlite3InitModule; db.createFunction("bar", { arity: -1, xFunc: (pCx,...args)=>{ + T.assert(db.pointer === capi.sqlite3_context_db_handle(pCx)); let rc = 0; for(const v of args) rc += v; return rc; diff --git a/manifest b/manifest index 2c24cd9701..ce22b98bdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\ssqlite3.wasm.xWrap.FuncPtrAdapter\sto\sbe\sable\sto\shandle\ssqlite3_create_function()\sand\sfriends\sand\sreimplement\sthose\sbindings\sto\suse\sthis\sfeature\s(this\swill\salso\ssimplify\scertain\ssession\sAPI\sbindings).\sInteral\sAPI\schanges\sonly\swith\sno\sclient-side\sbreakage. -D 2022-12-25T12:51:53.541 +C Add\smissing\ssqlite3_context_db_handle()\sJS\sbinding.\sReimplement\ssqlite3_set_authorizer()\sand\ssqlite3_set_auxdata()\sJS\sbindings\sto\stake\sadvantage\sof\s[7f9ace1b11a67].\sTeach\sFuncPtrAdapter\sto\semit\sa\sconsole.warn()\smessage\sif\sit\sis\sinvoked\safter\sthe\slibrary\sis\sbootstrapped,\sthe\sgoal\sbeing\sto\sinform\susers\sthat\sit's\san\sinternal\sAPI\sand\sshould\snot\sbe\sinvoked\sfrom\sclient-side\scode. +D 2022-12-25T14:04:06.021 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile ffe0e9818a3b6b36c85a1d10dab76b220a8f5cd83439c62e50223a7970b3d68a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 4c7788042196cecab32f87d8e4965c183fea59037603888059f244b1752babcc +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 7e0468ad0294786da90b2062043288f734a65243a458a541f2f880a785be0bb9 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,16 +503,16 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 4114cbd92818eda90bffb9cf3f181a4c1eb50521c95a3ea6d4e0bbc552901ffb +F ext/wasm/api/sqlite3-api-glue.js ef838f43483e8bfd4ccb5a01feb227198b0f69d40120dc33c805b6c39eb2c36d F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b -F ext/wasm/api/sqlite3-api-prologue.js a27762fd1ed2576897026f28a748a69edcdcc53ef79f46cead5e4446dc949763 +F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 313489816e1733a10ece74a92cbea65d3ee241eb07d98088e96258cc211c9719 +F ext/wasm/api/sqlite3-wasm.c 325ca43b982ef608243493c42249ba4e6b2e549f7cbd9b332e2f7ee8227d2ae3 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 46e1ae432eda14ade6c84318c257917dd86755cb0bfa329d989522e057adff6e +F ext/wasm/common/whwasmutil.js de2871d66b786a5272a345ccf48e56ec74b12b1e228cc218160109aac8bbfced F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js e75daf4e82ce9c9506d165544b6052403802dd1bcf3f4f06fa6084b8520fb549 +F ext/wasm/tester1.c-pp.js 47190277040a6163716c02d11930dc4f028d44a6fcdacb10303010f239ce0a6c F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b -R 942325294903c7f082d03ed59c06bba6 +P 7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d +R f078a5b2f216a35fd658583197af5c35 U stephan -Z 9f06406b1eaa13fb27bb0e5cf658bbb6 +Z 83e66bae6539242de70262c0ffddff2b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 59d0c24513..9f257ff602 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d \ No newline at end of file +8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b \ No newline at end of file From 3494ec15e574fe752dbbca78cf2d21156f7da68b Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 15:14:10 +0000 Subject: [PATCH 029/165] Update the session-related JS bindings to account for today's internal API changes. FossilOrigin-Name: be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 --- ext/wasm/api/sqlite3-api-glue.js | 39 +++++++++++++++++++------------- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index fc5e2823d6..91be75b81f 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -317,16 +317,23 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ // Add session/changeset APIs... if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ /* ACHTUNG: 2022-12-23: the session/changeset API bindings are - COMPLETELY UNTESTED. Additionally, the callback-taking APIs - have a shortcoming which will make using those which take - string-type arguments more painful than it should be. How best - to resolve that, such that we can perform the same type conversions - as we do when binding in "the other direction," is as yet - undetermined. + COMPLETELY UNTESTED. */ + /** + FuncPtrAdapter options for session-related callbacks with the + native signature "i(ps)". This proxy converts the 2nd argument + from a C string to a JS string before passing the arguments on + to the client-provided JS callback. */ - /* TODO: we need hand-written wrappers to adapt callbacks which - take string arguments. Or we need to find a way to do this sort - of reverse-binding which includes type conversions. */ + const __ipsProxy = { + signature: 'i(ps)', + callProxy:(callback)=>{ + return (p,s)=>{ + try{return callback(p, wasm.cstrToJs(s)) | 0} + catch(e){return e.resultCode || capi.SQLITE_ERROR} + } + } + }; + wasm.bindingSignatures.int64.push(...[ ['sqlite3changegroup_add', 'int', ['sqlite3_changegroup*', 'int', 'void*']], ['sqlite3changegroup_add_strm', 'int', [ @@ -349,7 +356,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -363,7 +370,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }), 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -373,7 +380,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply_v2', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -384,7 +391,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3changeset_apply_v2', 'int', [ 'sqlite3*', 'int', 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -398,7 +405,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }), 'void*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', bindScope: 'transient' + name: 'xFilter', bindScope: 'transient', ...__ipsProxy }), new wasm.xWrap.FuncPtrAdapter({ name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' @@ -487,8 +494,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ['sqlite3session_table_filter', undefined, [ 'sqlite3_session*', new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', signature: 'i(ps)', - contextKey: (argIndex,argv)=>argv[0/* (sqlite3_session*) */] + name: 'xFilter', ...__ipsProxy, + contextKey: (argv,argIndex)=>argv[0/* (sqlite3_session*) */] }), '*' ]] diff --git a/manifest b/manifest index 8b68df83ea..841003c821 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\swasm-session-api\sbranch. -D 2022-12-25T14:13:52.379 +C Update\sthe\ssession-related\sJS\sbindings\sto\saccount\sfor\stoday's\sinternal\sAPI\schanges. +D 2022-12-25T15:14:10.329 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 171657a8c758cba72d903b20b42c72a523915ca03c8d652339bf41f5f1da2f09 +F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6cdb036d8e8c5ddb0c6578aeefe318e74d7a90228e57b9f9047057dae3252963 8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b -R 81fe514e1af16b08edf276165dc4ebe1 +P 7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 +R dfeb1d551c8453a8d3a795c7dad85108 U stephan -Z 68ce3f310d94edded8b970aa4257758a +Z 7d17f1f03aff9dd128f571dc7f5c762d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 29353fc4d9..e8d64eedfa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 \ No newline at end of file +be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 \ No newline at end of file From 8b5a5ef030182a54e4752043c5e6bdf2db6d6951 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 15:28:19 +0000 Subject: [PATCH 030/165] Add the address of the associated db handle to the sqlite3_trace_v2() output originating from sqlite3.oo1.DB's trace flag. FossilOrigin-Name: 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 --- ext/wasm/api/sqlite3-api-oo1.js | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 16f5f00b15..1823773dec 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -72,7 +72,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.installFunction('i(ippp)', function(t,c,p,x){ if(capi.SQLITE_TRACE_STMT===t){ // x == SQL, p == sqlite3_stmt* - console.log("SQL TRACE #"+(++this.counter), + console.log("SQL TRACE #"+(++this.counter)+' via sqlite3@'+c+':', wasm.cstrToJs(x)); } }.bind({counter: 0})); @@ -161,7 +161,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ capi.sqlite3_extended_result_codes(pDb, 1); if(flagsStr.indexOf('t')>=0){ capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, - __dbTraceToConsole, 0); + __dbTraceToConsole, pDb); } }catch( e ){ if( pDb ) capi.sqlite3_close_v2(pDb); diff --git a/manifest b/manifest index 841003c821..ef1186091e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssession-related\sJS\sbindings\sto\saccount\sfor\stoday's\sinternal\sAPI\schanges. -D 2022-12-25T15:14:10.329 +C Add\sthe\saddress\sof\sthe\sassociated\sdb\shandle\sto\sthe\ssqlite3_trace_v2()\soutput\soriginating\sfrom\ssqlite3.oo1.DB's\strace\sflag. +D 2022-12-25T15:28:19.113 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f -F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b +F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f8f1acd82be7dc2eb2147d96299b1b443e86774dfe0b0a8d32669a0500fc9c6 -R dfeb1d551c8453a8d3a795c7dad85108 +P be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 +R a0850be6b0937570f1f7baa999a6a514 U stephan -Z 7d17f1f03aff9dd128f571dc7f5c762d +Z c3cd9380ad4a7408eae4565bc713502d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e8d64eedfa..82c4e532fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 \ No newline at end of file +0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 \ No newline at end of file From 031ee6b9dabe7711c5ec7cfd91f7bef20cb7432e Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 16:20:05 +0000 Subject: [PATCH 031/165] Remove duplicated JS binding of sqlite3changeset_apply_v2(). FossilOrigin-Name: 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 --- ext/wasm/api/sqlite3-api-glue.js | 10 ---------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 91be75b81f..7d4d888d76 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -388,16 +388,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'void*', '**', 'int*', 'int' ]], - ['sqlite3changeset_apply_v2', 'int', [ - 'sqlite3*', 'int', 'void*', - new wasm.xWrap.FuncPtrAdapter({ - name: 'xFilter', bindScope: 'transient', ...__ipsProxy - }), - new wasm.xWrap.FuncPtrAdapter({ - name: 'xConflict', signature: 'i(pip)', bindScope: 'transient' - }), - 'void*', '**', 'int*', 'int' - ]], ['sqlite3changeset_apply_v2_strm', 'int', [ 'sqlite3*', new wasm.xWrap.FuncPtrAdapter({ diff --git a/manifest b/manifest index ef1186091e..93bd6a9a83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\saddress\sof\sthe\sassociated\sdb\shandle\sto\sthe\ssqlite3_trace_v2()\soutput\soriginating\sfrom\ssqlite3.oo1.DB's\strace\sflag. -D 2022-12-25T15:28:19.113 +C Remove\sduplicated\sJS\sbinding\sof\ssqlite3changeset_apply_v2(). +D 2022-12-25T16:20:05.864 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js f22d7bc226b6b8b1f8399cdcc547ad3289b49f39722c91301fe07e529148a94f +F ext/wasm/api/sqlite3-api-glue.js fe8a0c30d906e4f14be26a2abdad5d84aa901eeb594f76c8050cb4df4f746a5d F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be63944d4114f53f2dab65bc6c1b85f4766a4ea14ee7b2690acde239a2a0bf54 -R a0850be6b0937570f1f7baa999a6a514 +P 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 +R 7b14429320eea0000f7897f56a599155 U stephan -Z c3cd9380ad4a7408eae4565bc713502d +Z c6f737ca9a33ea9873dd8c76d61cfde2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 82c4e532fb..8c99823063 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 \ No newline at end of file +2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 \ No newline at end of file From 73bf9d5fed1ed13e4bfdd4c338115e3dd4e95c6b Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 17:09:34 +0000 Subject: [PATCH 032/165] Replace the "manual" implementation of sqlite3.capi.sqlite3_exec() with a briefer "automated" one via the [7f9ace1b11a67] feature addition. Minor code-adjacent internal cleanups. FossilOrigin-Name: 4888957baf18c6763f959fbba998a74156ff656368779107f502b926e9e9d949 --- ext/wasm/api/sqlite3-api-glue.js | 72 ++++++++++------------------ ext/wasm/api/sqlite3-api-prologue.js | 2 +- ext/wasm/common/whwasmutil.js | 17 +++---- manifest | 16 +++---- manifest.uuid | 2 +- 5 files changed, 45 insertions(+), 64 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 85c549ae3e..dcdc179428 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -127,9 +127,32 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_errmsg", "string", "sqlite3*"], ["sqlite3_error_offset", "int", "sqlite3*"], ["sqlite3_errstr", "string", "int"], - /*["sqlite3_exec", "int", "sqlite3*", "string", "*", "*", "**" - Handled seperately to perform translation of the callback - into a WASM-usable one. ],*/ + ["sqlite3_exec", "int", [ + "sqlite3*", "string:flexible", + new wasm.xWrap.FuncPtrAdapter({ + signature: 'i(pipp)', + bindScope: 'transient', + callProxy: (callback)=>{ + let aNames; + return (pVoid, nCols, pColVals, pColNames)=>{ + try { + const aVals = wasm.cArgvToJs(nCols, pColVals); + if(!aNames) aNames = wasm.cArgvToJs(nCols, pColNames); + return callback(aVals, aNames) | 0; + }catch(e){ + /* If we set the db error state here, the higher-level + exec() call replaces it with its own, so we have no way + of reporting the exception message except the console. We + must not propagate exceptions through the C API. Though + we make an effort to report OOM here, sqlite3_exec() + translates that into SQLITE_ABORT as well. */ + return e.resultCode || capi.SQLITE_ERROR; + } + } + } + }), + "*", "**" + ]], ["sqlite3_expanded_sql", "string", "sqlite3_stmt*"], ["sqlite3_extended_errcode", "int", "sqlite3*"], ["sqlite3_extended_result_codes", "int", "sqlite3*", "int"], @@ -591,49 +614,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_create_collation() and friends*/ - {/* Special-case handling of sqlite3_exec() */ - const __exec = wasm.xWrap("sqlite3_exec", "int", - ["sqlite3*", "string:flexible", - new wasm.xWrap.FuncPtrAdapter({ - signature: 'i(pipp)', - bindScope: 'transient' - }), "*", "**"]); - /* Documented in the api object's initializer. */ - capi.sqlite3_exec = function f(pDb, sql, callback, pVoid, pErrMsg){ - if(f.length!==arguments.length){ - return __dbArgcMismatch(pDb,"sqlite3_exec",f.length); - }else if(!(callback instanceof Function)){ - return __exec(pDb, sql, callback, pVoid, pErrMsg); - } - /* Wrap the callback in a WASM-bound function and convert the callback's - `(char**)` arguments to arrays of strings... */ - let aNames; - const cbwrap = function(pVoid, nCols, pColVals, pColNames){ - try { - const aVals = wasm.cArgvToJs(nCols, pColVals); - if(!aNames) aNames = wasm.cArgvToJs(nCols, pColNames); - return callback(aVals, aNames) | 0; - }catch(e){ - /* If we set the db error state here, the higher-level - exec() call replaces it with its own, so we have no way - of reporting the exception message except the console. We - must not propagate exceptions through the C API. Though - we make an effort to report OOM here, sqlite3_exec() - translates that into SQLITE_ABORT as well. */ - return e.resultCode || capi.SQLITE_ERROR; - } - }; - let rc; - try{ - rc = __exec(pDb, sql, cbwrap, pVoid, pErrMsg); - }catch(e){ - rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR, - "Error running exec(): "+e); - } - return rc; - }; - }/*sqlite3_exec() proxy*/; - {/* Special-case handling of sqlite3_create_function_v2() and sqlite3_create_window_function(). */ /** diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 7804c04589..307ab43f5e 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1419,7 +1419,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( wasm.dealloc(pData); } }; - + if( util.isUIThread() ){ /* Features specific to the main window thread... */ diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 8e18586120..7a7747ef35 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1604,18 +1604,19 @@ self.WhWasmUtilInstaller = function(target){ 'client-level code. Invoked with:',opt); } this.signature = opt.signature; - if(!opt.bindScope && (opt.contextKey instanceof Function)){ - opt.bindScope = 'context'; - }else if(FuncPtrAdapter.bindScopes.indexOf(opt.bindScope)<0){ + if(opt.contextKey instanceof Function){ + this.contextKey = opt.contextKey; + if(!opt.bindScope) opt.bindScope = 'context'; + } + this.bindScope = opt.bindScope + || toss("FuncPtrAdapter options requires a bindScope (explicit or implied)."); + if(FuncPtrAdapter.bindScopes.indexOf(opt.bindScope)<0){ toss("Invalid options.bindScope ("+opt.bindMod+") for FuncPtrAdapter. "+ "Expecting one of: ("+FuncPtrAdapter.bindScopes.join(', ')+')'); } - this.bindScope = opt.bindScope; - if(opt.contextKey) this.contextKey = opt.contextKey /*else inherit one*/; this.isTransient = 'transient'===this.bindScope; this.isContext = 'context'===this.bindScope; - if( ('singleton'===this.bindScope) ) this.singleton = []; - else this.singleton = undefined; + this.singleton = ('singleton'===this.bindScope) ? [] : undefined; //console.warn("FuncPtrAdapter()",opt,this); this.callProxy = (opt.callProxy instanceof Function) ? opt.callProxy : undefined; @@ -1918,7 +1919,7 @@ self.WhWasmUtilInstaller = function(target){ const scope = target.scopedAllocPush(); try{ /* - Maintenance reminder re. arguments passed to convertArgs(): + Maintenance reminder re. arguments passed to convertArg(): The public interface of argument adapters is that they take ONE argument and return a (possibly) converted result for it. The passing-on of arguments after the first is an diff --git a/manifest b/manifest index ce22b98bdd..2ccb290a22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\ssqlite3_context_db_handle()\sJS\sbinding.\sReimplement\ssqlite3_set_authorizer()\sand\ssqlite3_set_auxdata()\sJS\sbindings\sto\stake\sadvantage\sof\s[7f9ace1b11a67].\sTeach\sFuncPtrAdapter\sto\semit\sa\sconsole.warn()\smessage\sif\sit\sis\sinvoked\safter\sthe\slibrary\sis\sbootstrapped,\sthe\sgoal\sbeing\sto\sinform\susers\sthat\sit's\san\sinternal\sAPI\sand\sshould\snot\sbe\sinvoked\sfrom\sclient-side\scode. -D 2022-12-25T14:04:06.021 +C Replace\sthe\s"manual"\simplementation\sof\ssqlite3.capi.sqlite3_exec()\swith\sa\sbriefer\s"automated"\sone\svia\sthe\s[7f9ace1b11a67]\sfeature\saddition.\sMinor\scode-adjacent\sinternal\scleanups. +D 2022-12-25T17:09:34.880 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js ef838f43483e8bfd4ccb5a01feb227198b0f69d40120dc33c805b6c39eb2c36d +F ext/wasm/api/sqlite3-api-glue.js 7e8bbf3a987b7220db8220045c4d575744bac9faa0d6bc2924ce93e89d1176e3 F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b -F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 +F ext/wasm/api/sqlite3-api-prologue.js 30dc037af2f33e773ea6c5e0362a44f1de69e174d729dd33e8049cf2d0676fa2 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js de2871d66b786a5272a345ccf48e56ec74b12b1e228cc218160109aac8bbfced +F ext/wasm/common/whwasmutil.js 02d04a086a16130e97dc2a04555686dc19c48bd41842a96934737365678ca839 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d -R f078a5b2f216a35fd658583197af5c35 +P 8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b +R 2df92a51136615b2a37539ac7dcbebf7 U stephan -Z 83e66bae6539242de70262c0ffddff2b +Z 9719f2c37cbd201ac24a565e7ff0d05e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9f257ff602..4a9e2d7bae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b \ No newline at end of file +4888957baf18c6763f959fbba998a74156ff656368779107f502b926e9e9d949 \ No newline at end of file From 7a5544b958e04f8cf99e27353aa3982b28728a5e Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 17:12:24 +0000 Subject: [PATCH 033/165] Add tests confirming that JS sqlite3_exec()'s SQL argument participates in the 'string:flexible' type conversion. FossilOrigin-Name: 926d0c61a391c601adc2804d3fdaa8b667ae2abd565939cddfa12d5151b098f8 --- ext/wasm/tester1.c-pp.js | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index a9b29729b8..c7fa893954 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1923,7 +1923,10 @@ self.sqlite3InitModule = sqlite3InitModule; }); try { T.assert(wasm.isPtr(pCb)); - rc = capi.sqlite3_exec(db, "select a, a*2 from foo.bar", pCb, 0, 0); + rc = capi.sqlite3_exec( + db, new TextEncoder('utf-8').encode("select a, a*2 from foo.bar"), + pCb, 0, 0 + ); T.assert(0===rc) .assert(3===rowCount) .assert(2===colCount); @@ -1933,7 +1936,7 @@ self.sqlite3InitModule = sqlite3InitModule; // Demonstrate that an OOM result does not propagate through sqlite3_exec()... rc = capi.sqlite3_exec( - db, "select a, a*2 from foo.bar", function(aVals, aNames){ + db, ["select a,"," a*2 from foo.bar"], (aVals, aNames)=>{ sqlite3.WasmAllocError.toss("just testing"); }, 0, 0 ); diff --git a/manifest b/manifest index 2ccb290a22..827df733d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sthe\s"manual"\simplementation\sof\ssqlite3.capi.sqlite3_exec()\swith\sa\sbriefer\s"automated"\sone\svia\sthe\s[7f9ace1b11a67]\sfeature\saddition.\sMinor\scode-adjacent\sinternal\scleanups. -D 2022-12-25T17:09:34.880 +C Add\stests\sconfirming\sthat\sJS\ssqlite3_exec()'s\sSQL\sargument\sparticipates\sin\sthe\s'string:flexible'\stype\sconversion. +D 2022-12-25T17:12:24.209 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 47190277040a6163716c02d11930dc4f028d44a6fcdacb10303010f239ce0a6c +F ext/wasm/tester1.c-pp.js 1396611f11d75fc124ffb7600dc05d3ad7cc25885c4a8f842b9291ea9e0b8abd F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e3d4f6294037396e388ec21abb18bf0201a6bec6ff004730cc5d11b705a6d2b -R 2df92a51136615b2a37539ac7dcbebf7 +P 4888957baf18c6763f959fbba998a74156ff656368779107f502b926e9e9d949 +R cfaf4d7e6ebced21987511a642eb3cd6 U stephan -Z 9719f2c37cbd201ac24a565e7ff0d05e +Z c6e0af2cef9d9cd33fe188241216b8ea # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4a9e2d7bae..47997d8d14 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4888957baf18c6763f959fbba998a74156ff656368779107f502b926e9e9d949 \ No newline at end of file +926d0c61a391c601adc2804d3fdaa8b667ae2abd565939cddfa12d5151b098f8 \ No newline at end of file From 7d59d90a5b9dc56f5a19fe9a24be2500af664013 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 20:05:11 +0000 Subject: [PATCH 034/165] Add sqlite3.wasm.irSizeof() and extend certain allocation functions to make use of it. FossilOrigin-Name: 1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 --- ext/wasm/api/sqlite3-api-prologue.js | 17 +++++++++++++++-- ext/wasm/common/whwasmutil.js | 19 +++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 7804c04589..aafe1dd08b 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1020,12 +1020,20 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( to the memory. On error, returns throws a WasmAllocError. The memory must eventually be released using restore(). + If n is a string, it must be a WASM "IR" value in the set + accepted by wasm.irSizeof(), which is mapped to the size of + that data type. If passed a string not in that set, it throws a + WasmAllocError. + This method always adjusts the given value to be a multiple of 8 bytes because failing to do so can lead to incorrect results when reading and writing 64-bit values from/to the WASM heap. Similarly, the returned address is always 8-byte aligned. */ - alloc: (n)=>{ + alloc: function(n){ + if('string'===typeof n && !(n = wasm.irSizeof(n))){ + WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")"); + } return wasm.exports.sqlite3_wasm_pstack_alloc(n) || WasmAllocError.toss("Could not allocate",n, "bytes from the pstack."); @@ -1035,6 +1043,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( returns the addresses as an array of n element, each holding the address of one chunk. + sz may optionally be an IR string accepted by wasm.irSizeof(). + Throws a WasmAllocError if allocation fails. Example: @@ -1043,7 +1053,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const [p1, p2, p3] = wasm.pstack.allocChunks(3,4); ``` */ - allocChunks: (n,sz)=>{ + allocChunks: function(n,sz){ + if('string'===typeof sz && !(sz = wasm.irSizeof(sz))){ + WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")"); + } const mem = wasm.pstack.alloc(n * sz); const rc = []; let i = 0, offset = 0; diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index c296a946b9..e6f32abfae 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -246,6 +246,25 @@ self.WhWasmUtilInstaller = function(target){ cache.utf8Decoder = new TextDecoder(); cache.utf8Encoder = new TextEncoder('utf-8'); + /** + For the given IR-like string in the set ('i8', 'i16', 'i32', + 'f32', 'float', 'i64', 'f64', 'double', '*'), or any string value + ending in '*', returns the sizeof for that value + (target.ptrSizeof in the latter case). For any other value, it + returns the undefined value. + */ + target.irSizeof = (n)=>{ + switch(n){ + case 'i8': return 1; + case 'i16': return 2; + case 'i32': case 'f32': case 'float': return 4; + case 'i64': case 'f64': case 'double': return 8; + case '*': return ptrSizeof; + default: + return (''+n).endsWith('*') ? ptrSizeof : undefined; + } + }; + /** If (cache.heapSize !== cache.memory.buffer.byteLength), i.e. if the heap has grown since the last call, updates cache.HEAPxyz. diff --git a/manifest b/manifest index 93bd6a9a83..8ff3505e92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sduplicated\sJS\sbinding\sof\ssqlite3changeset_apply_v2(). -D 2022-12-25T16:20:05.864 +C Add\ssqlite3.wasm.irSizeof()\sand\sextend\scertain\sallocation\sfunctions\sto\smake\suse\sof\sit. +D 2022-12-25T20:05:11.134 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a9578430388 F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js fe8a0c30d906e4f14be26a2abdad5d84aa901eeb594f76c8050cb4df4f746a5d F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 -F ext/wasm/api/sqlite3-api-prologue.js 4ffe2b80742e2fcf44de6174bfb2981ff26ea0d1fe505bb511ffe0d9ac8fe6d0 +F ext/wasm/api/sqlite3-api-prologue.js 72e2b66daf1f5ea7b6a8477c4fe86493925a067cfa0b156a339589e653446920 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 495cdffe8a6107608412ee57cdad79267f14a56e6b7825b9dc30c8ccfb02c87b +F ext/wasm/common/whwasmutil.js a94f776bd3afcfc73283aad2bb0821ddf8e77f687a0d7ee84d14d2a138d78636 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0a36568c5a3db56a8ad23fd8abc672c5a7f1abed55984d902842ffd3ebb816e8 -R 7b14429320eea0000f7897f56a599155 +P 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 +R 63f0c28ba499a3e86a80a83d5b02806d U stephan -Z c6f737ca9a33ea9873dd8c76d61cfde2 +Z e2479a6e1c7cf91263ea3378ad83cfc4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8c99823063..f118531ec6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 \ No newline at end of file +1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 \ No newline at end of file From 9d61db1944238d35ee00cefe0b4bfb7ac291e36b Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 20:22:20 +0000 Subject: [PATCH 035/165] Add basic session API JS tests. FossilOrigin-Name: 64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc --- ext/wasm/tester1.c-pp.js | 88 +++++++++++++++++++++++++++++++++++++--- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index a9b29729b8..9655cd8572 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1010,7 +1010,12 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(P.quota >= 4096) .assert(remaining === P.quota) .mustThrowMatching(()=>P.alloc(0), isAllocErr) - .mustThrowMatching(()=>P.alloc(-1), isAllocErr); + .mustThrowMatching(()=>P.alloc(-1), isAllocErr) + .mustThrowMatching( + ()=>P.alloc('i33'), + (e)=>e instanceof sqlite3.WasmAllocError + ); + ; let p1 = P.alloc(12); T.assert(p1 === stack - 16/*8-byte aligned*/) .assert(P.pointer === p1); @@ -1029,7 +1034,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(P.pointer === stack); try { - const [p1, p2, p3] = P.allocChunks(3,4); + const [p1, p2, p3] = P.allocChunks(3,'i32'); T.assert(P.pointer === stack-16/*always rounded to multiple of 8*/) .assert(p2 === p1 + 4) .assert(p3 === p2 + 4); @@ -1143,7 +1148,7 @@ self.sqlite3InitModule = sqlite3InitModule; } } }; - + T.assert(wasm.isPtr(db.pointer)) .mustThrowMatching(()=>db.pointer=1, /read-only/) .assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1)) @@ -1183,7 +1188,7 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(0 === rc); const stack = wasm.pstack.pointer; try { - const [pCur, pHi] = wasm.pstack.allocChunks(2,8); + const [pCur, pHi] = wasm.pstack.allocChunks(2,'i64'); rc = capi.sqlite3_db_status(this.db, capi.SQLITE_DBSTATUS_LOOKASIDE_USED, pCur, pHi, 0); T.assert(0===rc); @@ -1729,7 +1734,7 @@ self.sqlite3InitModule = sqlite3InitModule; // sqlite3_result_xyz() and return undefined. Both are // functionally equivalent. } - }); + }); T.assert(18===db.selectValue('select summerN(1,8,9), summerN(2,3,4)')); T.mustThrowMatching(()=>{ db.createFunction('nope',{ @@ -1856,7 +1861,6 @@ self.sqlite3InitModule = sqlite3InitModule; .assert('select 2;' === rc[1]) .assert('-- empty\n; select 3' === rc[2] /* Strange but true. */); - T.mustThrowMatching(()=>{ db.exec({sql:'', returnValue: 'nope'}); }, /^Invalid returnValue/); @@ -2632,6 +2636,78 @@ self.sqlite3InitModule = sqlite3InitModule; }/*OPFS util sanity checks*/) ;/* end OPFS tests */ + T.g('Session API') + .t({ + name: 'Session API sanity checks', + predicate: ()=>!!capi.sqlite3changegroup_add, + test: function(sqlite3){ + const db1 = new sqlite3.oo1.DB(), db2 = new sqlite3.oo1.DB(); + const sqlInit = [ + "create table t(rowid INTEGER PRIMARY KEY,a,b); ", + "insert into t(rowid,a,b) values", + "(1,'a1','b1'),", + "(2,'a2','b2'),", + "(3,'a3','b3');" + ].join(''); + db1.exec(sqlInit); + db2.exec(sqlInit); + T.assert(3 === db1.selectValue("select count(*) from t")) + .assert('b3' === db1.selectValue('select b from t where rowid=3')); + const stackPtr = wasm.pstack.pointer; + try{ + let ppOut = wasm.pstack.allocPtr(); + let rc = capi.sqlite3session_create(db1, "main", ppOut); + T.assert(0===rc); + let pSession = wasm.peekPtr(ppOut); + T.assert(pSession && wasm.isPtr(pSession)); + if(1){ + capi.sqlite3session_table_filter(pSession, (pCtx, tbl)=>{ + T.assert('t' === tbl).assert( 99 === pCtx ); + return 1; + }, 99); + }else{ + rc = capi.sqlite3session_attach(pSession, "t"); + T.assert( 0 === rc ); + } + db1.exec([ + "update t set b='bTwo' where rowid=2;", + "update t set a='aThree' where rowid=3;", + "delete from t where rowid=1;", + "insert into t(rowid,a,b) values(4,'a4','b4')" + ]); + T.assert('bTwo' === db1.selectValue("select b from t where rowid=2")) + .assert(undefined === db1.selectValue('select a from t where rowid=1')) + .assert('b4' === db1.selectValue('select b from t where rowid=4')); + + let pnChanges = wasm.pstack.alloc('i32'), + ppChanges = wasm.pstack.allocPtr(); + rc = capi.sqlite3session_changeset(pSession, pnChanges, ppChanges); + T.assert( 0 === rc ); + capi.sqlite3session_delete(pSession); + pSession = 0; + const pChanges = wasm.peekPtr(ppChanges), + nChanges = wasm.peek32(pnChanges); + T.assert( pChanges && wasm.isPtr( pChanges ) ).assert( nChanges > 0 ); + pnChanges = ppChanges = 0; + //log("pnChanges =", pnChanges, wasm.peek32(pnChanges), '@', pChanges); + rc = capi.sqlite3changeset_apply( + db2, nChanges, pChanges, 0, (pCtx, eConflict, pIter)=>{ + return pCtx ? 1 : 0 + }, 1 + ); + wasm.dealloc( pChanges ); + T.assert( 0 === rc ) + .assert( 3 === db2.selectValue('select count(*) from t')) + .assert( 'b4' === db2.selectValue('select b from t where rowid=4') ); + }finally{ + wasm.pstack.restore(stackPtr); + db1.close(); + db2.close(); + } + } + }) + ;/*end of session API group*/; + //////////////////////////////////////////////////////////////////////// log("Loading and initializing sqlite3 WASM module..."); if(!self.sqlite3InitModule && !isUIThread()){ diff --git a/manifest b/manifest index 8ff3505e92..4de86c1325 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3.wasm.irSizeof()\sand\sextend\scertain\sallocation\sfunctions\sto\smake\suse\sof\sit. -D 2022-12-25T20:05:11.134 +C Add\sbasic\ssession\sAPI\sJS\stests. +D 2022-12-25T20:22:20.918 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 47190277040a6163716c02d11930dc4f028d44a6fcdacb10303010f239ce0a6c +F ext/wasm/tester1.c-pp.js a690f82c02d2b0531bad264054a276d09d274487fd1f8aac6bab24f7cfedaa6f F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2e8336b6e1cba89dbcc11d6316e39c929bf8b018a18b92efc232abd47e0a5cc6 -R 63f0c28ba499a3e86a80a83d5b02806d +P 1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 +R e7bca9ee95dfee32728e67001af3a1d6 U stephan -Z e2479a6e1c7cf91263ea3378ad83cfc4 +Z 1d08930538afdb25a0799e1e3a67b3c1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f118531ec6..3d55a2ae03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cbc7b1875e8611b9db7a747b4c9499501450deaf90c929d212511837d6f72b6 \ No newline at end of file +64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc \ No newline at end of file From 9f1adb8c12bdaf9e57e9d938c4af7c04c8d06ee0 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 22:44:13 +0000 Subject: [PATCH 036/165] Add sqlite3.oo1.DB.selectValues(). Correct a logic error which could cause DB.selectValue(), DB.selectArray(), and DB.selectObject() to fail to finalize a statement if a call to bind() failed. Add more session API tests. FossilOrigin-Name: 6adc8a10146190037d55d3328d2f78aa5233559f88d4aa70fbbf9e10145b9b6c --- ext/wasm/api/sqlite3-api-oo1.js | 45 +++++++++++------ ext/wasm/tester1.c-pp.js | 85 +++++++++++++++++++++++++++------ manifest | 15 +++--- manifest.uuid | 2 +- 4 files changed, 109 insertions(+), 38 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 1823773dec..b4d76e5737 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -463,22 +463,20 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; /** - Internal impl of the DB.selectArray() and + Internal impl of the DB.selectValue(), selectArray(), and selectObject() methods. */ - const __selectFirstRow = (db, sql, bind, getArg)=>{ - let stmt, rc; + const __selectFirstRow = (db, sql, bind, ...getArgs)=>{ + const stmt = db.prepare(sql); try { - stmt = db.prepare(sql).bind(bind); - if(stmt.step()) rc = stmt.get(getArg); + return stmt.bind(bind).step() ? stmt.get(...getArgs) : undefined; }finally{ - if(stmt) stmt.finalize(); + stmt.finalize(); } - return rc; }; /** - Internal impl of the DB.selectArrays() and + Internal impl of the DB.selectvalues(), selectArrays(), and selectObjects() methods. */ const __selectAll = @@ -1083,15 +1081,31 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Throws on error (e.g. malformed SQL). */ selectValue: function(sql,bind,asType){ - let stmt, rc; + return __selectFirstRow(this, sql, bind, 0, asType); + }, + + /** + Runs the given query and returns an array of the values from + the first result column of each row of the result set. The 2nd + argument is an optional value for use in a single-argument call + to Stmt.bind(). The 3rd argument may be any value suitable for + use as the 2nd argument to Stmt.get(). If a 3rd argument is + desired but no bind data are needed, pass `undefined` for the 2nd + argument. + + If there are no result rows, an empty array is returned. + */ + selectValues: function(sql,bind,asType){ + const stmt = this.prepare(sql), rc = []; try { - stmt = this.prepare(sql).bind(bind); - if(stmt.step()) rc = stmt.get(0,asType); + stmt.bind(bind); + while(stmt.step()) rc.push(stmt.get(0,asType)); }finally{ - if(stmt) stmt.finalize(); + stmt.finalize(); } return rc; }, + /** Prepares the given SQL, step()s it one time, and returns an array containing the values of the first result row. If it has @@ -1147,7 +1161,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Returns the number of currently-opened Stmt handles for this db - handle, or 0 if this DB instance is closed. + handle, or 0 if this DB instance is closed. Note that only + handles prepared via this.prepare() are counted, and not + handles prepared using capi.sqlite3_prepare_v3() (or + equivalent). */ openStatementCount: function(){ return this.pointer ? Object.keys(__stmtMap.get(this)).length : 0; @@ -1611,7 +1628,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }, /** Fetches the value from the given 0-based column index of - the current data row, throwing if index is out of range. + the current data row, throwing if index is out of range. Requires that step() has just returned a truthy value, else an exception is thrown. diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index d03acd4cb6..9f32b85eff 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1358,6 +1358,16 @@ self.sqlite3InitModule = sqlite3InitModule; if(wasm.bigIntEnabled){ T.assert(4n===db.changes(false,true)); } + + let vals = db.selectValues('select a from t order by a limit 2'); + T.assert( 2 === vals.length ) + .assert( 1===vals[0] && 3===vals[1] ); + vals = db.selectValues('select a from t order by a limit ?', + 2, capi.SQLITE_TEXT); + T.assert( 2 === vals.length ) + .assert( '1'===vals[0] && '3'===vals[1] ); + vals = undefined; + let blob = db.selectValue("select b from t where a='blob'"); T.assert(blob instanceof Uint8Array). assert(0x68===blob[0] && 0x69===blob[1]); @@ -2639,6 +2649,7 @@ self.sqlite3InitModule = sqlite3InitModule; }/*OPFS util sanity checks*/) ;/* end OPFS tests */ + //////////////////////////////////////////////////////////////////////// T.g('Session API') .t({ name: 'Session API sanity checks', @@ -2664,15 +2675,10 @@ self.sqlite3InitModule = sqlite3InitModule; T.assert(0===rc); let pSession = wasm.peekPtr(ppOut); T.assert(pSession && wasm.isPtr(pSession)); - if(1){ - capi.sqlite3session_table_filter(pSession, (pCtx, tbl)=>{ - T.assert('t' === tbl).assert( 99 === pCtx ); - return 1; - }, 99); - }else{ - rc = capi.sqlite3session_attach(pSession, "t"); - T.assert( 0 === rc ); - } + capi.sqlite3session_table_filter(pSession, (pCtx, tbl)=>{ + T.assert('t' === tbl).assert( 99 === pCtx ); + return 1; + }, 99); db1.exec([ "update t set b='bTwo' where rowid=2;", "update t set a='aThree' where rowid=3;", @@ -2681,8 +2687,27 @@ self.sqlite3InitModule = sqlite3InitModule; ]); T.assert('bTwo' === db1.selectValue("select b from t where rowid=2")) .assert(undefined === db1.selectValue('select a from t where rowid=1')) - .assert('b4' === db1.selectValue('select b from t where rowid=4')); + .assert('b4' === db1.selectValue('select b from t where rowid=4')) + .assert(3 === db1.selectValue('select count(*) from t')); + const testSessionEnable = false; + if(testSessionEnable){ + rc = capi.sqlite3session_enable(pSession, 0); + T.assert( 0 === rc ) + .assert( 0 === capi.sqlite3session_enable(pSession, -1) ); + db1.exec("delete from t where rowid=2;"); + rc = capi.sqlite3session_enable(pSession, 1); + T.assert( rc > 0 ) + .assert( capi.sqlite3session_enable(pSession, -1) > 0 ) + .assert(undefined === db1.selectValue('select a from t where rowid=2')); + }else{ + warn("sqlite3session_enable() tests disabled due to unexpected results.", + "(Possibly a tester misunderstanding, as opposed to a bug.)"); + } + let db1Count = db1.selectValue("select count(*) from t"); + T.assert( db1Count === (testSessionEnable ? 2 : 3) ); + + /* Capture changeset and destroy session. */ let pnChanges = wasm.pstack.alloc('i32'), ppChanges = wasm.pstack.allocPtr(); rc = capi.sqlite3session_changeset(pSession, pnChanges, ppChanges); @@ -2691,9 +2716,29 @@ self.sqlite3InitModule = sqlite3InitModule; pSession = 0; const pChanges = wasm.peekPtr(ppChanges), nChanges = wasm.peek32(pnChanges); - T.assert( pChanges && wasm.isPtr( pChanges ) ).assert( nChanges > 0 ); + T.assert( pChanges && wasm.isPtr( pChanges ) ) + .assert( nChanges > 0 ); + + /* Revert db1 via an inverted changeset, but keep pChanges + and nChanges for application to db2. */ + rc = capi.sqlite3changeset_invert( nChanges, pChanges, pnChanges, ppChanges ); + T.assert( 0 === rc ); + rc = capi.sqlite3changeset_apply( + db1, wasm.peek32(pnChanges), wasm.peekPtr(ppChanges), 0, (pCtx, eConflict, pIter)=>{ + return 1; + }, 0 + ); + T.assert( 0 === rc ); + wasm.dealloc( wasm.peekPtr(ppChanges) ); pnChanges = ppChanges = 0; - //log("pnChanges =", pnChanges, wasm.peek32(pnChanges), '@', pChanges); + T.assert('b2' === db1.selectValue("select b from t where rowid=2")) + .assert('a1' === db1.selectValue('select a from t where rowid=1')) + .assert(undefined === db1.selectValue('select b from t where rowid=4')); + db1Count = db1.selectValue("select count(*) from t"); + T.assert(3 === db1Count); + + /* Apply pre-reverted changeset (pChanges, nChanges) to + db2... */ rc = capi.sqlite3changeset_apply( db2, nChanges, pChanges, 0, (pCtx, eConflict, pIter)=>{ return pCtx ? 1 : 0 @@ -2701,15 +2746,25 @@ self.sqlite3InitModule = sqlite3InitModule; ); wasm.dealloc( pChanges ); T.assert( 0 === rc ) - .assert( 3 === db2.selectValue('select count(*) from t')) - .assert( 'b4' === db2.selectValue('select b from t where rowid=4') ); + .assert( 'b4' === db2.selectValue('select b from t where rowid=4') ) + .assert( 'aThree' === db2.selectValue('select a from t where rowid=3') ) + .assert( undefined === db2.selectValue('select b from t where rowid=1') ); + if(testSessionEnable){ + T.assert( (undefined === db2.selectValue('select b from t where rowid=2')), + "But... the session was disabled when rowid=2 was deleted?" ); + log("rowids from db2.t:",db2.selectValues('select rowid from t order by rowid')); + T.assert( 3 === db2.selectValue('select count(*) from t') ); + }else{ + T.assert( 'bTwo' === db2.selectValue('select b from t where rowid=2') ) + .assert( 3 === db2.selectValue('select count(*) from t') ); + } }finally{ wasm.pstack.restore(stackPtr); db1.close(); db2.close(); } } - }) + })/*session API sanity tests*/ ;/*end of session API group*/; //////////////////////////////////////////////////////////////////////// diff --git a/manifest b/manifest index 690055e610..5a0c3e6b92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\swasm-session-api\sbranch\sinto\strunk,\sadding\sthe\ssession\sAPI\sto\sthe\sJS/WASM\scomponents. -D 2022-12-25T20:25:44.871 +C Add\ssqlite3.oo1.DB.selectValues().\sCorrect\sa\slogic\serror\swhich\scould\scause\sDB.selectValue(),\sDB.selectArray(),\sand\sDB.selectObject()\sto\sfail\sto\sfinalize\sa\sstatement\sif\sa\scall\sto\sbind()\sfailed.\sAdd\smore\ssession\sAPI\stests. +D 2022-12-25T22:44:13.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js 594741f7cbff68f0b4a0c1a066bce335146de1124366377292e27d30f9a5f751 -F ext/wasm/api/sqlite3-api-oo1.js ae4f6950913b4703b767f640a533675b45e9e6c462bf01e357cec16bc68943e2 +F ext/wasm/api/sqlite3-api-oo1.js 8fdb63b6a88399e30dee6f80a38923f4ddab84b51002b23c4554bfbcde6ca558 F ext/wasm/api/sqlite3-api-prologue.js 9dfbb41ebc0aadfac9c41ae8d050187af39819fff4e4f22ac6a8a4f3008f722b F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 314e7bdbc73f558cf12c050c5af42f866195ee17bf451d63f7337052fcf44c7a +F ext/wasm/tester1.c-pp.js be6c06b3f1e244cd71c86aa075e532b15737e59c707ab03856a973999747cf46 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,9 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 926d0c61a391c601adc2804d3fdaa8b667ae2abd565939cddfa12d5151b098f8 64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc -R 5a9d5d7e14f03170b616d0bb48ba8894 -T +closed 64e032602cf420851c8029603c76f5512000d1c9a40fa7a545528d69d6d1d4cc Closed\sby\sintegrate-merge. +P dfb8b651fa4faef2d3307a05512cdc479398484c3a59715827179c363861a777 +R 11f4e29f6d9cd2a2b70132c232c1be63 U stephan -Z 42f975ba9994385873d5d768be40b720 +Z 8afaa92daa5954ca91195b5a042039e6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b020053bce..9440d57d5c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfb8b651fa4faef2d3307a05512cdc479398484c3a59715827179c363861a777 \ No newline at end of file +6adc8a10146190037d55d3328d2f78aa5233559f88d4aa70fbbf9e10145b9b6c \ No newline at end of file From 6431f860aee2805999730e7fa7a9758d9789a90a Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 22:49:55 +0000 Subject: [PATCH 037/165] Minor internal API doc correction and extend a test for oo1.DB.selectValues(). FossilOrigin-Name: b7295b1ca700945ae4e89be69f954dce9960e8975664e620898392b2cc78d452 --- ext/wasm/api/sqlite3-api-oo1.js | 4 ++-- ext/wasm/tester1.c-pp.js | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index b4d76e5737..965f7ee93c 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -476,8 +476,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; /** - Internal impl of the DB.selectvalues(), selectArrays(), and - selectObjects() methods. + Internal impl of the DB.selectArrays() and selectObjects() + methods. */ const __selectAll = (db, sql, bind, rowMode)=>db.exec({ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 9f32b85eff..bf4497a3e5 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1362,8 +1362,8 @@ self.sqlite3InitModule = sqlite3InitModule; let vals = db.selectValues('select a from t order by a limit 2'); T.assert( 2 === vals.length ) .assert( 1===vals[0] && 3===vals[1] ); - vals = db.selectValues('select a from t order by a limit ?', - 2, capi.SQLITE_TEXT); + vals = db.selectValues('select a from t order by a limit $L', + {$L:2}, capi.SQLITE_TEXT); T.assert( 2 === vals.length ) .assert( '1'===vals[0] && '3'===vals[1] ); vals = undefined; diff --git a/manifest b/manifest index 5a0c3e6b92..7ec9eca484 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3.oo1.DB.selectValues().\sCorrect\sa\slogic\serror\swhich\scould\scause\sDB.selectValue(),\sDB.selectArray(),\sand\sDB.selectObject()\sto\sfail\sto\sfinalize\sa\sstatement\sif\sa\scall\sto\sbind()\sfailed.\sAdd\smore\ssession\sAPI\stests. -D 2022-12-25T22:44:13.588 +C Minor\sinternal\sAPI\sdoc\scorrection\sand\sextend\sa\stest\sfor\soo1.DB.selectValues(). +D 2022-12-25T22:49:55.364 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js 594741f7cbff68f0b4a0c1a066bce335146de1124366377292e27d30f9a5f751 -F ext/wasm/api/sqlite3-api-oo1.js 8fdb63b6a88399e30dee6f80a38923f4ddab84b51002b23c4554bfbcde6ca558 +F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 9dfbb41ebc0aadfac9c41ae8d050187af39819fff4e4f22ac6a8a4f3008f722b F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js be6c06b3f1e244cd71c86aa075e532b15737e59c707ab03856a973999747cf46 +F ext/wasm/tester1.c-pp.js fba3a4b5f235e5c41d635f6de5acf26133cec5b17078c1114d7212d09bfdbc00 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dfb8b651fa4faef2d3307a05512cdc479398484c3a59715827179c363861a777 -R 11f4e29f6d9cd2a2b70132c232c1be63 +P 6adc8a10146190037d55d3328d2f78aa5233559f88d4aa70fbbf9e10145b9b6c +R ab9bc9eeed21f370b3c130570f9e653a U stephan -Z 8afaa92daa5954ca91195b5a042039e6 +Z c1bfc6c7f86e8bde4952cf14d3251cf0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9440d57d5c..7593c2c512 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6adc8a10146190037d55d3328d2f78aa5233559f88d4aa70fbbf9e10145b9b6c \ No newline at end of file +b7295b1ca700945ae4e89be69f954dce9960e8975664e620898392b2cc78d452 \ No newline at end of file From ec35e92d1d52cbe92a3a283b510a45c8fb03c9d1 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 22:55:45 +0000 Subject: [PATCH 038/165] Rename the new wasm.irSizeof() to sizeofIR() because that seems clearer. FossilOrigin-Name: 49a83ca3ba46d3ae8021fbdd72b48ce9181eea6845fa7bb7aa83b16fad1728be --- ext/wasm/api/sqlite3-api-prologue.js | 8 ++++---- ext/wasm/common/whwasmutil.js | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 9bac704483..ff528feef5 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1021,7 +1021,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( memory must eventually be released using restore(). If n is a string, it must be a WASM "IR" value in the set - accepted by wasm.irSizeof(), which is mapped to the size of + accepted by wasm.sizeofIR(), which is mapped to the size of that data type. If passed a string not in that set, it throws a WasmAllocError. @@ -1031,7 +1031,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( heap. Similarly, the returned address is always 8-byte aligned. */ alloc: function(n){ - if('string'===typeof n && !(n = wasm.irSizeof(n))){ + if('string'===typeof n && !(n = wasm.sizeofIR(n))){ WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")"); } return wasm.exports.sqlite3_wasm_pstack_alloc(n) @@ -1043,7 +1043,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( returns the addresses as an array of n element, each holding the address of one chunk. - sz may optionally be an IR string accepted by wasm.irSizeof(). + sz may optionally be an IR string accepted by wasm.sizeofIR(). Throws a WasmAllocError if allocation fails. @@ -1054,7 +1054,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( ``` */ allocChunks: function(n,sz){ - if('string'===typeof sz && !(sz = wasm.irSizeof(sz))){ + if('string'===typeof sz && !(sz = wasm.sizeofIR(sz))){ WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")"); } const mem = wasm.pstack.alloc(n * sz); diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index bfe66dfb15..9f634d7744 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -253,7 +253,7 @@ self.WhWasmUtilInstaller = function(target){ (target.ptrSizeof in the latter case). For any other value, it returns the undefined value. */ - target.irSizeof = (n)=>{ + target.sizeofIR = (n)=>{ switch(n){ case 'i8': return 1; case 'i16': return 2; diff --git a/manifest b/manifest index 7ec9eca484..11356ed11a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sinternal\sAPI\sdoc\scorrection\sand\sextend\sa\stest\sfor\soo1.DB.selectValues(). -D 2022-12-25T22:49:55.364 +C Rename\sthe\snew\swasm.irSizeof()\sto\ssizeofIR()\sbecause\sthat\sseems\sclearer. +D 2022-12-25T22:55:45.073 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a9578430388 F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js 594741f7cbff68f0b4a0c1a066bce335146de1124366377292e27d30f9a5f751 F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d -F ext/wasm/api/sqlite3-api-prologue.js 9dfbb41ebc0aadfac9c41ae8d050187af39819fff4e4f22ac6a8a4f3008f722b +F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 77aedbe53b05bfe08f4ca52e96d520eb14d792df09e107df6e3d1300de37e02f +F ext/wasm/common/whwasmutil.js 961f190a955b419a795d1ce2136032bf8c0b14f2bda69c2b3263bab5a48f01a9 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6adc8a10146190037d55d3328d2f78aa5233559f88d4aa70fbbf9e10145b9b6c -R ab9bc9eeed21f370b3c130570f9e653a +P b7295b1ca700945ae4e89be69f954dce9960e8975664e620898392b2cc78d452 +R f20b23dc49016616e4537ae3fbf889f2 U stephan -Z c1bfc6c7f86e8bde4952cf14d3251cf0 +Z 2cf153cf91d4387022d8e0a87cff2eb5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7593c2c512..3bc48826d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7295b1ca700945ae4e89be69f954dce9960e8975664e620898392b2cc78d452 \ No newline at end of file +49a83ca3ba46d3ae8021fbdd72b48ce9181eea6845fa7bb7aa83b16fad1728be \ No newline at end of file From 7103801df1049ca96d764d73bd4a42fa21b53273 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 23:45:59 +0000 Subject: [PATCH 039/165] Update JS worker #1 API and related tests for recent API changes. FossilOrigin-Name: d797e183e96e04520636865204c02307b751fdc2949a04587de9259a1733e37b --- ext/wasm/api/sqlite3-api-worker1.js | 18 +++--------------- ext/wasm/api/sqlite3-worker1.js | 3 --- ext/wasm/demo-worker1-promiser.js | 6 ++---- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 14 insertions(+), 31 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.js index 62e2bb9bdf..250b6fcdf7 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.js @@ -158,15 +158,6 @@ bigIntEnabled: bool. True if BigInt support is enabled. - wasmfsOpfsDir: path prefix, if any, _intended_ for use with - WASMFS OPFS persistent storage. - - wasmfsOpfsEnabled: true if persistent storage is enabled in the - current environment. Only files stored under wasmfsOpfsDir - will persist using that mechanism, however. It is legal to use - the non-WASMFS OPFS VFS to open a database via a URI-style - db filename. - vfsList: result of sqlite3.capi.sqlite3_js_vfs_list() } } @@ -449,7 +440,6 @@ sqlite3.initWorker1API = function(){ toss("Throwing because of simulateError flag."); } const rc = Object.create(null); - const pDir = sqlite3.capi.sqlite3_wasmfs_opfs_dir(); let byteArray, pVfs; oargs.vfs = args.vfs; if(isSpecialDbFilename(args.filename)){ @@ -475,15 +465,14 @@ sqlite3.initWorker1API = function(){ e.name+' creating '+args.filename+": "+e.message, { cause: e } - ); + ); }finally{ if(pMem) sqlite3.wasm.dealloc(pMem); } } const db = wState.open(oargs); rc.filename = db.filename; - rc.persistent = (!!pDir && db.filename.startsWith(pDir+'/')) - || !!sqlite3.capi.sqlite3_js_db_uses_vfs(db.pointer, "opfs"); + rc.persistent = !!sqlite3.capi.sqlite3_js_db_uses_vfs(db.pointer, "opfs"); rc.dbId = getDbId(db); rc.vfs = db.dbVfsName(); return rc; @@ -558,11 +547,10 @@ sqlite3.initWorker1API = function(){ 'config-get': function(){ const rc = Object.create(null), src = sqlite3.config; [ - 'wasmfsOpfsDir', 'bigIntEnabled' + 'bigIntEnabled' ].forEach(function(k){ if(Object.getOwnPropertyDescriptor(src, k)) rc[k] = src[k]; }); - rc.wasmfsOpfsEnabled = !!sqlite3.capi.sqlite3_wasmfs_opfs_dir(); rc.version = sqlite3.version; rc.vfsList = sqlite3.capi.sqlite3_js_vfs_list(); rc.opfsEnabled = !!sqlite3.opfs; diff --git a/ext/wasm/api/sqlite3-worker1.js b/ext/wasm/api/sqlite3-worker1.js index 942437908f..4ff19b8880 100644 --- a/ext/wasm/api/sqlite3-worker1.js +++ b/ext/wasm/api/sqlite3-worker1.js @@ -41,9 +41,6 @@ //console.warn("worker1 theJs =",theJs); importScripts(theJs); sqlite3InitModule().then((sqlite3)=>{ - if(sqlite3.capi.sqlite3_wasmfs_opfs_dir){ - sqlite3.capi.sqlite3_wasmfs_opfs_dir(); - } sqlite3.initWorker1API(); }); })(); diff --git a/ext/wasm/demo-worker1-promiser.js b/ext/wasm/demo-worker1-promiser.js index a65cc31b6e..ef955403c5 100644 --- a/ext/wasm/demo-worker1-promiser.js +++ b/ext/wasm/demo-worker1-promiser.js @@ -76,9 +76,7 @@ await wtest('config-get', (ev)=>{ const r = ev.result; log('sqlite3.config subset:', r); - T.assert('boolean' === typeof r.bigIntEnabled) - .assert('string'===typeof r.wasmfsOpfsDir) - .assert('boolean' === typeof r.wasmfsOpfsEnabled); + T.assert('boolean' === typeof r.bigIntEnabled); sqConfig = r; }); logHtml('', @@ -213,7 +211,7 @@ sql: "select 'foo' foo, a bar, 'baz' baz from t limit 2", callback: resultRowTest3, columnNames: [], - rowMode: ':bar' + rowMode: '$bar' }, function(ev){ log("exec() result row:",ev); T.assert(2===resultRowTest3.counter); diff --git a/manifest b/manifest index 11356ed11a..000849c0f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\snew\swasm.irSizeof()\sto\ssizeofIR()\sbecause\sthat\sseems\sclearer. -D 2022-12-25T22:55:45.073 +C Update\sJS\sworker\s#1\sAPI\sand\srelated\stests\sfor\srecent\sAPI\schanges. +D 2022-12-25T23:45:59.277 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -506,7 +506,7 @@ F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c F ext/wasm/api/sqlite3-api-glue.js 594741f7cbff68f0b4a0c1a066bce335146de1124366377292e27d30f9a5f751 F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 -F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f +F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24 @@ -514,7 +514,7 @@ F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasm.c 2bee083def8f832c863d5f0a0fcbff86c236412663c6d3458128db154c0fccc8 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b -F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 +F ext/wasm/api/sqlite3-worker1.js 9d3d3dfc70bff8998c1d8ff6d881cf1c3d52468d635417f02796151fe6b31cd7 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c0779 @@ -528,7 +528,7 @@ F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb0 F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8 F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f -F ext/wasm/demo-worker1-promiser.js b85a2bb1b918db4f09dfa24419241cb3edad7791389425c2505092e9b715017d +F ext/wasm/demo-worker1-promiser.js b99c550763fa792c204e9a7cceadd976004036d9fc3e22fab7051712e30d207d F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js a619adffc98b75b66c633b00f747b856449a134a9a0357909287d80a182d70fa F ext/wasm/dist.make 5523b02e824db5ab8176e3eedc2e709fe1204d8f4d6e52e8321cdf6830114b72 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7295b1ca700945ae4e89be69f954dce9960e8975664e620898392b2cc78d452 -R f20b23dc49016616e4537ae3fbf889f2 +P 49a83ca3ba46d3ae8021fbdd72b48ce9181eea6845fa7bb7aa83b16fad1728be +R 27d11ee0c9b71ea59cc8cc5e957cd154 U stephan -Z 2cf153cf91d4387022d8e0a87cff2eb5 +Z 0d7e78e20bbd0ad5a9524bd13ad13d60 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3bc48826d7..5c6a4eac10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49a83ca3ba46d3ae8021fbdd72b48ce9181eea6845fa7bb7aa83b16fad1728be \ No newline at end of file +d797e183e96e04520636865204c02307b751fdc2949a04587de9259a1733e37b \ No newline at end of file From b87efce2c02fddb34979165326bce1dfe362ea68 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 25 Dec 2022 23:54:16 +0000 Subject: [PATCH 040/165] module-symbols.html: add some missing links to C-side API docs for recently-added JS counterparts. FossilOrigin-Name: 7d4f4e96f33f37b0774cb8df22ed1ef33062534653a4fadf606704b855e28c49 --- ext/wasm/module-symbols.html | 6 ++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ext/wasm/module-symbols.html b/ext/wasm/module-symbols.html index 6298aeb374..85fd3ebb3d 100644 --- a/ext/wasm/module-symbols.html +++ b/ext/wasm/module-symbols.html @@ -133,10 +133,10 @@ The sqlite3.version object exposes the following...

- +

sqlite3_...() Function List

- +

The sqlite3.capi namespace exposes the following sqlite3_...() functions... @@ -223,6 +223,8 @@ sqlite3_compileoption_get: 'www:/c3ref/compileoption_get.html', sqlite3_compileoption_used: 'www:/c3ref/compileoption_get.html', sqlite3_complete: 'www:/c3ref/complete.html', + sqlite3_config: 'www:/c3ref/config.html', + sqlite3_context_db_handle: 'www:/c3ref/context_db_handle.html', sqlite3_create_collation: 'www:/c3ref/create_collation.html', sqlite3_create_collation_v2: 'www:/c3ref/create_collation.html', sqlite3_create_function: 'wasm:/api-c-style.md#sqlite3_create_function', diff --git a/manifest b/manifest index 000849c0f6..ee0e210d84 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sJS\sworker\s#1\sAPI\sand\srelated\stests\sfor\srecent\sAPI\schanges. -D 2022-12-25T23:45:59.277 +C module-symbols.html:\sadd\ssome\smissing\slinks\sto\sC-side\sAPI\sdocs\sfor\srecently-added\sJS\scounterparts. +D 2022-12-25T23:54:16.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F ext/wasm/index-dist.html c806b6005145b71d64240606e9c6e0bf56878ee8829c66fe7486c F ext/wasm/index.html cc8b174ff01be282b399e64b58bdf3c921d7020da5d4e22e88bbbb4a6787a209 F ext/wasm/jaccwabyt/jaccwabyt.js 06f2ef1ad640c26c593def3d960336e9bb789819b920516480895c38ed5f58fa F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb -F ext/wasm/module-symbols.html 573317801087e67c946a157783715d5716e027fcf484918a0c3aae4e627cc93d +F ext/wasm/module-symbols.html ac9a26524f569b5510e2a66f6a04f3ebd66423c5524e28b1ca723ab1997297ae F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06 F ext/wasm/scratchpad-wasmfs-main.js 4c140457f4d6da9d646a49addd91edb6e9ad1643c6c48e3258b5bce24725dc18 F ext/wasm/speedtest1-wasmfs.html 7a301f4f5b6ad4f5d37fd6e7ca03a2f5d5547fd289da60a39075a93d7646d354 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 49a83ca3ba46d3ae8021fbdd72b48ce9181eea6845fa7bb7aa83b16fad1728be -R 27d11ee0c9b71ea59cc8cc5e957cd154 +P d797e183e96e04520636865204c02307b751fdc2949a04587de9259a1733e37b +R 3b62b1c0f38c86ade5b52d8fa8da0f03 U stephan -Z 0d7e78e20bbd0ad5a9524bd13ad13d60 +Z 2778815949abf0646823d20abb172e24 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5c6a4eac10..3640e29800 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d797e183e96e04520636865204c02307b751fdc2949a04587de9259a1733e37b \ No newline at end of file +7d4f4e96f33f37b0774cb8df22ed1ef33062534653a4fadf606704b855e28c49 \ No newline at end of file From 3a8fbc0749b5a1ff5a4d173568bd86e132e5d9ef Mon Sep 17 00:00:00 2001 From: larrybr Date: Mon, 26 Dec 2022 01:44:04 +0000 Subject: [PATCH 041/165] Grammar fixup in comment re SQLITE_TRACE_PROFILE trace event. FossilOrigin-Name: b6dc80cbf63ed521ef8f878fba24b0110d61813763ca7bfbcfb0a145656b300a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ee0e210d84..955f154be8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C module-symbols.html:\sadd\ssome\smissing\slinks\sto\sC-side\sAPI\sdocs\sfor\srecently-added\sJS\scounterparts. -D 2022-12-25T23:54:16.440 +C Grammar\sfixup\sin\scomment\sre\sSQLITE_TRACE_PROFILE\strace\sevent. +D 2022-12-26T01:44:04.994 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -647,7 +647,7 @@ F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 83de67e4857be2866d048c98e93f65461d8a0408ca4ce88fec68ebfe030997ae F src/shell.c.in 01816a1e0eb3a2e9a9a4b11570d68058969c88b2ec5ecaf80c57d6ca1b8d46a4 -F src/sqlite.h.in e752f82b9d71f1d42b259b1900e4b1caf0965e844d756cd5cc91cc2cf45ed925 +F src/sqlite.h.in 7982c691e4647071a6df1ef45e7d704613225259414e153939b0928a9952a1ae F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f F src/sqliteInt.h 98bc12d3191ff4c70e8491b639784c83d577b7177377d4fb344826ac56bae8a8 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d797e183e96e04520636865204c02307b751fdc2949a04587de9259a1733e37b -R 3b62b1c0f38c86ade5b52d8fa8da0f03 -U stephan -Z 2778815949abf0646823d20abb172e24 +P 7d4f4e96f33f37b0774cb8df22ed1ef33062534653a4fadf606704b855e28c49 +R 926f0cd5532702d032b25076c55fd75c +U larrybr +Z 868fbc8bce1667a24be059b48b2f0878 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3640e29800..87df863e5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d4f4e96f33f37b0774cb8df22ed1ef33062534653a4fadf606704b855e28c49 \ No newline at end of file +b6dc80cbf63ed521ef8f878fba24b0110d61813763ca7bfbcfb0a145656b300a \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 91a47f3357..213da4c79a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3288,7 +3288,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** execution of the prepared statement, such as at the start of each ** trigger subprogram. ^The P argument is a pointer to the ** [prepared statement]. ^The X argument is a pointer to a string which -** is the unexpanded SQL text of the prepared statement or an SQL comment +** is the unexpanded SQL text of the prepared statement or an SQL comment ** that indicates the invocation of a trigger. ^The callback can compute ** the same text that would have been returned by the legacy [sqlite3_trace()] ** interface by using the X argument when X begins with "--" and invoking @@ -3298,13 +3298,13 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, **

^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is the estimated of -** the number of nanosecond that the prepared statement took to run. +** X argument points to a 64-bit integer which is approximately +** the number of nanoseconds that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
SQLITE_TRACE_ROW
**
^An SQLITE_TRACE_ROW callback is invoked whenever a prepared -** statement generates a single row of result. +** statement generates a single row of result. ** ^The P argument is a pointer to the [prepared statement] and the ** X argument is unused. ** From 20170adf14bf6e23d17bf1d1eff79a87bd4e2a83 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 11:13:09 +0000 Subject: [PATCH 042/165] Reimplement sqlite3.capi.sqlite3_close_v2() and sqlite3session_delete() as a hand-written bindings so that they can attempt to clean up certain (potentially) FuncPtrAdapter-installed functions before closing. Correct the create-function family of JS-to-function-pointer automated conversions to include the UDF's arity as part of the mapping's key so that (un)binding a UDF to different functions for different arities works (and add tests confirming it). Correct a broken doc link in module-symbols.html. FossilOrigin-Name: 60b262ef0f57b162c2566b12e70685a92afb00b441332ea7a6540fcb188cc7af --- ext/wasm/api/sqlite3-api-glue.js | 74 +++++++++++++++++++++++++++++--- ext/wasm/common/whwasmutil.js | 30 +++++++++++-- ext/wasm/module-symbols.html | 2 +- ext/wasm/tester1.c-pp.js | 40 ++++++++++++++++- manifest | 20 ++++----- manifest.uuid | 2 +- 6 files changed, 146 insertions(+), 22 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 8a0d8147f0..94554e0b55 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -87,7 +87,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "*" ]], ["sqlite3_busy_timeout","int", "sqlite3*", "int"], - ["sqlite3_close_v2", "int", "sqlite3*"], + /*[sqlite3_close_v2() is implemented by hand to perform some + extra work. "sqlite3_close_v2", "int", "sqlite3*"],*/ ["sqlite3_changes", "int", "sqlite3*"], ["sqlite3_clear_bindings","int", "sqlite3_stmt*"], ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/], @@ -489,7 +490,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ]], ['sqlite3session_config', 'int', ['int', 'void*']], ['sqlite3session_create', 'int', ['sqlite3*', 'string', '**']], - ['sqlite3session_delete', undefined, ['sqlite3_session*']], + //sqlite3session_delete() is bound manually ['sqlite3session_diff', 'int', ['sqlite3_session*', 'string', 'string', '**']], ['sqlite3session_enable', 'int', ['sqlite3_session*', 'int']], ['sqlite3session_indirect', 'int', ['sqlite3_session*', 'int']], @@ -730,6 +731,67 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); }; + {/* Binding of sqlite3_close_v2() */ + const __sqlite3CloseV2 = wasm.xWrap("sqlite3_close_v2", "int", "sqlite3*"); + capi.sqlite3_close_v2 = function(pDb){ + if(1!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_close_v2', 1); + if(pDb){ + /* + We do this as a basic attempt at freeing up certain + automatically-installed WASM function bindings, as those may + otherwise leak. Installing NULL functions in the C API will + remove those bindings. The FuncPtrAdapter which sits between + us and the C API will also treat that as an opportunity to + wasm.uninstallFunction() any WASM function bindings it has + installed for pDb. + + This does not catch all such bindings: those which map to + both a db handle and a separate key (e.g. collation sequence + name or UDF name) cannot be unmapped here because we don't + have the other parts of the mapping key. It's also possible + for clients to call wasm.exports.sqlite3_close_v2() + directly, bypassing this cleanup altogether. i.e. this is + not a silver bullet, just an "honest effort." + + Perhaps we can add some code to sqlite3-wasm.c which can + walk through the UDF and collation names to help us free up + those auto-converted functions, too. Functions are more + complicated because a given function may have multiple + mappings for different arities. + + The issue being addressed here is covered at: + + https://sqlite.org/wasm/doc/trunk/api-c-style.md#convert-func-ptr + */ + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + try{capi.sqlite3_busy_handler(pDb, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_progress_handler(pDb, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_trace_v2(pDb, 0, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_set_authorizer(pDb, 0, 0)} catch(e){/*ignored*/} + } + return __sqlite3CloseV2(pDb); + }; + }/*sqlite3_close_v2()*/ + + if(capi.sqlite3session_table_filter){ + const __sqlite3SessionDelete = wasm.xWrap( + 'sqlite3session_delete', undefined, ['sqlite3_session*'] + ); + capi.sqlite3session_delete = function(pSession){ + if(1!==arguments.length){ + return __dbArgcMismatch(pDb, 'sqlite3session_delete', 1); + /* Yes, we're returning a value from a void function. That seems + like the lesser evil compared to not maintaining arg-count + consistency as we do with other similar bindings. */ + } + else if(pSession){ + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + capi.sqlite3session_table_filter(pSession, 0, 0); + } + __sqlite3SessionDelete(pSession); + }; + } + {/* Bindings for sqlite3_create_collation[_v2]() */ // contextKey() impl for wasm.xWrap.FuncPtrAdapter const contextKey = (argv,argIndex)=>{ @@ -798,13 +860,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ {/* Special-case handling of sqlite3_create_function_v2() and sqlite3_create_window_function(). */ - /** - FuncPtrAdapter for contextKey() for sqlite3_create_function(). - */ + /** FuncPtrAdapter for contextKey() for sqlite3_create_function() + and friends. */ const contextKey = function(argv,argIndex){ return ( argv[0/* sqlite3* */] - +':'+argIndex + +':'+(argv[2/*number of UDF args*/] < 0 ? -1 : argv[2]) + +':'+argIndex/*distinct for each xAbc callback type*/ +':'+wasm.cstrToJs(argv[1]).toLowerCase() ) }; diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 9f634d7744..df401c8fee 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1499,7 +1499,7 @@ self.WhWasmUtilInstaller = function(target){ */ const AbstractArgAdapter = class { constructor(opt){ - this.name = opt.name; + this.name = opt.name || 'unnamed adapter'; } /** Gets called via xWrap() to "convert" v to whatever type @@ -1651,8 +1651,21 @@ self.WhWasmUtilInstaller = function(target){ ? opt.callProxy : undefined; } + /** If true, the constructor emits a warning. The intent is that + this be set to true after bootstrapping of the higher-level + client library is complete, to warn downstream clients that + they shouldn't be relying on this implemenation detail which + does not have a stable interface. */ static warnOnUse = false; + /** If true, convertArg() will FuncPtrAdapter.debugOut() when it + (un)installs a function binding to/from WASM. + */ + static debugFuncInstall = false; + + /** Function used for debug output. */ + static debugOut = console.debug.bind(console); + static bindScopes = [ 'transient', 'context', 'singleton' ]; @@ -1692,7 +1705,7 @@ self.WhWasmUtilInstaller = function(target){ exactly the 2nd and 3rd arguments are. */ convertArg(v,argv,argIndex){ - //console.warn("FuncPtrAdapter.convertArg()",this.signature,this.transient,v); + //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.signature,this.transient,v); let pair = this.singleton; if(!pair && this.isContext){ pair = this.contextMap(this.contextKey(argv,argIndex)); @@ -1702,9 +1715,17 @@ self.WhWasmUtilInstaller = function(target){ /* Install a WASM binding and return its pointer. */ if(this.callProxy) v = this.callProxy(v); const fp = __installFunction(v, this.signature, this.isTransient); + if(FuncPtrAdapter.debugFuncInstall){ + FuncPtrAdapter.debugOut("FuncPtrAdapter installed", this, + this.contextKey(argv,argIndex), '@'+fp, v); + } if(pair){ /* Replace existing stashed mapping */ if(pair[1]){ + if(FuncPtrAdapter.debugFuncInstall){ + FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this, + this.contextKey(argv,argIndex), '@'+pair[1], v); + } try{target.uninstallFunction(pair[1])} catch(e){/*ignored*/} } @@ -1715,7 +1736,10 @@ self.WhWasmUtilInstaller = function(target){ }else if(target.isPtr(v) || null===v || undefined===v){ if(pair && pair[1] && pair[1]!==v){ /* uninstall stashed mapping and replace stashed mapping with v. */ - //console.warn("FuncPtrAdapter is uninstalling function", this.contextKey(argv,argIndex),v); + if(FuncPtrAdapter.debugFuncInstall){ + FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this, + this.contextKey(argv,argIndex), '@'+pair[1], v); + } try{target.uninstallFunction(pair[1])} catch(e){/*ignored*/} pair[0] = pair[1] = (v | 0); diff --git a/ext/wasm/module-symbols.html b/ext/wasm/module-symbols.html index 85fd3ebb3d..ff9c9769dc 100644 --- a/ext/wasm/module-symbols.html +++ b/ext/wasm/module-symbols.html @@ -290,7 +290,7 @@ sqlite3_result_zeroblob64: 'www:/c3ref/result_blob.html', sqlite3_serialize: 'www:/c3ref/serialize.html', sqlite3_set_authorizer: 'wasm:/api-c-style.md#sqlite3_set_authorizer', - sqlite3_set_auxdata: 'www:/c3ref/set_auxdata.html', + sqlite3_set_auxdata: 'www:/c3ref/get_auxdata.html', sqlite3_set_last_insert_rowid: 'www:/c3ref/set_last_insert_rowid', sqlite3_shutdown: 'www:/c3ref/initialize.html', sqlite3_sourceid: 'www:/c3ref/libversion.html', diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index bf4497a3e5..0c15bc063b 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1629,7 +1629,6 @@ self.sqlite3InitModule = sqlite3InitModule; //////////////////////////////////////////////////////////////////// .t({ name:'Scalar UDFs', - //predicate: ()=>false, test: function(sqlite3){ const db = this.db; db.createFunction("foo",(pCx,a,b)=>a+b); @@ -1696,6 +1695,45 @@ self.sqlite3InitModule = sqlite3InitModule; sqlite3.capi.SQLITE_MISUSE === rc, "For invalid arg count." ); + + /* Confirm that we can map and unmap the same function with + multiple arities... */ + const fCounts = [0,0]; + const fArityCheck = function(pCx){ + return ++fCounts[arguments.length-1]; + }; + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + rc = capi.sqlite3_create_function_v2( + db, "nary", 0, capi.SQLITE_UTF8, 0, fArityCheck, 0, 0, 0 + ); + T.assert( 0===rc ); + rc = capi.sqlite3_create_function_v2( + db, "nary", 1, capi.SQLITE_UTF8, 0, fArityCheck, 0, 0, 0 + ); + T.assert( 0===rc ); + const sqlFArity0 = "select nary()"; + const sqlFArity1 = "select nary(1)"; + T.assert( 1 === db.selectValue(sqlFArity0) ) + .assert( 1 === fCounts[0] ).assert( 0 === fCounts[1] ); + T.assert( 1 === db.selectValue(sqlFArity1) ) + .assert( 1 === fCounts[0] ).assert( 1 === fCounts[1] ); + capi.sqlite3_create_function_v2( + db, "nary", 0, capi.SQLITE_UTF8, 0, 0, 0, 0, 0 + ); + T.mustThrowMatching((()=>db.selectValue(sqlFArity0)), + (e)=>((e instanceof sqlite3.SQLite3Error) + && e.message.indexOf("wrong number of arguments")>0), + "0-arity variant was uninstalled."); + T.assert( 2 === db.selectValue(sqlFArity1) ) + .assert( 1 === fCounts[0] ).assert( 2 === fCounts[1] ); + capi.sqlite3_create_function_v2( + db, "nary", 1, capi.SQLITE_UTF8, 0, 0, 0, 0, 0 + ); + T.mustThrowMatching((()=>db.selectValue(sqlFArity1)), + (e)=>((e instanceof sqlite3.SQLite3Error) + && e.message.indexOf("no such function")>0), + "1-arity variant was uninstalled."); + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = false; } }) diff --git a/manifest b/manifest index 955f154be8..c0dd642d58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Grammar\sfixup\sin\scomment\sre\sSQLITE_TRACE_PROFILE\strace\sevent. -D 2022-12-26T01:44:04.994 +C Reimplement\ssqlite3.capi.sqlite3_close_v2()\sand\ssqlite3session_delete()\sas\sa\shand-written\sbindings\sso\sthat\sthey\scan\sattempt\sto\sclean\sup\scertain\s(potentially)\sFuncPtrAdapter-installed\sfunctions\sbefore\sclosing.\sCorrect\sthe\screate-function\sfamily\sof\sJS-to-function-pointer\sautomated\sconversions\sto\sinclude\sthe\sUDF's\sarity\sas\spart\sof\sthe\smapping's\skey\sso\sthat\s(un)binding\sa\sUDF\sto\sdifferent\sfunctions\sfor\sdifferent\sarities\sworks\s(and\sadd\stests\sconfirming\sit).\sCorrect\sa\sbroken\sdoc\slink\sin\smodule-symbols.html. +D 2022-12-26T11:13:09.162 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 594741f7cbff68f0b4a0c1a066bce335146de1124366377292e27d30f9a5f751 +F ext/wasm/api/sqlite3-api-glue.js 3bfe06cf019880a14353fe16102d8515e2cfd5b6d01941e54e2145d7298e0bb1 F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 961f190a955b419a795d1ce2136032bf8c0b14f2bda69c2b3263bab5a48f01a9 +F ext/wasm/common/whwasmutil.js 8014d4559b723a0f34f480c1962ad8625994cb17e7f71e9027732f0c16f3a70d F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -541,7 +541,7 @@ F ext/wasm/index-dist.html c806b6005145b71d64240606e9c6e0bf56878ee8829c66fe7486c F ext/wasm/index.html cc8b174ff01be282b399e64b58bdf3c921d7020da5d4e22e88bbbb4a6787a209 F ext/wasm/jaccwabyt/jaccwabyt.js 06f2ef1ad640c26c593def3d960336e9bb789819b920516480895c38ed5f58fa F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb -F ext/wasm/module-symbols.html ac9a26524f569b5510e2a66f6a04f3ebd66423c5524e28b1ca723ab1997297ae +F ext/wasm/module-symbols.html 12cff70dfc4c3c954447b743683b3674aa5ba666e3652004d07a6d664f33b6d2 F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06 F ext/wasm/scratchpad-wasmfs-main.js 4c140457f4d6da9d646a49addd91edb6e9ad1643c6c48e3258b5bce24725dc18 F ext/wasm/speedtest1-wasmfs.html 7a301f4f5b6ad4f5d37fd6e7ca03a2f5d5547fd289da60a39075a93d7646d354 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js fba3a4b5f235e5c41d635f6de5acf26133cec5b17078c1114d7212d09bfdbc00 +F ext/wasm/tester1.c-pp.js 4a5b1a1f5296686f04db017e5984230a266f2c09f1e8d25d76682566b5cacbc2 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7d4f4e96f33f37b0774cb8df22ed1ef33062534653a4fadf606704b855e28c49 -R 926f0cd5532702d032b25076c55fd75c -U larrybr -Z 868fbc8bce1667a24be059b48b2f0878 +P b6dc80cbf63ed521ef8f878fba24b0110d61813763ca7bfbcfb0a145656b300a +R 06748c7887c5b78d22b2056b9803d8a1 +U stephan +Z d4141c6258473aed1cc5843079c53a98 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 87df863e5f..e9f0cb9351 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6dc80cbf63ed521ef8f878fba24b0110d61813763ca7bfbcfb0a145656b300a \ No newline at end of file +60b262ef0f57b162c2566b12e70685a92afb00b441332ea7a6540fcb188cc7af \ No newline at end of file From 7197f0a8f22e66e9535684655dde72e33b94eb12 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 13:00:58 +0000 Subject: [PATCH 043/165] Add JS infrastructure which enables sqlite3.capi.sqlite3_close_v2() to clean up stale JS-to-WASM collation function conversions installed on behalf of a given db handle. The same for UDF mappings is TODO. FossilOrigin-Name: 0e69b2c379e61893c7db8a9c9d270650f2bd63b6cea30811d41136392a2e4f04 --- ext/wasm/api/sqlite3-api-glue.js | 120 ++++++++++++++++++++++--------- manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 94554e0b55..7db149ba5a 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -731,43 +731,95 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); }; + /** + __dbCleanupMap is infrastructure for recording registration of + UDFs and collations so that sqlite3_close_v2() can clean up any + automated JS-to-WASM function conversions installed by those. + */ + const __argPDb = (pDb)=>wasm.xWrap.argAdapter('sqlite3*')(pDb); + const __argStr = (str)=>wasm.isPtr(str) ? wasm.cstrToJs(str) : str; + const __dbCleanupMap = function( + pDb, mode/*0=remove, >0=create if needed, <0=do not create if missing*/ + ){ + pDb = __argPDb(pDb); + let m = this.dbMap.get(pDb); + if(!mode){ + this.dbMap.delete(pDb); + return m; + }else if(!m && mode>0){ + this.dbMap.set(pDb, (m = Object.create(null))); + } + return m; + }.bind(Object.assign(Object.create(null),{ + dbMap: new Map + })); + + __dbCleanupMap.addCollation = function(pDb, name){ + const m = __dbCleanupMap(pDb, 1); + if(!m.collation) m.collation = new Set; + m.collation.add(__argStr(name).toLowerCase()); + }; + + /** + Intended to be called _only_ from sqlite3_close_v2(), + passed its non-0 db argument. + + This function freees up certain automatically-installed WASM + function bindings which were installed on behalf of the given db, + as those may otherwise leak. + + Notable caveat: this is only ever run via + sqlite3.capi.sqlite3_close_v2(). If a client, for whatever + reason, uses sqlite3.wasm.exports.sqlite3_close_v2() (the + function directly exported from WASM), this cleanup will not + happen. + + This is not a silver bullet for avoiding automation-related + leaks but represents "an honest effort." + + The issue being addressed here is covered at: + + https://sqlite.org/wasm/doc/trunk/api-c-style.md#convert-func-ptr + */ + __dbCleanupMap.cleanup = function(pDb){ + pDb = __argPDb(pDb); + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + /** + Installing NULL functions in the C API will remove those + bindings. The FuncPtrAdapter which sits between us and the C + API will also treat that as an opportunity to + wasm.uninstallFunction() any WASM function bindings it has + installed for pDb. + */ + try{capi.sqlite3_busy_handler(pDb, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_progress_handler(pDb, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_trace_v2(pDb, 0, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_set_authorizer(pDb, 0, 0)} catch(e){/*ignored*/} + const m = __dbCleanupMap(pDb, 0); + if(!m) return; + if(m.collation){ + for(const name of m.collation){ + try{ + capi.sqlite3_create_collation_v2( + pDb, name, capi.SQLITE_UTF8, 0, 0, 0 + ); + }catch(e){ + /*ignored*/ + } + } + delete m.collation; + } + if(m.udf){ + //TODO: map and clean up UDFs. + } + }; + {/* Binding of sqlite3_close_v2() */ const __sqlite3CloseV2 = wasm.xWrap("sqlite3_close_v2", "int", "sqlite3*"); capi.sqlite3_close_v2 = function(pDb){ if(1!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_close_v2', 1); if(pDb){ - /* - We do this as a basic attempt at freeing up certain - automatically-installed WASM function bindings, as those may - otherwise leak. Installing NULL functions in the C API will - remove those bindings. The FuncPtrAdapter which sits between - us and the C API will also treat that as an opportunity to - wasm.uninstallFunction() any WASM function bindings it has - installed for pDb. - - This does not catch all such bindings: those which map to - both a db handle and a separate key (e.g. collation sequence - name or UDF name) cannot be unmapped here because we don't - have the other parts of the mapping key. It's also possible - for clients to call wasm.exports.sqlite3_close_v2() - directly, bypassing this cleanup altogether. i.e. this is - not a silver bullet, just an "honest effort." - - Perhaps we can add some code to sqlite3-wasm.c which can - walk through the UDF and collation names to help us free up - those auto-converted functions, too. Functions are more - complicated because a given function may have multiple - mappings for different arities. - - The issue being addressed here is covered at: - - https://sqlite.org/wasm/doc/trunk/api-c-style.md#convert-func-ptr - */ - //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; - try{capi.sqlite3_busy_handler(pDb, 0, 0)} catch(e){/*ignored*/} - try{capi.sqlite3_progress_handler(pDb, 0, 0, 0)} catch(e){/*ignored*/} - try{capi.sqlite3_trace_v2(pDb, 0, 0, 0, 0)} catch(e){/*ignored*/} - try{capi.sqlite3_set_authorizer(pDb, 0, 0)} catch(e){/*ignored*/} + try{__dbCleanupMap.cleanup(pDb)} catch(e){/*ignored*/} } return __sqlite3CloseV2(pDb); }; @@ -844,7 +896,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __errEncoding(pDb); } try{ - return __sqlite3CreateCollationV2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); + const rc = __sqlite3CreateCollationV2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); + if(xCompare) __dbCleanupMap.addCollation(pDb, zName); + return rc; }catch(e){ return util.sqlite3_wasm_db_error(pDb, e); } diff --git a/manifest b/manifest index c0dd642d58..e61313a295 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reimplement\ssqlite3.capi.sqlite3_close_v2()\sand\ssqlite3session_delete()\sas\sa\shand-written\sbindings\sso\sthat\sthey\scan\sattempt\sto\sclean\sup\scertain\s(potentially)\sFuncPtrAdapter-installed\sfunctions\sbefore\sclosing.\sCorrect\sthe\screate-function\sfamily\sof\sJS-to-function-pointer\sautomated\sconversions\sto\sinclude\sthe\sUDF's\sarity\sas\spart\sof\sthe\smapping's\skey\sso\sthat\s(un)binding\sa\sUDF\sto\sdifferent\sfunctions\sfor\sdifferent\sarities\sworks\s(and\sadd\stests\sconfirming\sit).\sCorrect\sa\sbroken\sdoc\slink\sin\smodule-symbols.html. -D 2022-12-26T11:13:09.162 +C Add\sJS\sinfrastructure\swhich\senables\ssqlite3.capi.sqlite3_close_v2()\sto\sclean\sup\sstale\sJS-to-WASM\scollation\sfunction\sconversions\sinstalled\son\sbehalf\sof\sa\sgiven\sdb\shandle.\sThe\ssame\sfor\sUDF\smappings\sis\sTODO. +D 2022-12-26T13:00:58.115 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 3bfe06cf019880a14353fe16102d8515e2cfd5b6d01941e54e2145d7298e0bb1 +F ext/wasm/api/sqlite3-api-glue.js 8e6336cd5c6e404b1460a196196eb6362b13de4ec24544ef1a3a1a4132245d9c F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6dc80cbf63ed521ef8f878fba24b0110d61813763ca7bfbcfb0a145656b300a -R 06748c7887c5b78d22b2056b9803d8a1 +P 60b262ef0f57b162c2566b12e70685a92afb00b441332ea7a6540fcb188cc7af +R ad57ccb8cecad2b9daaaef2f36f544d6 U stephan -Z d4141c6258473aed1cc5843079c53a98 +Z 7341e7115e45a0f5c9a909c3a65ff344 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e9f0cb9351..23b40688f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60b262ef0f57b162c2566b12e70685a92afb00b441332ea7a6540fcb188cc7af \ No newline at end of file +0e69b2c379e61893c7db8a9c9d270650f2bd63b6cea30811d41136392a2e4f04 \ No newline at end of file From 171aa209faaa5d42a7208cefebe13d952c9208cf Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 13:45:10 +0000 Subject: [PATCH 044/165] Extend [0e69b2c379e618] to support uninstalling stale JS-to-WASM function pointers added on behalf of UDFs. FossilOrigin-Name: 7a46e629dcbf97ae037c5abb39306af7ad55f1910c1e962373e09d88d8bd5a33 --- ext/wasm/api/sqlite3-api-glue.js | 71 ++++++++++++++++++++++++++++---- ext/wasm/common/whwasmutil.js | 5 ++- manifest | 14 +++---- manifest.uuid | 2 +- 4 files changed, 73 insertions(+), 19 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 7db149ba5a..2b44c05638 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -760,6 +760,26 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ m.collation.add(__argStr(name).toLowerCase()); }; + __dbCleanupMap._addUDF = function(pDb, name, arity, map){ + /* Map UDF name to a Set of arity values */ + name = __argStr(name).toLowerCase(); + let u = map.get(name); + if(!u) map.set(name, (u = new Set)); + u.add((arity<0) ? -1 : arity); + }; + + __dbCleanupMap.addFunction = function(pDb, name, arity){ + const m = __dbCleanupMap(pDb, 1); + if(!m.udf) m.udf = new Map; + this._addUDF(pDb, name, arity, m.udf); + }; + + __dbCleanupMap.addWindowFunc = function(pDb, name, arity){ + const m = __dbCleanupMap(pDb, 1); + if(!m.wudf) m.wudf = new Map; + this._addUDF(pDb, name, arity, m.wudf); + }; + /** Intended to be called _only_ from sqlite3_close_v2(), passed its non-0 db argument. @@ -783,7 +803,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ __dbCleanupMap.cleanup = function(pDb){ pDb = __argPDb(pDb); - //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; /** Installing NULL functions in the C API will remove those bindings. The FuncPtrAdapter which sits between us and the C @@ -809,10 +829,28 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } delete m.collation; } - if(m.udf){ - //TODO: map and clean up UDFs. + let i; + for(i = 0; i < 2; ++i){ /* Clean up UDFs... */ + const fmap = i ? m.wudf : m.udf; + if(!fmap) continue; + const func = i + ? capi.sqlite3_create_window_function + : capi.sqlite3_create_function_v2; + for(const e of fmap){ + const name = e[0], arities = e[1]; + const fargs = [pDb, name, 0/*arity*/, capi.SQLITE_UTF8, 0, 0, 0, 0, 0]; + if(i) fargs.push(0); + for(const arity of arities){ + try{ fargs[2] = arity; func.apply(null, fargs); } + catch(e){/*ignored*/} + } + arities.clear(); + } + fmap.clear(); } - }; + delete m.udf; + delete m.wudf; + }/*__dbCleanupMap.cleanup()*/; {/* Binding of sqlite3_close_v2() */ const __sqlite3CloseV2 = wasm.xWrap("sqlite3_close_v2", "int", "sqlite3*"); @@ -1015,8 +1053,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __errEncoding(pDb); } try{ - return __sqlite3CreateFunction(pDb, funcName, nArg, eTextRep, - pApp, xFunc, xStep, xFinal, xDestroy); + const rc = __sqlite3CreateFunction(pDb, funcName, nArg, eTextRep, + pApp, xFunc, xStep, xFinal, xDestroy); + if(0===rc && (xFunc instanceof Function + || xStep instanceof Function + || xFinal instanceof Function + || xDestroy instanceof Function)){ + __dbCleanupMap.addFunction(pDb, funcName, nArg); + } + return rc; }catch(e){ console.error("sqlite3_create_function_v2() setup threw:",e); return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); @@ -1051,9 +1096,17 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __errEncoding(pDb); } try{ - return __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep, - pApp, xStep, xFinal, xValue, - xInverse, xDestroy); + const rc = __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep, + pApp, xStep, xFinal, xValue, + xInverse, xDestroy); + if(0===rc && (xStep instanceof Function + || xFinal instanceof Function + || xValue instanceof Function + || xInverse instanceof Function + || xDestroy instanceof Function)){ + __dbCleanupMap.addWindowFunc(pDb, funcName, nArg); + } + return rc; }catch(e){ console.error("sqlite3_create_window_function() setup threw:",e); return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e); diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index df401c8fee..9b946b24be 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1659,8 +1659,9 @@ self.WhWasmUtilInstaller = function(target){ static warnOnUse = false; /** If true, convertArg() will FuncPtrAdapter.debugOut() when it - (un)installs a function binding to/from WASM. - */ + (un)installs a function binding to/from WASM. Note that + deinstallation of bindScope=transient bindings happens + via scopedAllocPop() so will not be output. */ static debugFuncInstall = false; /** Function used for debug output. */ diff --git a/manifest b/manifest index e61313a295..8a880c0f78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sJS\sinfrastructure\swhich\senables\ssqlite3.capi.sqlite3_close_v2()\sto\sclean\sup\sstale\sJS-to-WASM\scollation\sfunction\sconversions\sinstalled\son\sbehalf\sof\sa\sgiven\sdb\shandle.\sThe\ssame\sfor\sUDF\smappings\sis\sTODO. -D 2022-12-26T13:00:58.115 +C Extend\s[0e69b2c379e618]\sto\ssupport\suninstalling\sstale\sJS-to-WASM\sfunction\spointers\sadded\son\sbehalf\sof\sUDFs. +D 2022-12-26T13:45:10.544 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 8e6336cd5c6e404b1460a196196eb6362b13de4ec24544ef1a3a1a4132245d9c +F ext/wasm/api/sqlite3-api-glue.js 859180a5cea4e33d18c3a129d41e4068d5330846efa3287f152ac063859055a6 F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 8014d4559b723a0f34f480c1962ad8625994cb17e7f71e9027732f0c16f3a70d +F ext/wasm/common/whwasmutil.js 63188a5b90de3c17a2fdf3f1a90321ffdeaa2c34f6ca9d76f830fb0800867854 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60b262ef0f57b162c2566b12e70685a92afb00b441332ea7a6540fcb188cc7af -R ad57ccb8cecad2b9daaaef2f36f544d6 +P 0e69b2c379e61893c7db8a9c9d270650f2bd63b6cea30811d41136392a2e4f04 +R 45aeadabb85c467b62debc379d9a6901 U stephan -Z 7341e7115e45a0f5c9a909c3a65ff344 +Z eea54b677b9aecae6309be4e3e0e63e0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 23b40688f4..f05bbdf17f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e69b2c379e61893c7db8a9c9d270650f2bd63b6cea30811d41136392a2e4f04 \ No newline at end of file +7a46e629dcbf97ae037c5abb39306af7ad55f1910c1e962373e09d88d8bd5a33 \ No newline at end of file From 67e4f6fcdb00a005f41e9dc877ec85d45a20b887 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 14:25:21 +0000 Subject: [PATCH 045/165] Only add an on-db-close cleanup entry for collations if adding the collation succeeds and xCompare is-a JS function. FossilOrigin-Name: 18a5480f1e0dca55703b43fa17685a4cc577cab8841ce47c807af02348ad85ee --- ext/wasm/api/sqlite3-api-glue.js | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 2b44c05638..f4c67eac82 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -935,7 +935,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } try{ const rc = __sqlite3CreateCollationV2(pDb, zName, eTextRep, pArg, xCompare, xDestroy); - if(xCompare) __dbCleanupMap.addCollation(pDb, zName); + if(0===rc && xCompare instanceof Function){ + __dbCleanupMap.addCollation(pDb, zName); + } return rc; }catch(e){ return util.sqlite3_wasm_db_error(pDb, e); diff --git a/manifest b/manifest index 8a880c0f78..aeb3923abd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\s[0e69b2c379e618]\sto\ssupport\suninstalling\sstale\sJS-to-WASM\sfunction\spointers\sadded\son\sbehalf\sof\sUDFs. -D 2022-12-26T13:45:10.544 +C Only\sadd\san\son-db-close\scleanup\sentry\sfor\scollations\sif\sadding\sthe\scollation\ssucceeds\sand\sxCompare\sis-a\sJS\sfunction. +D 2022-12-26T14:25:21.345 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 859180a5cea4e33d18c3a129d41e4068d5330846efa3287f152ac063859055a6 +F ext/wasm/api/sqlite3-api-glue.js 232bdd95abf27ce6e92b5d7e7ad28118992365520599fcc1b91cf25a430ea8bf F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0e69b2c379e61893c7db8a9c9d270650f2bd63b6cea30811d41136392a2e4f04 -R 45aeadabb85c467b62debc379d9a6901 +P 7a46e629dcbf97ae037c5abb39306af7ad55f1910c1e962373e09d88d8bd5a33 +R ea04524f0bc74032e475c426c786ceba U stephan -Z eea54b677b9aecae6309be4e3e0e63e0 +Z de786855ae41b30556ccc9f965731fe5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f05bbdf17f..a7a26f3148 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a46e629dcbf97ae037c5abb39306af7ad55f1910c1e962373e09d88d8bd5a33 \ No newline at end of file +18a5480f1e0dca55703b43fa17685a4cc577cab8841ce47c807af02348ad85ee \ No newline at end of file From d9cfd0f339e4ca30981eb7dc44724480710cc48e Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 14:55:00 +0000 Subject: [PATCH 046/165] Correct some internal-use JS docs and update the 'string:flexible' type conversion to accept an ArrayBuffer (as it was recently documented to). FossilOrigin-Name: eff5d3bec29043cc1182bbb5229040dac5ff50264d025e354736bb63b4bc97a0 --- ext/wasm/api/sqlite3-api-oo1.js | 6 ++---- ext/wasm/api/sqlite3-api-prologue.js | 10 +++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 965f7ee93c..f72def751e 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1246,9 +1246,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(wasm.bigIntEnabled) return t; /* else fall through */ default: - //console.log("isSupportedBindType",t,v); - return (util.isBindableTypedArray(v) || (v instanceof ArrayBuffer)) - ? BindTypes.blob : undefined; + return util.isBindableTypedArray(v) ? BindTypes.blob : undefined; } }; @@ -1466,7 +1464,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ blob binding). - Uint8Array, Int8Array, and ArrayBuffer instances are bound as - blobs. (TODO? binding the other TypedArray types.) + blobs. If passed an array, each element of the array is bound at the parameter index equal to the array index plus 1 diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index ff528feef5..acf66b6e26 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -321,7 +321,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( }; /** - Returns v if v appears to be one of our bind()-able TypedArray + Returns true if v appears to be one of our bind()-able TypedArray types: Uint8Array or Int8Array or ArrayBuffer. Support for TypedArrays with element sizes >1 is a potential TODO just waiting on a use case to justify them. Until then, their `buffer` @@ -377,7 +377,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( returned. Else v is returned as-is. */ const flexibleString = function(v){ - if(isSQLableTypedArray(v)) return typedArrayToString(v); + if(isSQLableTypedArray(v)){ + return typedArrayToString( + (v instanceof ArrayBuffer) ? new Uint8Array(v) : v + ); + } else if(Array.isArray(v)) return v.join(""); else if(wasm.isPtr(v)) v = wasm.cstrToJs(v); return v; @@ -751,7 +755,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( affirmBindableTypedArray, flexibleString, bigIntFits32, bigIntFits64, bigIntFitsDouble, isBindableTypedArray, - isInt32, isSQLableTypedArray, isTypedArray, + isInt32, isSQLableTypedArray, isTypedArray, typedArrayToString, isUIThread: ()=>(self.window===self && !!self.document), // is this true for ESM?: 'undefined'===typeof WorkerGlobalScope diff --git a/manifest b/manifest index aeb3923abd..aa3fc81931 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\sadd\san\son-db-close\scleanup\sentry\sfor\scollations\sif\sadding\sthe\scollation\ssucceeds\sand\sxCompare\sis-a\sJS\sfunction. -D 2022-12-26T14:25:21.345 +C Correct\ssome\sinternal-use\sJS\sdocs\sand\supdate\sthe\s'string:flexible'\stype\sconversion\sto\saccept\san\sArrayBuffer\s(as\sit\swas\srecently\sdocumented\sto). +D 2022-12-26T14:55:00.015 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,8 +504,8 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js 232bdd95abf27ce6e92b5d7e7ad28118992365520599fcc1b91cf25a430ea8bf -F ext/wasm/api/sqlite3-api-oo1.js 959be9a922d1f012b4a25e7b763c112220bb0efb989f56b82a776ab1ccebe72d -F ext/wasm/api/sqlite3-api-prologue.js 3792a703ea15be8d4393a99992862c285d62732d760cec95226dc5ec2781d920 +F ext/wasm/api/sqlite3-api-oo1.js 045c98796950c22556fc0842fe9f0d9a67f31920f247e24fb440571cdb6be5b0 +F ext/wasm/api/sqlite3-api-prologue.js f8d21f26615c332de98e0eb85f2e55f7b90e3d522c0357e07d6e1de8c5681e49 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7a46e629dcbf97ae037c5abb39306af7ad55f1910c1e962373e09d88d8bd5a33 -R ea04524f0bc74032e475c426c786ceba +P 18a5480f1e0dca55703b43fa17685a4cc577cab8841ce47c807af02348ad85ee +R 160fe994465231b79e87837be38dc79b U stephan -Z de786855ae41b30556ccc9f965731fe5 +Z 59b56e199ffa18f089018d23ec3db748 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a7a26f3148..f86fa6c8e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18a5480f1e0dca55703b43fa17685a4cc577cab8841ce47c807af02348ad85ee \ No newline at end of file +eff5d3bec29043cc1182bbb5229040dac5ff50264d025e354736bb63b4bc97a0 \ No newline at end of file From 64fa85bb5e5e7870ed1f268c5b915f61e5ea1b28 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 15:08:48 +0000 Subject: [PATCH 047/165] Document sqlite3.capi.sqlite3_prepare_v3() as accepting an ArrayBuffer and ensure that it can. FossilOrigin-Name: ae3ae92ec45d3d5de92e70876502f8108fc3fcd87848e86c2b83f8842f1ff139 --- ext/wasm/api/sqlite3-api-glue.js | 10 ++++++---- ext/wasm/api/sqlite3-api-prologue.js | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index f4c67eac82..cef27b5485 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -1146,16 +1146,18 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Helper for string:flexible conversions which require a byte-length counterpart argument. Passed a value and its - ostensible length, this function returns [V,N], where V - is either v or a transformed copy of v and N is either n, - -1, or the byte length of v (if it's a byte array). + ostensible length, this function returns [V,N], where V is + either v or a transformed copy of v and N is either n, -1, or + the byte length of v (if it's a byte array or ArrayBuffer). */ const __flexiString = (v,n)=>{ if('string'===typeof v){ n = -1; }else if(util.isSQLableTypedArray(v)){ n = v.byteLength; - v = util.typedArrayToString(v); + v = util.typedArrayToString( + (v instanceof ArrayBuffer) ? new Uint8Array(v) : v + ); }else if(Array.isArray(v)){ v = v.join(""); n = -1; diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index acf66b6e26..cae268996b 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -662,8 +662,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( terminated with a 0 byte. In usage (1), the 2nd argument must be of type string, - Uint8Array, or Int8Array (either of which is assumed to - hold SQL). If it is, this function assumes case (1) and + Uint8Array, Int8Array, or ArrayBuffer (all of which are assumed + to hold SQL). If it is, this function assumes case (1) and calls the underyling C function with the equivalent of: (pDb, sqlAsString, -1, prepFlags, ppStmt, null) diff --git a/manifest b/manifest index aa3fc81931..71d9c2fd53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\ssome\sinternal-use\sJS\sdocs\sand\supdate\sthe\s'string:flexible'\stype\sconversion\sto\saccept\san\sArrayBuffer\s(as\sit\swas\srecently\sdocumented\sto). -D 2022-12-26T14:55:00.015 +C Document\ssqlite3.capi.sqlite3_prepare_v3()\sas\saccepting\san\sArrayBuffer\sand\sensure\sthat\sit\scan. +D 2022-12-26T15:08:48.274 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js 232bdd95abf27ce6e92b5d7e7ad28118992365520599fcc1b91cf25a430ea8bf +F ext/wasm/api/sqlite3-api-glue.js e16bf1de4c08d3906298d532e1e61478791286e768d7ba1538ca90d0fa344e12 F ext/wasm/api/sqlite3-api-oo1.js 045c98796950c22556fc0842fe9f0d9a67f31920f247e24fb440571cdb6be5b0 -F ext/wasm/api/sqlite3-api-prologue.js f8d21f26615c332de98e0eb85f2e55f7b90e3d522c0357e07d6e1de8c5681e49 +F ext/wasm/api/sqlite3-api-prologue.js e862e5b79d565bd79c8ff59ebb6618a07ecb1a0262a1560dc6a10aa0f4d6f531 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 18a5480f1e0dca55703b43fa17685a4cc577cab8841ce47c807af02348ad85ee -R 160fe994465231b79e87837be38dc79b +P eff5d3bec29043cc1182bbb5229040dac5ff50264d025e354736bb63b4bc97a0 +R 6ff80c69205054a7da640050cde0ccdf U stephan -Z 59b56e199ffa18f089018d23ec3db748 +Z 3c914ac569efd4e323dbc54f2636bac4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f86fa6c8e2..2e0706bd0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eff5d3bec29043cc1182bbb5229040dac5ff50264d025e354736bb63b4bc97a0 \ No newline at end of file +ae3ae92ec45d3d5de92e70876502f8108fc3fcd87848e86c2b83f8842f1ff139 \ No newline at end of file From ff78b2bee8a20485e4efd9571e3a60a92760e4a4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 26 Dec 2022 15:14:24 +0000 Subject: [PATCH 048/165] Fix an infinite loop in the MEMSYS5 auxiliary memory allocator that occurs for memory allocations between 1GiB and 2GiB in size. Error introduced by check-in [949133231f8f751a]. The problem only affects builds that include the SQLITE_ENABLE_MEMSYS5 compile-time option. FossilOrigin-Name: 8da0f0c38a458c57f979d59b49cf4804ef81fc2eccabde1f166bab24dd1dabea --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/mem5.c | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 71d9c2fd53..3301f5499c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\ssqlite3.capi.sqlite3_prepare_v3()\sas\saccepting\san\sArrayBuffer\sand\sensure\sthat\sit\scan. -D 2022-12-26T15:08:48.274 +C Fix\san\sinfinite\sloop\sin\sthe\sMEMSYS5\sauxiliary\smemory\sallocator\sthat\soccurs\nfor\smemory\sallocations\sbetween\s1GiB\sand\s2GiB\sin\ssize.\s\sError\sintroduced\nby\scheck-in\s[949133231f8f751a].\s\sThe\sproblem\sonly\saffects\sbuilds\sthat\ninclude\sthe\sSQLITE_ENABLE_MEMSYS5\scompile-time\soption. +D 2022-12-26T15:14:24.028 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -614,7 +614,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 -F src/mem5.c 5a3dbd8ac8a6501152a4fc1fcae9b0900c2d7eb0589c4ec7456fdde15725a26c +F src/mem5.c b658f3dd447ad8963d2b4b3f0081aa71f0c827eb99f9cb54675bdf2eea5ad34e F src/memdb.c 559c42e61eb70cd6d4bc692b042497133c6d96c09a3d514d92f3dac72268e223 F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0 F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eff5d3bec29043cc1182bbb5229040dac5ff50264d025e354736bb63b4bc97a0 -R 6ff80c69205054a7da640050cde0ccdf -U stephan -Z 3c914ac569efd4e323dbc54f2636bac4 +P ae3ae92ec45d3d5de92e70876502f8108fc3fcd87848e86c2b83f8842f1ff139 +R af6df6d036a8bd991cf092623d05af75 +U drh +Z 333253e835d0b6bf644788ba3ea65af5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2e0706bd0b..be2a3ca6de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae3ae92ec45d3d5de92e70876502f8108fc3fcd87848e86c2b83f8842f1ff139 \ No newline at end of file +8da0f0c38a458c57f979d59b49cf4804ef81fc2eccabde1f166bab24dd1dabea \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index b61b93e112..336f893c6a 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -424,9 +424,13 @@ static int memsys5Roundup(int n){ if( n<=mem5.szAtom ) return mem5.szAtom; return mem5.szAtom*2; } - if( n>0x40000000 ) return 0; + if( n>0x10000000 ){ + if( n>0x40000000 ) return 0; + if( n>0x20000000 ) return 0x40000000; + return 0x2000000; + } for(iFullSz=mem5.szAtom*8; iFullSz=n ) return iFullSz/2; + if( (iFullSz/2)>=(i64)n ) return iFullSz/2; return iFullSz; } From 84261bac96a9d5faeb76aec5bcd97d5fdc707400 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 26 Dec 2022 17:15:05 +0000 Subject: [PATCH 049/165] Expose the auto-extension API to JS and reorganize some nearby code. FossilOrigin-Name: 52b229d11d82bfb81c8b63e252c51c57a34dc50498dd685451588c185873c628 --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 3 + ext/wasm/api/sqlite3-api-glue.js | 237 ++++++++++++-------- ext/wasm/common/whwasmutil.js | 7 +- ext/wasm/tester1.c-pp.js | 24 ++ manifest | 20 +- manifest.uuid | 2 +- 6 files changed, 182 insertions(+), 111 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index a6559cbb34..8ba6e515c5 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -2,6 +2,7 @@ _malloc _free _realloc _sqlite3_aggregate_context +_sqlite3_auto_extension _sqlite3_bind_blob _sqlite3_bind_double _sqlite3_bind_int @@ -13,6 +14,7 @@ _sqlite3_bind_pointer _sqlite3_bind_text _sqlite3_busy_handler _sqlite3_busy_timeout +_sqlite3_cancel_auto_extension _sqlite3_changes _sqlite3_changes64 _sqlite3_clear_bindings @@ -81,6 +83,7 @@ _sqlite3_randomness _sqlite3_realloc _sqlite3_realloc64 _sqlite3_reset +_sqlite3_reset_auto_extension _sqlite3_result_blob _sqlite3_result_double _sqlite3_result_error diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index cef27b5485..ddb4a58fa6 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -69,6 +69,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.bindingSignatures = [ // Please keep these sorted by function name! ["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"], + /* sqlite3_auto_extension() has a hand-written binding. */ /* sqlite3_bind_blob() and sqlite3_bind_text() have hand-written bindings to permit more flexible inputs. */ ["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"], @@ -87,8 +88,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "*" ]], ["sqlite3_busy_timeout","int", "sqlite3*", "int"], - /*[sqlite3_close_v2() is implemented by hand to perform some - extra work. "sqlite3_close_v2", "int", "sqlite3*"],*/ + /* sqlite3_cancel_auto_extension() has a hand-written binding. */ + /* sqlite3_close_v2() is implemented by hand to perform some + extra work. */ ["sqlite3_changes", "int", "sqlite3*"], ["sqlite3_clear_bindings","int", "sqlite3_stmt*"], ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/], @@ -190,6 +192,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ]], ["sqlite3_realloc", "*","*","int"], ["sqlite3_reset", "int", "sqlite3_stmt*"], + /* sqlite3_reset_auto_extension() has a hand-written binding. */ ["sqlite3_result_blob", undefined, "sqlite3_context*", "*", "int", "*"], ["sqlite3_result_double", undefined, "sqlite3_context*", "f64"], ["sqlite3_result_error", undefined, "sqlite3_context*", "string", "int"], @@ -543,8 +546,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }); delete self.Jaccwabyt; - {/* Convert Arrays and certain TypedArrays to strings for - 'string:flexible'-type arguments */ + {// wasm.xWrap() bindings... + + /* Convert Arrays and certain TypedArrays to strings for + 'string:flexible'-type arguments */ const __xString = wasm.xWrap.argAdapter('string'); wasm.xWrap.argAdapter( 'string:flexible', (v)=>__xString(util.flexibleString(v)) @@ -580,9 +585,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return rc || (this[v] = wasm.allocCString(v)); }.bind(Object.create(null)) ); - }/* special-case string-type argument conversions */ - if(1){// wasm.xWrap() bindings... /** Add some descriptive xWrap() aliases for '*' intended to (A) initially improve readability/correctness of @@ -590,27 +593,27 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ from higher-level representations, e.g. capi.sqlite3_vfs to `sqlite3_vfs*` via capi.sqlite3_vfs.pointer. */ - const aPtr = wasm.xWrap.argAdapter('*'); - const nilType = function(){}; - wasm.xWrap.argAdapter('sqlite3_filename', aPtr) - ('sqlite3_context*', aPtr) - ('sqlite3_value*', aPtr) - ('void*', aPtr) - ('sqlite3_changegroup*', aPtr) - ('sqlite3_changeset_iter*', aPtr) - //('sqlite3_rebaser*', aPtr) - ('sqlite3_session*', aPtr) + const __xArgPtr = wasm.xWrap.argAdapter('*'); + const nilType = function(){}/*a class no value can ever be an instance of*/; + wasm.xWrap.argAdapter('sqlite3_filename', __xArgPtr) + ('sqlite3_context*', __xArgPtr) + ('sqlite3_value*', __xArgPtr) + ('void*', __xArgPtr) + ('sqlite3_changegroup*', __xArgPtr) + ('sqlite3_changeset_iter*', __xArgPtr) + //('sqlite3_rebaser*', __xArgPtr) + ('sqlite3_session*', __xArgPtr) ('sqlite3_stmt*', (v)=> - aPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType)) + __xArgPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType)) ? v.pointer : v)) ('sqlite3*', (v)=> - aPtr((v instanceof (sqlite3?.oo1?.DB || nilType)) + __xArgPtr((v instanceof (sqlite3?.oo1?.DB || nilType)) ? v.pointer : v)) ('sqlite3_index_info*', (v)=> - aPtr((v instanceof (capi.sqlite3_index_info || nilType)) + __xArgPtr((v instanceof (capi.sqlite3_index_info || nilType)) ? v.pointer : v)) ('sqlite3_module*', (v)=> - aPtr((v instanceof (capi.sqlite3_module || nilType)) + __xArgPtr((v instanceof (capi.sqlite3_module || nilType)) ? v.pointer : v)) /** `sqlite3_vfs*`: @@ -631,8 +634,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "Unknown sqlite3_vfs name:", v ); } - return aPtr((v instanceof (capi.sqlite3_vfs || nilType)) - ? v.pointer : v); + return __xArgPtr((v instanceof (capi.sqlite3_vfs || nilType)) + ? v.pointer : v); }); const __xRcPtr = wasm.xWrap.resultAdapter('*'); @@ -709,7 +712,83 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return errCode; }; } - }/*xWrap() bindings*/; + }/*xWrap() bindings*/ + + {/* Import C-level constants and structs... */ + const cJson = wasm.xCall('sqlite3_wasm_enum_json'); + if(!cJson){ + toss("Maintenance required: increase sqlite3_wasm_enum_json()'s", + "static buffer size!"); + } + //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); + wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); + // Groups of SQLITE_xyz macros... + const defineGroups = ['access', 'authorizer', + 'blobFinalizers', 'changeset', + 'config', 'dataTypes', + 'dbConfig', 'dbStatus', + 'encodings', 'fcntl', 'flock', 'ioCap', + 'limits', 'openFlags', + 'prepareFlags', 'resultCodes', + 'sqlite3Status', + 'stmtStatus', 'syncFlags', + 'trace', 'txnState', 'udfFlags', + 'version' ]; + if(wasm.bigIntEnabled){ + defineGroups.push('serialize', 'session', 'vtab'); + } + for(const t of defineGroups){ + for(const e of Object.entries(wasm.ctype[t])){ + // ^^^ [k,v] there triggers a buggy code transformation via + // one of the Emscripten-driven optimizers. + capi[e[0]] = e[1]; + } + } + const __rcMap = Object.create(null); + for(const t of ['resultCodes']){ + for(const e of Object.entries(wasm.ctype[t])){ + __rcMap[e[1]] = e[0]; + } + } + /** + For the given integer, returns the SQLITE_xxx result code as a + string, or undefined if no such mapping is found. + */ + capi.sqlite3_js_rc_str = (rc)=>__rcMap[rc]; + /* Bind all registered C-side structs... */ + const notThese = Object.assign(Object.create(null),{ + // For each struct to NOT register, map its name to true: + WasmTestStruct: true, + /* We unregister the kvvfs VFS from Worker threads below. */ + sqlite3_kvvfs_methods: !util.isUIThread(), + /* sqlite3_index_info and friends require int64: */ + sqlite3_index_info: !wasm.bigIntEnabled, + sqlite3_index_constraint: !wasm.bigIntEnabled, + sqlite3_index_orderby: !wasm.bigIntEnabled, + sqlite3_index_constraint_usage: !wasm.bigIntEnabled + }); + for(const s of wasm.ctype.structs){ + if(!notThese[s.name]){ + capi[s.name] = sqlite3.StructBinder(s); + } + } + if(capi.sqlite3_index_info){ + /* Move these inner structs into sqlite3_index_info. Binding + ** them to WASM requires that we create global-scope structs to + ** model them with, but those are no longer needed after we've + ** passed them to StructBinder. */ + for(const k of ['sqlite3_index_constraint', + 'sqlite3_index_orderby', + 'sqlite3_index_constraint_usage']){ + capi.sqlite3_index_info[k] = capi[k]; + delete capi[k]; + } + capi.sqlite3_vtab_config = wasm.xWrap( + 'sqlite3_wasm_vtab_config','int',[ + 'sqlite3*', 'int', 'int'] + ); + }/* end vtab-related setup */ + }/*end C constant and struct imports*/ /** Internal helper to assist in validating call argument counts in @@ -803,7 +882,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ __dbCleanupMap.cleanup = function(pDb){ pDb = __argPDb(pDb); - wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + wasm.xWrap.FuncPtrAdapter.debugFuncInstall = false; /** Installing NULL functions in the C API will remove those bindings. The FuncPtrAdapter which sits between us and the C @@ -1140,8 +1219,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/; - if(1){/* Special-case handling of sqlite3_prepare_v2() and - sqlite3_prepare_v3() */ + {/* Special-case handling of sqlite3_prepare_v2() and + sqlite3_prepare_v3() */ /** Helper for string:flexible conversions which require a @@ -1346,81 +1425,41 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; }/* sqlite3_config() */ - {/* Import C-level constants and structs... */ - const cJson = wasm.xCall('sqlite3_wasm_enum_json'); - if(!cJson){ - toss("Maintenance required: increase sqlite3_wasm_enum_json()'s", - "static buffer size!"); - } - //console.debug('wasm.ctype length =',wasm.cstrlen(cJson)); - wasm.ctype = JSON.parse(wasm.cstrToJs(cJson)); - // Groups of SQLITE_xyz macros... - const defineGroups = ['access', 'authorizer', - 'blobFinalizers', 'changeset', - 'config', 'dataTypes', - 'dbConfig', 'dbStatus', - 'encodings', 'fcntl', 'flock', 'ioCap', - 'limits', 'openFlags', - 'prepareFlags', 'resultCodes', - 'sqlite3Status', - 'stmtStatus', 'syncFlags', - 'trace', 'txnState', 'udfFlags', - 'version' ]; - if(wasm.bigIntEnabled){ - defineGroups.push('serialize', 'session', 'vtab'); - } - for(const t of defineGroups){ - for(const e of Object.entries(wasm.ctype[t])){ - // ^^^ [k,v] there triggers a buggy code transformation via - // one of the Emscripten-driven optimizers. - capi[e[0]] = e[1]; + {/*auto-extension bindings.*/ + const __autoExtFptr = new Set; + + capi.sqlite3_auto_extension = function(fPtr){ + if( fPtr instanceof Function ){ + fPtr = wasm.installFunction('i(ppp)', fPtr); + }else if( 1!==arguments.length || !wasm.isPtr(fPtr) ){ + return capi.SQLITE_MISUSE; } - } - const __rcMap = Object.create(null); - for(const t of ['resultCodes']){ - for(const e of Object.entries(wasm.ctype[t])){ - __rcMap[e[1]] = e[0]; + const rc = wasm.exports.sqlite3_auto_extension(fPtr); + if( fPtr!==arguments[0] ){ + if(0===rc) __autoExtFptr.add(fPtr); + else wasm.uninstallFunction(fPtr); } - } - /** - For the given integer, returns the SQLITE_xxx result code as a - string, or undefined if no such mapping is found. - */ - capi.sqlite3_js_rc_str = (rc)=>__rcMap[rc]; - /* Bind all registered C-side structs... */ - const notThese = Object.assign(Object.create(null),{ - // For each struct to NOT register, map its name to true: - WasmTestStruct: true, - /* We unregister the kvvfs VFS from Worker threads below. */ - sqlite3_kvvfs_methods: !util.isUIThread(), - /* sqlite3_index_info and friends require int64: */ - sqlite3_index_info: !wasm.bigIntEnabled, - sqlite3_index_constraint: !wasm.bigIntEnabled, - sqlite3_index_orderby: !wasm.bigIntEnabled, - sqlite3_index_constraint_usage: !wasm.bigIntEnabled - }); - for(const s of wasm.ctype.structs){ - if(!notThese[s.name]){ - capi[s.name] = sqlite3.StructBinder(s); - } - } - if(capi.sqlite3_index_info){ - /* Move these inner structs into sqlite3_index_info. Binding - ** them to WASM requires that we create global-scope structs to - ** model them with, but those are no longer needed after we've - ** passed them to StructBinder. */ - for(const k of ['sqlite3_index_constraint', - 'sqlite3_index_orderby', - 'sqlite3_index_constraint_usage']){ - capi.sqlite3_index_info[k] = capi[k]; - delete capi[k]; - } - capi.sqlite3_vtab_config = wasm.xWrap( - 'sqlite3_wasm_vtab_config','int',[ - 'sqlite3*', 'int', 'int'] - ); - }/* end vtab-related setup */ - }/*end C constant and struct imports*/ + return rc; + }; + + capi.sqlite3_cancel_auto_extension = function(fPtr){ + /* We do not do an automatic JS-to-WASM function conversion here + because it would be senseless: the converted pointer would + never possibly match an already-installed one. */; + if(!fPtr || 1!==arguments.length || !wasm.isPtr(fPtr)) return 0; + return wasm.exports.sqlite3_cancel_auto_extension(fPtr); + /* Note that it "cannot happen" that a client passes a pointer which + is in __autoExtFptr because __autoExtFptr only contains automatic + conversions created inside sqlite3_auto_extension() and + never exposed to the client. */ + }; + + capi.sqlite3_reset_auto_extension = function(){ + wasm.exports.sqlite3_reset_auto_extension(); + for(const fp of __autoExtFptr) wasm.uninstallFunction(fp); + __autoExtFptr.clear(); + }; + }/* auto-extension */ const pKvvfs = capi.sqlite3_vfs_find("kvvfs"); if( pKvvfs ){/* kvvfs-specific glue */ diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 9b946b24be..e50210206f 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -1560,6 +1560,10 @@ self.WhWasmUtilInstaller = function(target){ context. This mode is the default if bindScope is _not_ set but a property named contextKey (described below) is. + - 'permanent': the function is installed and left there + forever. There is no way to recover its pointer address + later on. + - callProxy (function): if set, this must be a function which will act as a proxy for any "converted" JS function. It is passed the being-converted function value and must return @@ -1645,6 +1649,7 @@ self.WhWasmUtilInstaller = function(target){ } this.isTransient = 'transient'===this.bindScope; this.isContext = 'context'===this.bindScope; + this.isPermanent = 'permanent'===this.bindScope; this.singleton = ('singleton'===this.bindScope) ? [] : undefined; //console.warn("FuncPtrAdapter()",opt,this); this.callProxy = (opt.callProxy instanceof Function) @@ -1668,7 +1673,7 @@ self.WhWasmUtilInstaller = function(target){ static debugOut = console.debug.bind(console); static bindScopes = [ - 'transient', 'context', 'singleton' + 'transient', 'context', 'singleton', 'permanent' ]; /* Dummy impl. Overwritten per-instance as needed. */ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 0c15bc063b..7cb6c260eb 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -2687,6 +2687,30 @@ self.sqlite3InitModule = sqlite3InitModule; }/*OPFS util sanity checks*/) ;/* end OPFS tests */ + //////////////////////////////////////////////////////////////////////// + T.g('Auto-extension API') + .t({ + name: "Auto-extension sanity checks.", + test: function(sqlite3){ + let counter = 0; + const fp = wasm.installFunction('i(ppp)', function(pDb,pzErr,pApi){ + ++counter; + return 0; + }); + (new sqlite3.oo1.DB()).close(); + T.assert( 0===counter ); + capi.sqlite3_auto_extension(fp); + (new sqlite3.oo1.DB()).close(); + T.assert( 1===counter ); + (new sqlite3.oo1.DB()).close(); + T.assert( 2===counter ); + capi.sqlite3_cancel_auto_extension(fp); + wasm.uninstallFunction(fp); + (new sqlite3.oo1.DB()).close(); + T.assert( 2===counter ); + } + }); + //////////////////////////////////////////////////////////////////////// T.g('Session API') .t({ diff --git a/manifest b/manifest index 3301f5499c..0b5563055d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinfinite\sloop\sin\sthe\sMEMSYS5\sauxiliary\smemory\sallocator\sthat\soccurs\nfor\smemory\sallocations\sbetween\s1GiB\sand\s2GiB\sin\ssize.\s\sError\sintroduced\nby\scheck-in\s[949133231f8f751a].\s\sThe\sproblem\sonly\saffects\sbuilds\sthat\ninclude\sthe\sSQLITE_ENABLE_MEMSYS5\scompile-time\soption. -D 2022-12-26T15:14:24.028 +C Expose\sthe\sauto-extension\sAPI\sto\sJS\sand\sreorganize\ssome\snearby\scode. +D 2022-12-26T17:15:05.417 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile ffe0e9818a3b6b36c85a1d10dab76b220a8f5cd83439c62e50223a7970b3d68a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api beec6b5993e234153446aaa48e68d2a75db590b3c7eed26bd61e5fb5f8c9a881 +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 1e61a3ff4085974080ecf782d4defea6b7d443eaa98f9aea773b5f5b416b417c F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js e16bf1de4c08d3906298d532e1e61478791286e768d7ba1538ca90d0fa344e12 +F ext/wasm/api/sqlite3-api-glue.js b55e13aadf33a037e9a6950f370d16e2b0e858b74a2070faa2c87d7cde48c80c F ext/wasm/api/sqlite3-api-oo1.js 045c98796950c22556fc0842fe9f0d9a67f31920f247e24fb440571cdb6be5b0 F ext/wasm/api/sqlite3-api-prologue.js e862e5b79d565bd79c8ff59ebb6618a07ecb1a0262a1560dc6a10aa0f4d6f531 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07 F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 63188a5b90de3c17a2fdf3f1a90321ffdeaa2c34f6ca9d76f830fb0800867854 +F ext/wasm/common/whwasmutil.js cad510071533dbe47787bce53f2e0dcab5b05d2dde1dbe477d8fb04e00d4e8c4 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 4a5b1a1f5296686f04db017e5984230a266f2c09f1e8d25d76682566b5cacbc2 +F ext/wasm/tester1.c-pp.js 93e3ebae7f0caa1b54265447f76b0485d4a28799e02b7c2a3cc92883aa84fda6 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ae3ae92ec45d3d5de92e70876502f8108fc3fcd87848e86c2b83f8842f1ff139 -R af6df6d036a8bd991cf092623d05af75 -U drh -Z 333253e835d0b6bf644788ba3ea65af5 +P 8da0f0c38a458c57f979d59b49cf4804ef81fc2eccabde1f166bab24dd1dabea +R c287fdd5af6e6026238c7a465fc6dd21 +U stephan +Z 8fd2961047ac7596d6fac75a1b2c944b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index be2a3ca6de..68fae69eb3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8da0f0c38a458c57f979d59b49cf4804ef81fc2eccabde1f166bab24dd1dabea \ No newline at end of file +52b229d11d82bfb81c8b63e252c51c57a34dc50498dd685451588c185873c628 \ No newline at end of file From c8f245ab5cebef696de1a59d4568722634b4aaa2 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 27 Dec 2022 11:40:05 +0000 Subject: [PATCH 050/165] Add an optional argument to oo1.DB.transaction() to specify an explicit BEGIN qualifier. FossilOrigin-Name: 507335c12b1dbe21d180cf6f0a0deb4cc737417acb44c8f1d8fac98b86f62b01 --- ext/wasm/api/sqlite3-api-oo1.js | 20 ++++++++++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index f72def751e..ba210e7f99 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -1180,9 +1180,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Note that transactions may not be nested, so this will throw if it is called recursively. For nested transactions, use the savepoint() method or manually manage SAVEPOINTs using exec(). + + If called with 2 arguments, the first must be a keyword which + is legal immediately after a BEGIN statement, e.g. one of + "DEFERRED", "IMMEDIATE", or "EXCLUSIVE". Though the exact list + of supported keywords is not hard-coded here, in order to be + future-compatible, if the argument does not look like a single + keyword then an exception is triggered with a description of + the problem. */ - transaction: function(callback){ - affirmDbOpen(this).exec("BEGIN"); + transaction: function(/* [beginQualifier,] */callback){ + let opener = 'BEGIN'; + if(arguments.length>1){ + if(/[^a-zA-Z]/.test(arguments[0])){ + toss3(capi.SQLITE_MISUSE, "Invalid argument for BEGIN qualifier."); + } + opener += ' '+arguments[0]; + callback = arguments[1]; + } + affirmDbOpen(this).exec(opener); try { const rc = callback(this); this.exec("COMMIT"); diff --git a/manifest b/manifest index 0b5563055d..90f98310f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expose\sthe\sauto-extension\sAPI\sto\sJS\sand\sreorganize\ssome\snearby\scode. -D 2022-12-26T17:15:05.417 +C Add\san\soptional\sargument\sto\soo1.DB.transaction()\sto\sspecify\san\sexplicit\sBEGIN\squalifier. +D 2022-12-27T11:40:05.031 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 F ext/wasm/api/sqlite3-api-glue.js b55e13aadf33a037e9a6950f370d16e2b0e858b74a2070faa2c87d7cde48c80c -F ext/wasm/api/sqlite3-api-oo1.js 045c98796950c22556fc0842fe9f0d9a67f31920f247e24fb440571cdb6be5b0 +F ext/wasm/api/sqlite3-api-oo1.js e9fba119e9b1716b3f731838ed1ab18741401bcf4c51d2a4a6e9d1d23cf9d771 F ext/wasm/api/sqlite3-api-prologue.js e862e5b79d565bd79c8ff59ebb6618a07ecb1a0262a1560dc6a10aa0f4d6f531 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8da0f0c38a458c57f979d59b49cf4804ef81fc2eccabde1f166bab24dd1dabea -R c287fdd5af6e6026238c7a465fc6dd21 +P 52b229d11d82bfb81c8b63e252c51c57a34dc50498dd685451588c185873c628 +R 907b947f3596b78852af2b253c74cbfb U stephan -Z 8fd2961047ac7596d6fac75a1b2c944b +Z 14582b10a3620eea75adde1bd5a1eeb7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 68fae69eb3..a86e29ff13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52b229d11d82bfb81c8b63e252c51c57a34dc50498dd685451588c185873c628 \ No newline at end of file +507335c12b1dbe21d180cf6f0a0deb4cc737417acb44c8f1d8fac98b86f62b01 \ No newline at end of file From 55a21fbcef97b5cbcc3b0d692ebd21741156b8da Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 27 Dec 2022 12:13:01 +0000 Subject: [PATCH 051/165] Expose sqlite3_commit/rollback/update_hook() to JS API. FossilOrigin-Name: f99f8e3ecfe205337996ee61c0b9f139d3e8788b14f32e26560888b3a16564de --- ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api | 3 + ext/wasm/api/sqlite3-api-glue.js | 39 +++++++++- ext/wasm/tester1.c-pp.js | 82 +++++++++++++++++++++ manifest | 16 ++-- manifest.uuid | 2 +- 5 files changed, 131 insertions(+), 11 deletions(-) diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api index 8ba6e515c5..93ab8b7950 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api @@ -31,6 +31,7 @@ _sqlite3_column_name _sqlite3_column_text _sqlite3_column_type _sqlite3_column_value +_sqlite3_commit_hook _sqlite3_compileoption_get _sqlite3_compileoption_used _sqlite3_complete @@ -98,6 +99,7 @@ _sqlite3_result_subtype _sqlite3_result_text _sqlite3_result_zeroblob _sqlite3_result_zeroblob64 +_sqlite3_rollback_hook _sqlite3_serialize _sqlite3_set_authorizer _sqlite3_set_auxdata @@ -120,6 +122,7 @@ _sqlite3_total_changes _sqlite3_total_changes64 _sqlite3_trace_v2 _sqlite3_txn_state +_sqlite3_update_hook _sqlite3_uri_boolean _sqlite3_uri_int64 _sqlite3_uri_key diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index ddb4a58fa6..e8fe5aba6b 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -103,6 +103,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_column_text","string", "sqlite3_stmt*", "int"], ["sqlite3_column_type","int", "sqlite3_stmt*", "int"], ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"], + ["sqlite3_commit_hook", "void*", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_commit_hook', + signature: 'i(p)', + contextKey: (argv)=>argv[0/* sqlite3* */] + }), + '*' + ]], ["sqlite3_compileoption_get", "string", "int"], ["sqlite3_compileoption_used", "int", "string"], ["sqlite3_complete", "int", "string:flexible"], @@ -206,6 +215,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_result_subtype", undefined, "sqlite3_value*", "int"], ["sqlite3_result_text", undefined, "sqlite3_context*", "string", "int", "*"], ["sqlite3_result_zeroblob", undefined, "sqlite3_context*", "int"], + ["sqlite3_rollback_hook", "void*", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_rollback_hook', + signature: 'v(p)', + contextKey: (argv)=>argv[0/* sqlite3* */] + }), + '*' + ]], ["sqlite3_set_authorizer", "int", [ "sqlite3*", new wasm.xWrap.FuncPtrAdapter({ @@ -327,6 +345,20 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_set_last_insert_rowid", undefined, ["sqlite3*", "i64"]], ["sqlite3_status64", "int", "int", "*", "*", "int"], ["sqlite3_total_changes64", "i64", ["sqlite3*"]], + ["sqlite3_update_hook", "*", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_update_hook', + signature: "v(iippj)", + contextKey: (argv)=>argv[0/* sqlite3* */], + callProxy: (callback)=>{ + return (p,op,z0,z1,rowid)=>{ + callback(p, op, wasm.cstrToJs(z0), wasm.cstrToJs(z1), rowid); + }; + } + }), + "*" + ]], ["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]], ["sqlite3_value_int64","i64", "sqlite3_value*"], ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"], @@ -704,7 +736,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ message = message || ''+resultCode; resultCode = (resultCode.resultCode || capi.SQLITE_ERROR); } - return __db_err(pDb, resultCode, message); + return pDb ? __db_err(pDb, resultCode, message) : resultCode; }; }else{ util.sqlite3_wasm_db_error = function(pDb,errCode,msg){ @@ -891,9 +923,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ installed for pDb. */ try{capi.sqlite3_busy_handler(pDb, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_commit_hook(pDb, 0, 0)} catch(e){/*ignored*/} try{capi.sqlite3_progress_handler(pDb, 0, 0, 0)} catch(e){/*ignored*/} - try{capi.sqlite3_trace_v2(pDb, 0, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_rollback_hook(pDb, 0, 0)} catch(e){/*ignored*/} try{capi.sqlite3_set_authorizer(pDb, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_trace_v2(pDb, 0, 0, 0, 0)} catch(e){/*ignored*/} + try{capi.sqlite3_update_hook(pDb, 0, 0)} catch(e){/*ignored*/} const m = __dbCleanupMap(pDb, 0); if(!m) return; if(m.collation){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 7cb6c260eb..2f085650c5 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -2687,6 +2687,88 @@ self.sqlite3InitModule = sqlite3InitModule; }/*OPFS util sanity checks*/) ;/* end OPFS tests */ + //////////////////////////////////////////////////////////////////////// + T.g('Hook APIs') + .t({ + name: "Commit/update/rollback hooks.", + predicate: ()=>wasm.bigIntEnabled || "Update hook requires int64", + test: function(sqlite3){ + let countCommit = 0, countRollback = 0;; + const db = new sqlite3.oo1.DB(':memory:',1 ? 'c' : 'ct'); + let rc = capi.sqlite3_commit_hook(db, (p)=>{ + ++countCommit; + return (1 === p) ? 0 : capi.SQLITE_ERROR; + }, 1); + T.assert( 0 === rc /*void pointer*/ ); + + // Commit hook... + db.exec("BEGIN; SELECT 1; COMMIT"); + T.assert(0 === countCommit, + "No-op transactions (mostly) do not trigger commit hook."); + db.exec("BEGIN EXCLUSIVE; SELECT 1; COMMIT"); + T.assert(1 === countCommit, + "But EXCLUSIVE transactions do."); + db.transaction((d)=>{d.exec("create table t(a)");}); + T.assert(2 === countCommit); + + // Rollback hook: + rc = capi.sqlite3_rollback_hook(db, (p)=>{ + ++countRollback; + T.assert( 2 === p ); + }, 2); + T.assert( 0 === rc /*void pointer*/ ); + T.mustThrowMatching(()=>{ + db.transaction('drop table t',()=>{}) + }, (e)=>{ + return (capi.SQLITE_MISUSE === e.resultCode) + && ( e.message.indexOf('Invalid argument') > 0 ); + }); + T.assert(0 === countRollback, "Transaction was not started."); + T.mustThrowMatching(()=>{ + db.transaction('immediate', ()=>{ + sqlite3.SQLite3Error.toss(capi.SQLITE_FULL,'testing rollback hook'); + }); + }, (e)=>{ + return capi.SQLITE_FULL === e.resultCode + }); + T.assert(1 === countRollback); + + // Update hook... + const countUpdate = Object.create(null); + capi.sqlite3_update_hook(db, (p,op,db,tbl,rowid)=>{ + switch(op){ + case capi.SQLITE_INSERT: + case capi.SQLITE_UPDATE: + case capi.SQLITE_DELETE: + countUpdate[op] = (countUpdate[op]||0) + 1; + break; + default: return; + } + T.assert(3===p).assert('bigint' === typeof rowid); + }, 3); + db.transaction((d)=>{ + d.exec([ + "insert into t(a) values(1);", + "update t set a=2;", + "update t set a=3;", + "delete from t where a=3" + // update hook is not called for an unqualified DELETE + ]); + }); + T.assert(1 === countRollback) + .assert(3 === countCommit) + .assert(1 === countUpdate[capi.SQLITE_INSERT]) + .assert(2 === countUpdate[capi.SQLITE_UPDATE]) + .assert(1 === countUpdate[capi.SQLITE_DELETE]); + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = true; + T.assert(1 === capi.sqlite3_commit_hook(db, 0, 0)); + T.assert(2 === capi.sqlite3_rollback_hook(db, 0, 0)); + T.assert(3 === capi.sqlite3_update_hook(db, 0, 0)); + //wasm.xWrap.FuncPtrAdapter.debugFuncInstall = false; + db.close(); + } + }); + //////////////////////////////////////////////////////////////////////// T.g('Auto-extension API') .t({ diff --git a/manifest b/manifest index 90f98310f7..59b4ef7d55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\soptional\sargument\sto\soo1.DB.transaction()\sto\sspecify\san\sexplicit\sBEGIN\squalifier. -D 2022-12-27T11:40:05.031 +C Expose\ssqlite3_commit/rollback/update_hook()\sto\sJS\sAPI. +D 2022-12-27T12:13:01.660 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce F ext/wasm/GNUmakefile ffe0e9818a3b6b36c85a1d10dab76b220a8f5cd83439c62e50223a7970b3d68a F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 1e61a3ff4085974080ecf782d4defea6b7d443eaa98f9aea773b5f5b416b417c +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 445ae63749f47c50c251de53388ca2d1247f06b62f71289d3d2b9c3cee014575 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d @@ -503,7 +503,7 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 -F ext/wasm/api/sqlite3-api-glue.js b55e13aadf33a037e9a6950f370d16e2b0e858b74a2070faa2c87d7cde48c80c +F ext/wasm/api/sqlite3-api-glue.js 7d619834cc0d378e9f46afc1eab0587f8f097944936aff5723da7243f36bc787 F ext/wasm/api/sqlite3-api-oo1.js e9fba119e9b1716b3f731838ed1ab18741401bcf4c51d2a4a6e9d1d23cf9d771 F ext/wasm/api/sqlite3-api-prologue.js e862e5b79d565bd79c8ff59ebb6618a07ecb1a0262a1560dc6a10aa0f4d6f531 F ext/wasm/api/sqlite3-api-worker1.js c9ef8865f072e61251260b218aa4ed614a21a25e9e3cc6f22acf81794d32fc0b @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 93e3ebae7f0caa1b54265447f76b0485d4a28799e02b7c2a3cc92883aa84fda6 +F ext/wasm/tester1.c-pp.js e183830a1c09e9535fea0f28ad8ed60049797d0461450e590f39e61aee48ae81 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 52b229d11d82bfb81c8b63e252c51c57a34dc50498dd685451588c185873c628 -R 907b947f3596b78852af2b253c74cbfb +P 507335c12b1dbe21d180cf6f0a0deb4cc737417acb44c8f1d8fac98b86f62b01 +R 1861a6bdb0fe2e8302265dde3d3ce972 U stephan -Z 14582b10a3620eea75adde1bd5a1eeb7 +Z 65af223f5379fb35b8546fe3024152a5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a86e29ff13..6fc68debea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -507335c12b1dbe21d180cf6f0a0deb4cc737417acb44c8f1d8fac98b86f62b01 \ No newline at end of file +f99f8e3ecfe205337996ee61c0b9f139d3e8788b14f32e26560888b3a16564de \ No newline at end of file From 69d8b3636e955b201d0f6ba5f05453a0baeb6785 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 27 Dec 2022 12:17:20 +0000 Subject: [PATCH 052/165] Add two more tests to [f99f8e3ecfe20]. FossilOrigin-Name: 9cffccd335b11feb6a5beadb26e1a68af7b6b1b3c953063dcf6ef74edf3c59b1 --- ext/wasm/tester1.c-pp.js | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 2f085650c5..c5b1a6e4be 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -2735,7 +2735,11 @@ self.sqlite3InitModule = sqlite3InitModule; // Update hook... const countUpdate = Object.create(null); - capi.sqlite3_update_hook(db, (p,op,db,tbl,rowid)=>{ + capi.sqlite3_update_hook(db, (p,op,dbName,tbl,rowid)=>{ + T.assert('main' === dbName.toLowerCase()) + .assert('t' === tbl.toLowerCase()) + .assert(3===p) + .assert('bigint' === typeof rowid); switch(op){ case capi.SQLITE_INSERT: case capi.SQLITE_UPDATE: @@ -2744,7 +2748,6 @@ self.sqlite3InitModule = sqlite3InitModule; break; default: return; } - T.assert(3===p).assert('bigint' === typeof rowid); }, 3); db.transaction((d)=>{ d.exec([ diff --git a/manifest b/manifest index 59b4ef7d55..dd2bb06f26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expose\ssqlite3_commit/rollback/update_hook()\sto\sJS\sAPI. -D 2022-12-27T12:13:01.660 +C Add\stwo\smore\stests\sto\s[f99f8e3ecfe20]. +D 2022-12-27T12:17:20.531 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js e183830a1c09e9535fea0f28ad8ed60049797d0461450e590f39e61aee48ae81 +F ext/wasm/tester1.c-pp.js 1c14fd42a66e22204bf9444f03f06a25f326cce495475b215caf0b946cc7ec15 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 507335c12b1dbe21d180cf6f0a0deb4cc737417acb44c8f1d8fac98b86f62b01 -R 1861a6bdb0fe2e8302265dde3d3ce972 +P f99f8e3ecfe205337996ee61c0b9f139d3e8788b14f32e26560888b3a16564de +R 51d3334085c220c05328003abe0ae370 U stephan -Z 65af223f5379fb35b8546fe3024152a5 +Z f6ae1936446bb6550f102dedb48b83c9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6fc68debea..d159d2bf61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f99f8e3ecfe205337996ee61c0b9f139d3e8788b14f32e26560888b3a16564de \ No newline at end of file +9cffccd335b11feb6a5beadb26e1a68af7b6b1b3c953063dcf6ef74edf3c59b1 \ No newline at end of file From de75c9c5a063663ab03a87193cc90cd44c890c53 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 27 Dec 2022 12:25:28 +0000 Subject: [PATCH 053/165] Add links to module-symbols.html for newly-added APIs. FossilOrigin-Name: 335ef03eb9694d1fd123f113f235cd34e97834fadc5f7c80489b6513be45d070 --- ext/wasm/module-symbols.html | 6 ++++++ ext/wasm/tester1.c-pp.js | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ext/wasm/module-symbols.html b/ext/wasm/module-symbols.html index ff9c9769dc..865f1b3338 100644 --- a/ext/wasm/module-symbols.html +++ b/ext/wasm/module-symbols.html @@ -194,6 +194,7 @@ diff --git a/manifest b/manifest index 99b0ff4c5e..6275e3d92e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sassume\sthat\ssub-queries\sthat\scontain\swindow\sfunctions\sare\suncorrelated. -D 2023-01-28T21:06:15.825 +C Correct\sthe\shandling\sof\sthe\sworker1\sand\spromiser\sJS\sfiles\sin\sthe\sface\sof\sthe\sbundler-friendly\schanges.\sThose\sfiles\srequire\sseparate,\sbundler-friendly\scopies. +D 2023-01-29T05:09:39.456 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -466,8 +466,8 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 6fee35e99b82c948a1a4675bb4d1d037800c2171274bd8ab3779fac53aca6d1a -F ext/wasm/README-dist.txt 4a1db3677d0341a12434d1fd6c97aae2f96785d734641407a201b719f5d94f44 +F ext/wasm/GNUmakefile 5418b4702f4ad0f2162a7e0d128042e8d9219827e3d36978bd2dd6e26ce8f68e +F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 @@ -506,14 +506,14 @@ F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98 F ext/wasm/demo-worker1-promiser.js b99c550763fa792c204e9a7cceadd976004036d9fc3e22fab7051712e30d207d F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js a619adffc98b75b66c633b00f747b856449a134a9a0357909287d80a182d70fa -F ext/wasm/dist.make b50668a4f79d4464a59c3378b6b53968bb0652a06737b1e0b07544458de28f3d +F ext/wasm/dist.make 836176877b8d4ae1d4217dcc1f3c057c7d7c5546df012532b9f5ff83061b24fd F ext/wasm/fiddle.make d5308b5c35f691758ef20badd25f91f3780b20415760daf0d98afbe4f24921b9 F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/fiddle/fiddle-worker.js b4a0c8ab6c0983218543ca771c45f6075449f63a1dcf290ae5a681b2cba8800d F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715 F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2 F ext/wasm/index-dist.html c806b6005145b71d64240606e9c6e0bf56878ee8829c66fe7486cebf34b0e6b1 -F ext/wasm/index.html cc8b174ff01be282b399e64b58bdf3c921d7020da5d4e22e88bbbb4a6787a209 +F ext/wasm/index.html 6b7139e64eef500aee9315deac5e4ac84ef31453aaf053b794bb0505859dcde5 F ext/wasm/jaccwabyt/jaccwabyt.js 06f2ef1ad640c26c593def3d960336e9bb789819b920516480895c38ed5f58fa F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10 @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3d05dddd0bc826a73a8cecd6b116168082fb46b6e4868d03438c0a5a546d2f97 -R 15c7aa257d7f9f8322c2cff93b9d4aee -U dan -Z b5cdea142483e57c2a66955139fc295d +P f27804484df57de76be9dbd1a9e5869916617684ee407101c978df7da30b34ac +R 667e12e7399fd0840589fd5b12faf9a7 +U stephan +Z 6f0092c7605698427bc685848784d5f5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b782372af7..6a5ce342cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f27804484df57de76be9dbd1a9e5869916617684ee407101c978df7da30b34ac \ No newline at end of file +9062b31174618c0e67e86441e14eac420c734a0cc321f7eebc7d89ff8a449c10 \ No newline at end of file From 26c7cff254b09285c41e82656f5fa53cd7ce95f8 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 29 Jan 2023 06:01:32 +0000 Subject: [PATCH 158/165] Two JS file renames which got inadvertently undone while setting up [9062b31174618c0e]. Cosmetic cleanups in ext/wasm/dist.make. FossilOrigin-Name: 0c2fde767f77d6204e95737edd573f42d72e956a3c20ea7e4daeff906657bbe5 --- ...miser.js => sqlite3-worker1-promiser.c-pp.js} | 0 ...qlite3-worker1.js => sqlite3-worker1.c-pp.js} | 0 ext/wasm/dist.make | 13 ++++++++----- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) rename ext/wasm/api/{sqlite3-worker1-promiser.js => sqlite3-worker1-promiser.c-pp.js} (100%) rename ext/wasm/api/{sqlite3-worker1.js => sqlite3-worker1.c-pp.js} (100%) diff --git a/ext/wasm/api/sqlite3-worker1-promiser.js b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js similarity index 100% rename from ext/wasm/api/sqlite3-worker1-promiser.js rename to ext/wasm/api/sqlite3-worker1-promiser.c-pp.js diff --git a/ext/wasm/api/sqlite3-worker1.js b/ext/wasm/api/sqlite3-worker1.c-pp.js similarity index 100% rename from ext/wasm/api/sqlite3-worker1.js rename to ext/wasm/api/sqlite3-worker1.c-pp.js diff --git a/ext/wasm/dist.make b/ext/wasm/dist.make index d2fa920be7..7073c24b78 100644 --- a/ext/wasm/dist.make +++ b/ext/wasm/dist.make @@ -56,10 +56,13 @@ dist.common.extras := \ $(dir.common)/SqliteTestUtil.js .PHONY: dist snapshot +# DIST_STRIP_COMMENTS $(call)able to be used in stripping C-style +# from the dist copies of certain files. +# +# $1 = source js file +# $2 = flags for $(bin.stripcomments) define DIST_STRIP_COMMENTS -# $1 = source js file -# $2 = flags for $(bin.stripcomments) -$(bin.stripccomments) $(2) < $(1) > $(dist-dir.jswasm)/$(notdir $(1)); +$(bin.stripccomments) $(2) < $(1) > $(dist-dir.jswasm)/$(notdir $(1)) || exit; endef # STRIP_K1.js = list of JS files which need to be passed through # $(bin.stripcomments) with a single -k flag. @@ -92,8 +95,8 @@ dist: \ @cp -p README-dist.txt $(dist-dir.top)/README.txt @cp -p index-dist.html $(dist-dir.top)/index.html @cp -p $(dist.jswasm.extras) $(dist-dir.jswasm) - $(foreach JS,$(STRIP_K1.js),$(call DIST_STRIP_COMMENTS,$(JS),-k)) - $(foreach JS,$(STRIP_K2.js),$(call DIST_STRIP_COMMENTS,$(JS),-k -k)) + @$(foreach JS,$(STRIP_K1.js),$(call DIST_STRIP_COMMENTS,$(JS),-k)) + @$(foreach JS,$(STRIP_K2.js),$(call DIST_STRIP_COMMENTS,$(JS),-k -k)) @cp -p $(dist.common.extras) $(dist-dir.common) @set -e; \ vnum=$$($(bin.version-info) --download-version); \ diff --git a/manifest b/manifest index 6275e3d92e..fd561474b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sthe\shandling\sof\sthe\sworker1\sand\spromiser\sJS\sfiles\sin\sthe\sface\sof\sthe\sbundler-friendly\schanges.\sThose\sfiles\srequire\sseparate,\sbundler-friendly\scopies. -D 2023-01-29T05:09:39.456 +C Two\sJS\sfile\srenames\swhich\sgot\sinadvertently\sundone\swhile\ssetting\sup\s[9062b31174618c0e].\sCosmetic\scleanups\sin\sext/wasm/dist.make. +D 2023-01-29T06:01:32.206 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,8 +488,8 @@ F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d17283185 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js a10bdc9695dcf453e120970a5de8a3e61db4e4047d0a7cc5a6d63dfe7ae87f4e F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasm.c 76625a70937a8522d014ef686c32db5b53a3ee61850323f5c601d2ac39fe52fe -F ext/wasm/api/sqlite3-worker1-promiser.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a -F ext/wasm/api/sqlite3-worker1.js 77b3835192469e9da23926ec8f78fb0b114a51d048dc54388709ac22b5c5f0a0 +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a w ext/wasm/api/sqlite3-worker1-promiser.js +F ext/wasm/api/sqlite3-worker1.c-pp.js 77b3835192469e9da23926ec8f78fb0b114a51d048dc54388709ac22b5c5f0a0 w ext/wasm/api/sqlite3-worker1.js F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4 @@ -506,7 +506,7 @@ F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98 F ext/wasm/demo-worker1-promiser.js b99c550763fa792c204e9a7cceadd976004036d9fc3e22fab7051712e30d207d F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js a619adffc98b75b66c633b00f747b856449a134a9a0357909287d80a182d70fa -F ext/wasm/dist.make 836176877b8d4ae1d4217dcc1f3c057c7d7c5546df012532b9f5ff83061b24fd +F ext/wasm/dist.make f55f9c9e1980ea11a59964e59535c66175a17f004d1c2e274522c3366b3a084a F ext/wasm/fiddle.make d5308b5c35f691758ef20badd25f91f3780b20415760daf0d98afbe4f24921b9 F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/fiddle/fiddle-worker.js b4a0c8ab6c0983218543ca771c45f6075449f63a1dcf290ae5a681b2cba8800d @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f27804484df57de76be9dbd1a9e5869916617684ee407101c978df7da30b34ac -R 667e12e7399fd0840589fd5b12faf9a7 +P 9062b31174618c0e67e86441e14eac420c734a0cc321f7eebc7d89ff8a449c10 +R 8f85e81de3851592997fc03573edca4f U stephan -Z 6f0092c7605698427bc685848784d5f5 +Z bfd47a7c26f55476ee645fdcf247a796 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6a5ce342cf..33c1027661 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9062b31174618c0e67e86441e14eac420c734a0cc321f7eebc7d89ff8a449c10 \ No newline at end of file +0c2fde767f77d6204e95737edd573f42d72e956a3c20ea7e4daeff906657bbe5 \ No newline at end of file From f7af9ba13cb7ef413c5202d12678a475ed1234c9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jan 2023 20:44:54 +0000 Subject: [PATCH 159/165] Additional tweaks to the enhancement at [609fbb94b8f01d67] to further reduce the cost estimate for constructing an automatic index on an ephemeral table, in order to resolve the performance problem described by [forum:/forumpost/1d571c0296|forum post 1d571c0296]. FossilOrigin-Name: bf1aae7a8c7f2c74681aa29baa35259d10ce6a1737d2607def6bf27fed592131 --- manifest | 20 +++++++------- manifest.uuid | 2 +- src/where.c | 3 ++- test/where.test | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index fd561474b9..7b52f050f3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Two\sJS\sfile\srenames\swhich\sgot\sinadvertently\sundone\swhile\ssetting\sup\s[9062b31174618c0e].\sCosmetic\scleanups\sin\sext/wasm/dist.make. -D 2023-01-29T06:01:32.206 +C Additional\stweaks\sto\sthe\senhancement\sat\s[609fbb94b8f01d67]\sto\sfurther\sreduce\nthe\scost\sestimate\sfor\sconstructing\san\sautomatic\sindex\son\san\sephemeral\stable,\nin\sorder\sto\sresolve\sthe\sperformance\sproblem\sdescribed\sby\n[forum:/forumpost/1d571c0296|forum\spost\s1d571c0296]. +D 2023-01-30T20:44:54.399 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -488,8 +488,8 @@ F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d17283185 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js a10bdc9695dcf453e120970a5de8a3e61db4e4047d0a7cc5a6d63dfe7ae87f4e F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasm.c 76625a70937a8522d014ef686c32db5b53a3ee61850323f5c601d2ac39fe52fe -F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a w ext/wasm/api/sqlite3-worker1-promiser.js -F ext/wasm/api/sqlite3-worker1.c-pp.js 77b3835192469e9da23926ec8f78fb0b114a51d048dc54388709ac22b5c5f0a0 w ext/wasm/api/sqlite3-worker1.js +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a +F ext/wasm/api/sqlite3-worker1.c-pp.js 77b3835192469e9da23926ec8f78fb0b114a51d048dc54388709ac22b5c5f0a0 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4 @@ -707,7 +707,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c e75ca01cc4025c0023a4e32c137ad933ecaf1d5fbaf9f88ffae7db216ac2f762 +F src/where.c f180e2fdc93d286b48f23647cc26aab5a5b7437af2d3843f6228aff8d68eb9fe F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c F src/wherecode.c 76bca3379219880d2527493b71a3be49e696f75396d3481e4de5d4ceec7886b2 F src/whereexpr.c 7c5671a04b00c876bec5e99fd4e6f688065feb4773160fbf76fd7900d2901777 @@ -1864,7 +1864,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 1bea58a6a8e68a73f542ee4fca28b771b84ed803bd0c9e385087070b3d747b3c x -F test/where.test 3954cf22ba7b17f9606e177001d2963bcd1ecfbc6e1e7caadb14462f7eecd099 +F test/where.test 26c9e2f5db19c7f90e5b70127f664facd30c0e5c496956ea3a533bcda7fad74a F test/where2.test 03c21a11e7b90e2845fc3c8b4002fc44cc2797fa74c86ee47d70bd7ea4f29ed6 F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67753 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9062b31174618c0e67e86441e14eac420c734a0cc321f7eebc7d89ff8a449c10 -R 8f85e81de3851592997fc03573edca4f -U stephan -Z bfd47a7c26f55476ee645fdcf247a796 +P 0c2fde767f77d6204e95737edd573f42d72e956a3c20ea7e4daeff906657bbe5 +R eff4b53eb789da902d77064ecbd62787 +U drh +Z 55e9959d5ae7e5a9913374f5d774ce27 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33c1027661..bc5d3b3b4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c2fde767f77d6204e95737edd573f42d72e956a3c20ea7e4daeff906657bbe5 \ No newline at end of file +bf1aae7a8c7f2c74681aa29baa35259d10ce6a1737d2607def6bf27fed592131 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 6a9edd028b..51e018c97f 100644 --- a/src/where.c +++ b/src/where.c @@ -3595,7 +3595,8 @@ static int whereLoopAddBtree( if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ pNew->rSetup += 28; }else{ - pNew->rSetup -= 10; + pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes + ** on ephemeral materializations of views */ } ApplyCostMultiplier(pNew->rSetup, pTab->costMult); if( pNew->rSetup<0 ) pNew->rSetup = 0; diff --git a/test/where.test b/test/where.test index 4f7c2f84b2..acc3253819 100644 --- a/test/where.test +++ b/test/where.test @@ -1633,4 +1633,73 @@ do_execsql_test where-29.1 { 1, 1, 1, 1; } {xyz} +# 2023-01-30 +# Tests case for the query planner performance issue reported by +# https://sqlite.org/forum/forumpost/1d571c0296 +# +# The fix was to adjust the cost of computing an automatic index for +# ephemeral tables, to help ensure that they are generated if they are +# needed. The test case below only looks at the query plan. But 12x +# improved performance has been verified by populating the "raw" table +# with 100K rows of random data and running actual speed tests. +# +do_test where-30.1 { + unset -nocomplain res + set res {} + db eval {CREATE TABLE raw(country,date,total,delta, UNIQUE(country,date));} + db eval { + EXPLAIN QUERY PLAN + WITH + -- Find the country and min/max date + init(country, date, fin) AS (SELECT country, min(date), max(date) + FROM raw WHERE total > 0 GROUP BY country), + + -- Generate the date stream for each country + src(country, date) AS (SELECT raw.country, raw.date + FROM raw JOIN init i on raw.country = i.country AND raw.date > i.date + ORDER BY raw.country, raw.date), + + -- Generate the x & y for each entry in the country/date stream + vals(country, date, x, y) AS (SELECT src.country, src.date, + julianday(raw.date) - julianday(src.date), log(delta+1) + FROM src JOIN raw on raw.country = src.country + AND raw.date > date(src.date,'-7 days') + AND raw.date <= src.date AND delta >= 0), + + -- Accumulate the data we need + sums(country, date, x2, x, n, xy, y) AS (SELECT country, date, + sum(x*x*1.0), sum(x*1.0), sum(1.0), sum(x*y*1.0), sum(y*1.0) + FROM vals GROUP BY 1, 2), + + -- use these to calculate to divisor for the inverse matrix + mult(country, date, m) AS (SELECT country, date, 1.0/(x2 * n - x * x) + FROM sums), + + -- Build the inverse matrix + inv(country, date, a,b,c,d) AS (SELECT mult.country, mult.date, n * m, + -x * m, -x * m, x2 * m + FROM mult JOIN sums on sums.country=mult.country + AND mult.date=sums.date), + + -- Calculate the coefficients for the least squares fit + fit(country, date, a, b) AS (SELECT inv.country, inv.date, + a * xy + b * y, c * xy + d * y + FROM inv + JOIN mult on mult.country = inv.country AND mult.date = inv.date + JOIN sums on sums.country = mult.country AND sums.date = mult.date + ) + SELECT *, nFin/nPrev - 1 AS growth, log(2)/log(nFin/nPrev) AS doubling + FROM (SELECT f.*, exp(b) - 1 AS nFin, exp(a* (-1) + b) - 1 AS nPrev + FROM fit f JOIN init i on i.country = f.country + AND f.date <= date(i.fin,'-3 days')) + WHERE nPrev > 0 AND nFin > 0; + } { + if {$parent!=0} continue + if {![string match SCAN* $detail]} continue + lappend res SCAN + } + set res +} {SCAN} +# ^^^^^^-- there should only be one top-level table scan in the query plan. + finish_test From ca3aabdf5397b7e47b24b85dc321dc0e8e4ec749 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 31 Jan 2023 20:21:06 +0000 Subject: [PATCH 160/165] Fix a race condition during hot-journal rollback that could theoretically cause spurious corruption errors. FossilOrigin-Name: 20ea53ddf590a9dd19501fabd2bfdb9c10b5eb265cd2995bdb335769c936c763 --- manifest | 20 ++++--- manifest.uuid | 2 +- src/os_unix.c | 11 ++-- src/test_vfs.c | 5 +- test/pendingrace.test | 123 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 test/pendingrace.test diff --git a/manifest b/manifest index 7b52f050f3..4b7e37fff5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\stweaks\sto\sthe\senhancement\sat\s[609fbb94b8f01d67]\sto\sfurther\sreduce\nthe\scost\sestimate\sfor\sconstructing\san\sautomatic\sindex\son\san\sephemeral\stable,\nin\sorder\sto\sresolve\sthe\sperformance\sproblem\sdescribed\sby\n[forum:/forumpost/1d571c0296|forum\spost\s1d571c0296]. -D 2023-01-30T20:44:54.399 +C Fix\sa\srace\scondition\sduring\shot-journal\srollback\sthat\scould\stheoretically\scause\sspurious\scorruption\serrors. +D 2023-01-31T20:21:06.739 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -604,7 +604,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 9107314500e44908e8d2cdf1ed3333ca5fa17dcfdf9c6a079002b4df90d5f806 +F src/os_unix.c 85096ad0bb4e6a6ac3764603cea0f5332816fa25f0e50c936453edc8ac9acee7 F src/os_win.c 295fe45f18bd86f2477f4cd79f3377c6f883ceb941b1f46808665c73747f2345 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c fc6d3ec7017d7369ab5dc5421ad1763ff224551c9381866b6da69040db62e406 @@ -677,7 +677,7 @@ F src/test_tclsh.c 7dd98be675a1dc0d1fd302b8247bab992c909db384df054381a2279ad76f9 F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc F src/test_thread.c 269ea9e1fa5828dba550eb26f619aa18aedbc29fd92f8a5f6b93521fbb74a61c F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 -F src/test_vfs.c 2cc38a79892017702d13da79ad5152c196eec19bbd67fbde4d88065aac894a84 +F src/test_vfs.c 193c18da3dbf62a0e33ae7a240bbef938a50846672ee947664512b77d853fe81 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215 @@ -1371,6 +1371,7 @@ F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035ce4b3 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 +F test/pendingrace.test fb997b46d6c144a508fb8025d988a1e511b53d42d24143c57b51de3a405c7490 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 4705a032bbfef531bb3fd98b8c6ba4a739998949eae9ac0ea97c8696b331211d F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f @@ -2045,8 +2046,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c2fde767f77d6204e95737edd573f42d72e956a3c20ea7e4daeff906657bbe5 -R eff4b53eb789da902d77064ecbd62787 -U drh -Z 55e9959d5ae7e5a9913374f5d774ce27 +P bf1aae7a8c7f2c74681aa29baa35259d10ce6a1737d2607def6bf27fed592131 +R acc2b6cc65d6bb367d9e15964ca7789d +T *branch * pending-lock-race +T *sym-pending-lock-race * +T -sym-trunk * +U dan +Z 4879461e3eb613f63b1ce94cf45161f5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bc5d3b3b4a..9dd108c7c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf1aae7a8c7f2c74681aa29baa35259d10ce6a1737d2607def6bf27fed592131 \ No newline at end of file +20ea53ddf590a9dd19501fabd2bfdb9c10b5eb265cd2995bdb335769c936c763 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index c3359f1bc7..7c1acc8164 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1652,7 +1652,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ ** UNLOCKED -> SHARED ** SHARED -> RESERVED ** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE +** RESERVED -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. Use the sqlite3OsUnlock() @@ -1767,7 +1767,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ lock.l_len = 1L; lock.l_whence = SEEK_SET; if( eFileLock==SHARED_LOCK - || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockeFileLock==RESERVED_LOCK) ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; @@ -1778,6 +1778,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){ storeLastErrno(pFile, tErrno); } goto end_lock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; } } @@ -1865,13 +1868,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){ } #endif - if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; pInode->eFileLock = eFileLock; - }else if( eFileLock==EXCLUSIVE_LOCK ){ - pFile->eFileLock = PENDING_LOCK; - pInode->eFileLock = PENDING_LOCK; } end_lock: diff --git a/src/test_vfs.c b/src/test_vfs.c index f3e8297ac7..312e1a1be6 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -485,6 +485,9 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){ tvfsExecTcl(p, "xLock", Tcl_NewStringObj(pFd->zFilename, -1), Tcl_NewStringObj(zLock, -1), 0, 0); } + if( p->mask&TESTVFS_LOCK_MASK && tvfsInjectIoerr(p) ){ + return SQLITE_IOERR_LOCK; + } return sqlite3OsLock(pFd->pReal, eLock); } @@ -500,7 +503,7 @@ static int tvfsUnlock(sqlite3_file *pFile, int eLock){ tvfsExecTcl(p, "xUnlock", Tcl_NewStringObj(pFd->zFilename, -1), Tcl_NewStringObj(zLock, -1), 0, 0); } - if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){ + if( p->mask&TESTVFS_UNLOCK_MASK && tvfsInjectIoerr(p) ){ return SQLITE_IOERR_UNLOCK; } return sqlite3OsUnlock(pFd->pReal, eLock); diff --git a/test/pendingrace.test b/test/pendingrace.test new file mode 100644 index 0000000000..645ebbfc80 --- /dev/null +++ b/test/pendingrace.test @@ -0,0 +1,123 @@ +# 2023 January 31 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix pendingrace + +# This test file tests that a race condition surrounding hot-journal +# rollback that once existed has been resolved. The problem was that +# if, when attempting to upgrade from a SHARED to EXCLUSIVE lock in +# order to roll back a hot journal, a connection failed to take the +# lock, the file-descriptor was left holding a PENDING lock for +# a very short amount of time. In a multi-threaded deployment, this +# could allow a second connection to read the database without rolling +# back the hot journal. +# + +testvfs tvfs +db close +sqlite3 db test.db -vfs tvfs + +# Create a 20 page database using connection [db]. Connection [db] uses +# Tcl VFS wrapper "tvfs", but it is configured to do straight pass-through +# for now. +# +do_execsql_test 1.0 { + PRAGMA cache_size = 5; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 + ) + INSERT INTO t1 SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s; + PRAGMA page_count; +} {20} + +# Simulate a crash in another process. This leaves the db with a hot-journal. +# Without the journal the db is corrupt. +# +sqlite3 db2 test.db +do_execsql_test -db db2 1.1 { + PRAGMA cache_size = 5; + BEGIN; + UPDATE t1 SET b=hex(randomblob(100)); +} +db_save +db2 close +proc my_db_restore {} { + forcecopy sv_test.db-journal test.db-journal + + set fd1 [open sv_test.db r] + fconfigure $fd1 -encoding binary -translation binary + set data [read $fd1] + close $fd1 + + set fd1 [open test.db w] + fconfigure $fd1 -encoding binary -translation binary + puts -nonewline $fd1 $data + close $fd1 +} +my_db_restore +do_test 1.2 { + file exists test.db-journal +} {1} + +# Set up connection [db2] to use Tcl VFS wrapper [tvfs2]. Which is configured +# so that the first call to xUnlock() fails. And then all VFS calls thereafter +# fail as well. +# +testvfs tvfs2 +tvfs2 filter xUnlock +tvfs2 script xUnlock +set ::seen_unlock 0 +proc xUnlock {args} { + if {$::seen_unlock==0} { + set ::seen_unlock 1 + tvfs2 ioerr 1 1 + tvfs2 filter {xLock xUnlock} + } + return "" +} +sqlite3 db2 test.db -vfs tvfs2 + +# Configure [tvfs] (used by [db]) so that within the first call to xAccess, +# [db2] attempts to read the db. This causes [db2] to fail to upgrade to +# EXCLUSIVE, leaving it with a PENDING lock. Which it holds on to, +# as the xUnlock() and all subsequent VFS calls fail. +# +tvfs filter xAccess +tvfs script xAccess +set ::seen_access 0 +proc xAccess {args} { + if {$::seen_access==0} { + set ::seen_access 1 + catch { db2 eval { SELECT count(*)+0 FROM t1 } } + breakpoint + } + return "" +} + +# Run an integrity check using [db]. +do_catchsql_test 1.3 { + PRAGMA integrity_check +} {1 {database is locked}} + +db close +db2 close +tvfs delete +tvfs2 delete + +finish_test + + + From 288409d7319625702da13ee0e8e955482d9b99e2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 Feb 2023 14:17:25 +0000 Subject: [PATCH 161/165] Fix a comment related to PENDING locks in os_unix.c. No code changes. FossilOrigin-Name: 6b3546c871fe78a4e550e0144b48ac98325787cc8b192a9e7f5f2a2ffa57f76d --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/os_unix.c | 29 +++++++++++++++-------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 35154f60aa..8db5bd8d45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\srace\scondition\sduring\shot-journal\srollback\son\sunix\sthat\scould\stheoretically\scause\sspurious\scorruption\serrors. -D 2023-01-31T20:43:21.518 +C Fix\sa\scomment\srelated\sto\sPENDING\slocks\sin\sos_unix.c.\sNo\scode\schanges. +D 2023-02-01T14:17:25.856 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -604,7 +604,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 85096ad0bb4e6a6ac3764603cea0f5332816fa25f0e50c936453edc8ac9acee7 +F src/os_unix.c 49b0d3d0f86fc4736d1b9a71035bbd791b892ed6908803f270d4d71f149c60ac F src/os_win.c 295fe45f18bd86f2477f4cd79f3377c6f883ceb941b1f46808665c73747f2345 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c fc6d3ec7017d7369ab5dc5421ad1763ff224551c9381866b6da69040db62e406 @@ -2046,9 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf1aae7a8c7f2c74681aa29baa35259d10ce6a1737d2607def6bf27fed592131 20ea53ddf590a9dd19501fabd2bfdb9c10b5eb265cd2995bdb335769c936c763 -R acc2b6cc65d6bb367d9e15964ca7789d -T +closed 20ea53ddf590a9dd19501fabd2bfdb9c10b5eb265cd2995bdb335769c936c763 +P e365dca4e5775b4897118c8937a1063282d7a1ecc2604529256b0a6b8a3510ba +R fb035ed50ecd9dcfe4baa0545c9c7232 U dan -Z ba4534b9ca16705b4343f518cb36fba2 +Z 000725ab58aa79e849a1ff78f61507a0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 34ffae9075..66baad4780 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e365dca4e5775b4897118c8937a1063282d7a1ecc2604529256b0a6b8a3510ba \ No newline at end of file +6b3546c871fe78a4e550e0144b48ac98325787cc8b192a9e7f5f2a2ffa57f76d \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 7c1acc8164..0990968189 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1651,8 +1651,8 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ ** ** UNLOCKED -> SHARED ** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> EXCLUSIVE +** SHARED -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. Use the sqlite3OsUnlock() @@ -1684,19 +1684,20 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** A RESERVED lock is implemented by grabbing a write-lock on the ** 'reserved byte'. ** - ** A process may only obtain a PENDING lock after it has obtained a - ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock - ** on the 'pending byte'. This ensures that no new SHARED locks can be - ** obtained, but existing SHARED locks are allowed to persist. A process - ** does not have to obtain a RESERVED lock on the way to a PENDING lock. - ** This property is used by the algorithm for rolling back a journal file - ** after a crash. + ** An EXCLUSIVE lock may only be requested after either a SHARED or + ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining + ** a write-lock on the entire 'shared byte range'. Since all other locks + ** require a read-lock on one of the bytes within this range, this ensures + ** that no other locks are held on the database. ** - ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is - ** implemented by obtaining a write-lock on the entire 'shared byte - ** range'. Since all other locks require a read-lock on one of the bytes - ** within this range, this ensures that no other locks are held on the - ** database. + ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then + ** a PENDING lock is obtained first. A PENDING lock is implemented by + ** obtaining a write-lock on the 'pending byte'. This ensures that no new + ** SHARED locks can be obtained, but existing SHARED locks are allowed to + ** persist. If the call to this function fails to obtain the EXCLUSIVE + ** lock in this case, it holds the PENDING lock intead. The client may + ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED + ** locks have cleared. */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; From 54725efd806a410624e6a193f841e7793c732f59 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 1 Feb 2023 15:41:07 +0000 Subject: [PATCH 162/165] Just because a CTE is used more than once, does not mean it should be tagged with M10d_Yes and thereby prohibited from participating in the query flattening optimization. See [forum:/forumpost/1d571c02963355ed|forum thread 1d571c02963]. FossilOrigin-Name: 66f29c403d28630bfaea9124bd63ee4a047b1fe4a7e27dc5d10d67d1601b15e0 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 19 ++++++++++-------- test/with6.test | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 8db5bd8d45..18a6046fe0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\srelated\sto\sPENDING\slocks\sin\sos_unix.c.\sNo\scode\schanges. -D 2023-02-01T14:17:25.856 +C Just\sbecause\sa\sCTE\sis\sused\smore\sthan\sonce,\sdoes\snot\smean\sit\sshould\sbe\ntagged\swith\sM10d_Yes\sand\sthereby\sprohibited\sfrom\sparticipating\sin\sthe\nquery\sflattening\soptimization.\s\sSee\n[forum:/forumpost/1d571c02963355ed|forum\sthread\s1d571c02963]. +D 2023-02-01T15:41:07.645 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -620,7 +620,7 @@ F src/printf.c ff4b05e38bf928ff1b80d3dda4f977b10fe39ecbfe69c018224c7e5594fb2455 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5a98a7bf277aa60584b6bb4c5dd6a9ef2b19537910612c34f596e2901e88596d F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d389ccdb96855dbfaadc22d936889e1f0652ffca17e31a6b6522b45d99daa8ce +F src/select.c c3ce1b49cca2c66c8c88fe7d9e1f3db23590deb4dd631619ad90e1e5d21bcf1f F src/shell.c.in f7fd28e68269a58690c665e8a5e96ba242201267925fbd335f08695c79fc6db7 F src/sqlite.h.in d2a5fc1f6740bd02b571d33d2eb308fa7d1b0fac5b86f6f1fe8310cd49bca97d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1924,7 +1924,7 @@ F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28 F test/with3.test e7bf809bf75c1f44f98bca78bc331dbf542002c5227bf53c1261144db4e824c8 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 -F test/with6.test ae570b31bf1f6fab6210fb1caf6dfa9a6d69c0e6633beb905583bb158a5e309e +F test/with6.test 7afab289442bd0a023c18deef854642932294fa63cdb885a4b4db69e28c5fbf9 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -2046,8 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e365dca4e5775b4897118c8937a1063282d7a1ecc2604529256b0a6b8a3510ba -R fb035ed50ecd9dcfe4baa0545c9c7232 -U dan -Z 000725ab58aa79e849a1ff78f61507a0 +P 6b3546c871fe78a4e550e0144b48ac98325787cc8b192a9e7f5f2a2ffa57f76d +R 70533f1fdb382e48eceffd4225281dd8 +U drh +Z 915bf0e8238a05acb8b086524ea9263b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 66baad4780..3fedf45517 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b3546c871fe78a4e550e0144b48ac98325787cc8b192a9e7f5f2a2ffa57f76d \ No newline at end of file +66f29c403d28630bfaea9124bd63ee4a047b1fe4a7e27dc5d10d67d1601b15e0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d27bed026f..b0e303066a 100644 --- a/src/select.c +++ b/src/select.c @@ -5626,9 +5626,6 @@ static int resolveFromTermToCte( pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; - if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ - pCteUse->eM10d = M10d_Yes; - } /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; @@ -6911,8 +6908,10 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ ** being used as the outer loop if the sqlite3WhereBegin() ** routine nominates it to that position. ** (iii) The query is not a UPDATE ... FROM -** (2) The subquery is not a CTE that should be materialized because of -** the AS MATERIALIZED keywords +** (2) The subquery is not a CTE that should be materialized because +** (a) the AS MATERIALIZED keyword is used, or +** (b) the CTE is used multiple times and does not have the +** NOT MATERIALIZED keyword ** (3) The subquery is not part of a left operand for a RIGHT JOIN ** (4) The SQLITE_Coroutine optimization disable flag is not set ** (5) The subquery is not self-joined @@ -6924,9 +6923,13 @@ static int fromClauseTermCanBeCoroutine( int selFlags /* Flags on the SELECT statement */ ){ SrcItem *pItem = &pTabList->a[i]; - if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ) return 0;/* (2) */ - if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ - if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ + if( pItem->fg.isCte ){ + const CteUse *pCteUse = pItem->u2.pCteUse; + if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ + if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ + } + if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ + if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ return 0; /* (5) */ } diff --git a/test/with6.test b/test/with6.test index 7fce34687e..91d64fa297 100644 --- a/test/with6.test +++ b/test/with6.test @@ -318,5 +318,56 @@ do_eqp_test 331 { `--SCAN t3 } +# 2023-02-01 +# https://sqlite.org/forum/forumpost/1d571c02963355ed +# +# Just because a CTE is used more than once, does not mean it should be +# marked with M10d_Yes and hence prohibited from participating in the +# query flattening optimization. +# +reset_db +db eval { + CREATE TABLE raw(country,date,total,delta, UNIQUE(country,date)); +} +do_eqp_test 400 { + with recursive + init(country, date, fin) AS (SELECT country, min(date), max(date) FROM raw WHERE total > 0 GROUP BY country), + src(country, date) AS (SELECT raw.country, raw.date + FROM raw JOIN init i on raw.country = i.country AND raw.date > i.date + ORDER BY raw.country, raw.date), + vals(country, date, x, y) AS (SELECT src.country, src.date, julianday(raw.date) - julianday(src.date), log(delta+1) + FROM src JOIN raw on raw.country = src.country AND raw.date > date(src.date,'-7 days') AND raw.date <= src.date AND delta >= 0), + sums(country, date, x2, x, n, xy, y) AS (SELECT country, date, sum(x*x*1.0), sum(x*1.0), sum(1.0), sum(x*y*1.0), sum(y*1.0) FROM vals GROUP BY 1, 2), + mult(country, date, m) AS (SELECT country, date, 1.0/(x2 * n - x * x) FROM sums), + inv(country, date, a,b,c,d) AS (SELECT mult.country, mult.date, n * m, -x * m, -x * m, x2 * m + FROM mult JOIN sums on sums.country=mult.country AND mult.date=sums.date), + fit(country, date, a, b) AS (SELECT inv.country, inv.date, a * xy + b * y, c * xy + d * y + FROM inv + JOIN mult on mult.country = inv.country AND mult.date = inv.date + JOIN sums on sums.country = mult.country AND sums.date = mult.date + ) + SELECT *, nFin/nPrev - 1 AS growth, log(2)/log(nFin/nPrev) AS doubling + FROM (SELECT f.*, exp(b) - 1 AS nFin, exp(a* (-1) + b) - 1 AS nPrev + FROM fit f JOIN init i on i.country = f.country AND f.date <= date(i.fin,'-3 days')) + WHERE nPrev > 0 AND nFin > 0; +} { + QUERY PLAN + |--MATERIALIZE sums + | |--MATERIALIZE src + | | |--MATERIALIZE init + | | | `--SCAN raw USING INDEX sqlite_autoindex_raw_1 + | | |--SCAN i + | | |--SEARCH raw USING COVERING INDEX sqlite_autoindex_raw_1 (country=? AND date>?) + | | `--USE TEMP B-TREE FOR ORDER BY + | |--SCAN src + | |--SEARCH raw USING INDEX sqlite_autoindex_raw_1 (country=? AND date>? AND date Date: Wed, 1 Feb 2023 20:45:12 +0000 Subject: [PATCH 163/165] New assert() statements to verify that sqlite3DeleteIndexSamples() is always called with non-NULL parameters. FossilOrigin-Name: 92c71fdd7167a7db055ef0aec522bbba8c7b4b37658efda10dac44699921b57f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 18a6046fe0..0f594a0adc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Just\sbecause\sa\sCTE\sis\sused\smore\sthan\sonce,\sdoes\snot\smean\sit\sshould\sbe\ntagged\swith\sM10d_Yes\sand\sthereby\sprohibited\sfrom\sparticipating\sin\sthe\nquery\sflattening\soptimization.\s\sSee\n[forum:/forumpost/1d571c02963355ed|forum\sthread\s1d571c02963]. -D 2023-02-01T15:41:07.645 +C New\sassert()\sstatements\sto\sverify\sthat\ssqlite3DeleteIndexSamples()\sis\salways\ncalled\swith\snon-NULL\sparameters. +D 2023-02-01T20:45:12.233 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 F src/alter.c 3ca2f449c890f8b86ec9e06f0c4fccf0648941c3308a16904cb2852227db83f7 -F src/analyze.c d2fce73f6a024897593012c6ca25368629fa4aeb49960d88a52fac664582e483 +F src/analyze.c b597c382f23b19cce563211181e84b7e8edddd6871d5f630bbadedb57e562806 F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 @@ -2046,8 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6b3546c871fe78a4e550e0144b48ac98325787cc8b192a9e7f5f2a2ffa57f76d -R 70533f1fdb382e48eceffd4225281dd8 +P 66f29c403d28630bfaea9124bd63ee4a047b1fe4a7e27dc5d10d67d1601b15e0 +R 528d21e7221f87a57110bf960c25518d U drh -Z 915bf0e8238a05acb8b086524ea9263b +Z ab69140996cae547f604b863d81ded55 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3fedf45517..72d83e6db9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66f29c403d28630bfaea9124bd63ee4a047b1fe4a7e27dc5d10d67d1601b15e0 \ No newline at end of file +92c71fdd7167a7db055ef0aec522bbba8c7b4b37658efda10dac44699921b57f \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 8562b9d7f1..f3356ea3ca 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1597,6 +1597,8 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** and its contents. */ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ + assert( db!=0 ); + assert( pIdx!=0 ); #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; @@ -1606,7 +1608,7 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ } sqlite3DbFree(db, pIdx->aSample); } - if( db && db->pnBytesFreed==0 ){ + if( db->pnBytesFreed==0 ){ pIdx->nSample = 0; pIdx->aSample = 0; } From 71a93396727bb457ecb293a713d8f3206d0a9428 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 1 Feb 2023 23:24:34 +0000 Subject: [PATCH 164/165] Adjustments of assert() statement in STAT4 in order to give 100% MC/DC. FossilOrigin-Name: 55a26c67ed4a3a937e009f60da2cd951d6f090b0bea748037db5c1680e5ff3b4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0f594a0adc..487dc17c6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sassert()\sstatements\sto\sverify\sthat\ssqlite3DeleteIndexSamples()\sis\salways\ncalled\swith\snon-NULL\sparameters. -D 2023-02-01T20:45:12.233 +C Adjustments\sof\sassert()\sstatement\sin\sSTAT4\sin\sorder\sto\sgive\s100%\sMC/DC. +D 2023-02-01T23:24:34.683 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -698,7 +698,7 @@ F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb F src/vdbeapi.c 40c47b1528d308a322203de21d2e0d711753257ed9771771b6129214b1d65932 F src/vdbeaux.c 3f9e3b6585e7434aa11300169dd66ddf0fc963a0c6f7940bdc058335dadeb353 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 316d518115f3720b4097f0231e2a3d6eefd06c787eccf44972f8d8f462153421 +F src/vdbemem.c 87d3811aabb68eb9210c14c9a8b5e8ec3acb7ba787beb80a4323af54fb6013f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac @@ -2046,8 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 66f29c403d28630bfaea9124bd63ee4a047b1fe4a7e27dc5d10d67d1601b15e0 -R 528d21e7221f87a57110bf960c25518d +P 92c71fdd7167a7db055ef0aec522bbba8c7b4b37658efda10dac44699921b57f +R 3bed385ef72ee5c0645ae5caa491aa6f U drh -Z ab69140996cae547f604b863d81ded55 +Z 5dbaa2f1ac06834b251752125ac989a8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 72d83e6db9..922d42aaa5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92c71fdd7167a7db055ef0aec522bbba8c7b4b37658efda10dac44699921b57f \ No newline at end of file +55a26c67ed4a3a937e009f60da2cd951d6f090b0bea748037db5c1680e5ff3b4 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index d9909decca..d415f9f72c 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1508,8 +1508,6 @@ static int valueFromFunction( goto value_from_function_out; } - testcase( pCtx->pParse->rc==SQLITE_ERROR ); - testcase( pCtx->pParse->rc==SQLITE_OK ); memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; @@ -1521,11 +1519,14 @@ static int valueFromFunction( }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); + assert( enc==pVal->enc || db->mallocFailed ); +#if 0 /* Not reachable except after a prior failure */ rc = sqlite3VdbeChangeEncoding(pVal, enc); if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; pCtx->pParse->nErr++; } +#endif } pCtx->pParse->rc = rc; From 7667eedf953e42c7a8e6371a59357eeffe6630db Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 2 Feb 2023 06:17:22 +0000 Subject: [PATCH 165/165] Remove automatic installation of JS-global S object for the sake of client libraries which embed this library, per [forum:9d4f722c6912799d|request in the forum]. FossilOrigin-Name: 9504f68af8360ea6d61574fd4b9811af34b721c12d9653eb50adcf0f12b129fc --- ext/wasm/api/sqlite3-api-cleanup.js | 5 ----- ext/wasm/tester1.c-pp.js | 2 ++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-cleanup.js b/ext/wasm/api/sqlite3-api-cleanup.js index 30cd64b053..7c23f8f894 100644 --- a/ext/wasm/api/sqlite3-api-cleanup.js +++ b/ext/wasm/api/sqlite3-api-cleanup.js @@ -51,11 +51,6 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build delete self.sqlite3ApiConfig; } - if(self.location && +self.location.port > 1024){ - console.warn("Installing sqlite3 bits as global S for local dev/test purposes."); - self.S = sqlite3; - } - Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to pass the sqlite3 object off to the client. */; }else{ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 86ec87b73d..2cc0d9ad20 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -3004,6 +3004,8 @@ self.sqlite3InitModule = sqlite3InitModule; }).then(function(sqlite3){ //console.log('sqlite3 =',sqlite3); log("Done initializing WASM/JS bits. Running tests..."); + console.warn("Installing sqlite3 bits as global S for local dev/test purposes."); + self.S = sqlite3; capi = sqlite3.capi; wasm = sqlite3.wasm; log("sqlite3 version:",capi.sqlite3_libversion(), diff --git a/manifest b/manifest index 487dc17c6c..8e2f69fbbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjustments\sof\sassert()\sstatement\sin\sSTAT4\sin\sorder\sto\sgive\s100%\sMC/DC. -D 2023-02-01T23:24:34.683 +C Remove\sautomatic\sinstallation\sof\sJS-global\sS\sobject\sfor\sthe\ssake\sof\sclient\slibraries\swhich\sembed\sthis\slibrary,\sper\s[forum:9d4f722c6912799d|request\sin\sthe\sforum]. +D 2023-02-02T06:17:22.084 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js 9ece5de1bb0509f0a8a360712fcc9c1291b9516c0be5bd66acedd6edbcec37a1 -F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4 +F ext/wasm/api/sqlite3-api-cleanup.js 2d63eb84267a1d15ce002e083d6396a521471da8af3afa76846d50f39a54d65e F ext/wasm/api/sqlite3-api-glue.js 0a93e58aabf52b32ddccbb107a1fd4552f2505e103ab63396c4d0a0743704785 F ext/wasm/api/sqlite3-api-oo1.js f85f4f939f67217d75898e3a32944dd8ae17f11c9a357e78a116150d038c0377 F ext/wasm/api/sqlite3-api-prologue.js 69a74f2777aaafafc07ad2c922674fe3197ef63c921a3262b4772f937e7eb14a @@ -530,7 +530,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html 258d08f1ba9cc2d455958751e26be833893cf9ff7853e9436e593e1f778a386b F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 483fc1393bff4d06e696e6b72ebd1daedb71a46e81cd33d9ede9ca2b5fb76f68 +F ext/wasm/tester1.c-pp.js 9d6252f7b9427fb936f855adf8cf9458049a1d39d440c74601284e1262689f70 F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2046,8 +2046,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 92c71fdd7167a7db055ef0aec522bbba8c7b4b37658efda10dac44699921b57f -R 3bed385ef72ee5c0645ae5caa491aa6f -U drh -Z 5dbaa2f1ac06834b251752125ac989a8 +P 55a26c67ed4a3a937e009f60da2cd951d6f090b0bea748037db5c1680e5ff3b4 +R 9c57120d89d797b8adf616b282c621a9 +U stephan +Z aa2910517eac4f7b9e54b969ac05fd1d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 922d42aaa5..41ebac68e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55a26c67ed4a3a937e009f60da2cd951d6f090b0bea748037db5c1680e5ff3b4 \ No newline at end of file +9504f68af8360ea6d61574fd4b9811af34b721c12d9653eb50adcf0f12b129fc \ No newline at end of file