From 5525ac1049ad73e6ddb1ad444993cc32d9980e4e Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 7 Jun 2024 21:00:42 +0000 Subject: [PATCH 01/88] Experimental optimization to rewrite a SELECT with an EXISTS(...) expression in the WHERE clause as a join. FossilOrigin-Name: 972a33db0b0e924b78d5309d222d8ea298bd59c72da14ea2d14e8e2caaad1e0a --- manifest | 24 ++++--- manifest.uuid | 2 +- src/build.c | 9 ++- src/resolve.c | 1 + src/select.c | 153 +++++++++++++++++++++++++++++++++++++++++++ src/sqliteInt.h | 1 + test/existsexpr.test | 116 ++++++++++++++++++++++++++++++++ 7 files changed, 292 insertions(+), 14 deletions(-) create mode 100644 test/existsexpr.test diff --git a/manifest b/manifest index f28f11b60c..6f4efd9bdc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\squery\splanner\saccess\sto\sthe\sargument\sof\sLIMIT\seven\sif\sthat\nargument\sis\sa\sbound\sparameter. -D 2024-06-06T23:56:36.923 +C Experimental\soptimization\sto\srewrite\sa\sSELECT\swith\san\sEXISTS(...)\sexpression\sin\sthe\sWHERE\sclause\sas\sa\sjoin. +D 2024-06-07T21:00:42.970 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -697,7 +697,7 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 F src/btree.c 8b42fc7d9efdb2df05c30e8f91ff6cfbd979724ae24bf90269028468b7a13333 F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6 -F src/build.c 237ccc0290d131d646be722f418e92ee0a38043aee25e7dfdc75f8ce5b3abe4e +F src/build.c 9e6a971156db6285f726fb03ddd9d47cb0a3648198b611f462021ac96fa24135 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3 @@ -753,14 +753,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 7e8d23ce7cdbfedf351a47e759f2722e8182ca10fd7580be43f4ce1f1a228145 +F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c ea0b75fce45e1f2c22f50ed2b6e2ddd7f66640948d0fc79a397917b4236a74af +F src/select.c 669cfc0392c8a0bd43e5a199cba5f796aead3423e2c529d09148adfa57ae1152 F src/shell.c.in 77d12a0dab8724819e64a14d5fbaad91a934be2b22ad329708fba9ba78993f04 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 0fec1cf17d9e4c93baf29bf74b7d03de9425299443d4abd6989a004d6eb53b60 +F src/sqliteInt.h b81970d56dcb4ed5fc53841ef8b75d42bf511cb9533584546113bc131de832eb F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1114,6 +1114,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac +F test/existsexpr.test a86e8300a2e0cd26109ba5b0d552dbc598b9ad4b79dfd26cac255839c9d5cf6a F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181 @@ -2195,8 +2196,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 f66608bd356efe492d1003663c2e1ccd7cfbf2d40393d256f8720149904ad2d5 e94dfe9928750dd98145d4d9920b298f7b0868703b487f86e0db77a41d53ccf9 -R f3d6aba1cc68a2224dd6f7df935a2c23 -U drh -Z b92cbf17475d91065d48b9fdd285839c +P c4a9dda2809c6e0e3d928e11e5553ead82cd9df551bcd35b11a7d869ef80ab8e +R 7e4221204288c4c4593aaccf38fb6e40 +T *branch * exists-to-join +T *sym-exists-to-join * +T -sym-trunk * +U dan +Z 8ebacdbf5bd3ee682966a7aab4962dc0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a310670ce9..7a08d86957 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4a9dda2809c6e0e3d928e11e5553ead82cd9df551bcd35b11a7d869ef80ab8e \ No newline at end of file +972a33db0b0e924b78d5309d222d8ea298bd59c72da14ea2d14e8e2caaad1e0a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9747810e82..e6de79e775 100644 --- a/src/build.c +++ b/src/build.c @@ -5049,14 +5049,17 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ ** are deleted by this function. */ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ - assert( p1 && p1->nSrc==1 ); + assert( p1 ); if( p2 ){ - SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, 1); + int nOld = p1->nSrc; + SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, nOld); if( pNew==0 ){ sqlite3SrcListDelete(pParse->db, p2); }else{ p1 = pNew; - memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); + memcpy(&p1->a[nOld], p2->a, p2->nSrc*sizeof(SrcItem)); + assert( nOld==1 || (p2->nSrc==1 && (p2->a[0].fg.jointype&JT_LTORJ)==0) ); + assert( p1->nSrc>=2 ); sqlite3DbFree(pParse->db, p2); p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); } diff --git a/src/resolve.c b/src/resolve.c index d5c1515a74..9cb3662625 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1367,6 +1367,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); pExpr->x.pSelect->selFlags |= SF_Correlated; + if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1; } pNC->ncFlags |= NC_Subquery; } diff --git a/src/select.c b/src/select.c index 9a0f2e40f5..332fba3b85 100644 --- a/src/select.c +++ b/src/select.c @@ -7283,6 +7283,152 @@ static int fromClauseTermCanBeCoroutine( return 1; } +/* +** sqlite3WalkExpr() callback used by exprReferencesTable(). +*/ +static int exprReferencesTableExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.iCur ){ + pWalker->eCode = 1; + } + return WRC_Continue; +} + +/* +** Return true if the expression passed as the first argument refers +** to cursor number iCur. Otherwise return false. +*/ +static int exprReferencesTable(Expr *pExpr, int iCur){ + Walker w; + memset(&w, 0, sizeof(w)); + w.u.iCur = iCur; + w.xExprCallback = exprReferencesTableExprCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + +/* +** Index pIdx is a UNIQUE index on the table accessed by cursor number +** iCsr. This function returns a mask of the index columns that are +** constrained to match a single, non-NULL value by the WHERE clause +** passed as the 4th argument. For example, if the index is: +** +** CREATE UNIQUE INDEX idx ON tbl(a, b, c); +** +** and pWhere: +** +** WHERE a=? AND c=? +** +** then this function returns 5. +*/ +static u64 findConstIdxTerms( + Parse *pParse, + int iCsr, + Index *pIdx, + Expr *pWhere +){ + u64 m = 0; + if( pWhere->op==TK_AND ){ + m = findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pLeft); + m |= findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pRight); + }else if( pWhere->op==TK_EQ ){ + Expr *pLeft = pWhere->pLeft; + Expr *pRight = pWhere->pRight; + if( pRight->op==TK_COLUMN && pRight->iTable==iCsr ){ + SWAP(Expr*, pLeft, pRight); + } + if( pLeft->op==TK_COLUMN + && pLeft->iTable==iCsr + && exprReferencesTable(pRight, iCsr)==0 + ){ + if( pIdx ){ + int ii; + for(ii=0; iinKeyCol; ii++){ + assert( pIdx->azColl[ii] ); + if( pLeft->iColumn==pIdx->aiColumn[ii] ){ + CollSeq *pColl = sqlite3ExprCompareCollSeq(pParse, pWhere); + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[ii])==0 ){ + m |= ((u64)1 << ii); + break; + } + } + } + }else{ + if( pLeft->iColumn<0 ) m = 1; + } + } + } + return m; +} + +/* +** Argument pWhere is the WHERE clause belonging to SELECT statement p. This +** function attempts to transform expressions of the form: +** +** EXISTS (SELECT ...) +** +** into joins. For example, given +** +** CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT); +** CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day)); +** +** SELECT name FROM sailors AS S WHERE EXISTS ( +** SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25' +** ); +** +** the SELECT statement may be transformed as follows: +** +** SELECT name FROM sailors AS S, reserves AS R +** WHERE S.sid = R.sid AND R.day = '2022-10-25'; +*/ +static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ + if( pWhere && p->pSrc->nSrc>0 ){ + if( pWhere->op==TK_AND ){ + existsToJoin(pParse, p, pWhere->pLeft); + existsToJoin(pParse, p, pWhere->pRight); + } + else if( pWhere->op==TK_EXISTS && (pWhere->flags & EP_xIsSelect) ){ + Select *pSub = pWhere->x.pSelect; + if( pSub->pSrc->nSrc==1 + && (pSub->selFlags & (SF_Aggregate|SF_Correlated))==SF_Correlated + && pSub->pWhere + ){ + int bTransform = 0; /* True if EXISTS can be made into join */ + Table *pTab = pSub->pSrc->a[0].pTab; + int iCsr = pSub->pSrc->a[0].iCursor; + Index *pIdx; + if( HasRowid(pTab) && findConstIdxTerms(pParse, iCsr, 0,pSub->pWhere) ){ + bTransform = 1; + } + for(pIdx=pTab->pIndex; pIdx && bTransform==0; pIdx=pIdx->pNext){ + if( pIdx->onError && pIdx->nKeyCol<64 ){ + u64 c = findConstIdxTerms(pParse, iCsr, pIdx, pSub->pWhere); + if( c==(1 << pIdx->nKeyCol)-1 ){ + bTransform = 1; + } + } + } + if( bTransform ){ + p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); + pSub->pSrc = 0; + if( p->pWhere ){ + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere); + }else{ + p->pWhere = pSub->pWhere; + } + pSub->pWhere = 0; + + sqlite3SelectDelete(pParse->db, pSub); + memset(pWhere, 0, sizeof(*pWhere)); + pWhere->op = TK_INTEGER; + pWhere->u.iValue = 1; + ExprSetProperty(pWhere, EP_IntValue); + } + } + } + } +} + /* ** Generate code for the SELECT statement given in the p argument. ** @@ -7609,6 +7755,13 @@ int sqlite3Select( } #endif + /* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt + ** to change it into a join. */ + if( pParse->bHasExists ){ + existsToJoin(pParse, p, p->pWhere); + pTabList = p->pSrc; + } + /* Do the WHERE-clause constant propagation optimization if this is ** a join. No need to speed time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8866b69ea5..8d104bc253 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3827,6 +3827,7 @@ struct Parse { u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ + u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif diff --git a/test/existsexpr.test b/test/existsexpr.test new file mode 100644 index 0000000000..4bd55db52d --- /dev/null +++ b/test/existsexpr.test @@ -0,0 +1,116 @@ +# 2024 May 25 +# +# 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 +source $testdir/lock_common.tcl +set testprefix existsexpr + + +do_execsql_test 1.0 { + CREATE TABLE x1(a, b); + INSERT INTO x1 VALUES(1, 2), (3, 4), (5, 6); + CREATE UNIQUE INDEX x1a ON x1(a); + CREATE INDEX x1b ON x1(b); + + CREATE TABLE x2(x, y); + INSERT INTO x2 VALUES(1, 2), (3, 4), (5, 6); +} + +do_execsql_test 1.1 { + SELECT 1 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=5) +} {1} + +do_execsql_test 1.2 { + SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) +} {1 2 3 4 5 6} + +# With "a=x", the UNIQUE index means the EXIST can be transformed to a join. +# So no "SUBQUERY". With "b=x", the index is not UNIQUE and so there is a +# "SUBQUERY". +do_execsql_test 1.3.1 { + EXPLAIN QUERY PLAN + SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) +} {~/SUBQUERY/} +do_execsql_test 1.3.2 { + EXPLAIN QUERY PLAN + SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE b=x) +} {/SUBQUERY/} + +do_execsql_test 1.4.1 { + EXPLAIN QUERY PLAN + SELECT * FROM x2 WHERE x=1 AND EXISTS (SELECT 1 FROM x1 WHERE a=x) +} {~/SUBQUERY/} +do_execsql_test 1.4.2 { + EXPLAIN QUERY PLAN + SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) AND y=2 +} {~/SUBQUERY/} + +do_execsql_test 1.5 { + SELECT count(*) FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) +} {3} + +#------------------------------------------------------------------------- +do_execsql_test 2.0 { + CREATE TABLE t1(a, b); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) INSERT INTO t1 SELECT i, i FROM s; + + CREATE TABLE t2(c, d); + WITH s(i) AS ( + SELECT 10 UNION ALL SELECT i+10 FROM s WHERE i<1000 + ) INSERT INTO t2 SELECT i, i FROM s; +} + +do_execsql_test 2.1 { + SELECT count(*) FROM t1; + SELECT count(*) FROM t2; +} {1000 100} + +do_execsql_test 2.2 { + SELECT count(*) FROM t1, t2 WHERE a=c; +} {100} + +do_execsql_test 2.3 { + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a) +} {100} +do_eqp_test 2.4 { + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a) +} {SCAN t1} + +do_execsql_test 2.5 { + CREATE UNIQUE INDEX t2c ON t2(c); + CREATE UNIQUE INDEX t1a ON t1(a); +} + +do_eqp_test 2.4.1 { + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); +} {SCAN t1*SEARCH t2} +do_execsql_test 2.4.2 { + ANALYZE; +} +do_eqp_test 2.4.3 { + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); +} {SCAN t2*SEARCH t1} +do_execsql_test 2.4.4 { + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); +} {100} + +do_execsql_test 2.5.1 { + EXPLAIN QUERY PLAN + SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.rowid=a); +} {~/SUBQUERY/} + +finish_test + + From b111f1cb2a32d0bc49436e90e162b82c5aa50060 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Jun 2024 18:13:12 +0000 Subject: [PATCH 02/88] Add extra tests for the changes on this branch. FossilOrigin-Name: a6365c778f2a6d6fa78e8520553373898f382ce73bf6496533e26291648ef5d1 --- manifest | 18 ++- manifest.uuid | 2 +- src/select.c | 29 +++-- test/existsexpr.test | 258 +++++++++++++++++++++++++++++++++++++++++- test/existsfault.test | 49 ++++++++ 5 files changed, 328 insertions(+), 28 deletions(-) create mode 100644 test/existsfault.test diff --git a/manifest b/manifest index 6f4efd9bdc..55819af278 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\soptimization\sto\srewrite\sa\sSELECT\swith\san\sEXISTS(...)\sexpression\sin\sthe\sWHERE\sclause\sas\sa\sjoin. -D 2024-06-07T21:00:42.970 +C Add\sextra\stests\sfor\sthe\schanges\son\sthis\sbranch. +D 2024-06-08T18:13:12.691 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,7 +755,7 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 669cfc0392c8a0bd43e5a199cba5f796aead3423e2c529d09148adfa57ae1152 +F src/select.c 06146768a11bfe8928fea0aabf8addedd4d146a8c4be70558f5c8ecdcc2ce338 F src/shell.c.in 77d12a0dab8724819e64a14d5fbaad91a934be2b22ad329708fba9ba78993f04 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1114,7 +1114,8 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test a86e8300a2e0cd26109ba5b0d552dbc598b9ad4b79dfd26cac255839c9d5cf6a +F test/existsexpr.test b101143b177d623c35166589d3e6772021dfe4f625ac318c91726a998939cd19 +F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181 @@ -2196,11 +2197,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 c4a9dda2809c6e0e3d928e11e5553ead82cd9df551bcd35b11a7d869ef80ab8e -R 7e4221204288c4c4593aaccf38fb6e40 -T *branch * exists-to-join -T *sym-exists-to-join * -T -sym-trunk * +P 972a33db0b0e924b78d5309d222d8ea298bd59c72da14ea2d14e8e2caaad1e0a +R 20ea5e8daae9a69a6e09a05cc19a6a37 U dan -Z 8ebacdbf5bd3ee682966a7aab4962dc0 +Z cbb8e2989ade033c119abad0907d9ec3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7a08d86957..ce5b16061c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -972a33db0b0e924b78d5309d222d8ea298bd59c72da14ea2d14e8e2caaad1e0a \ No newline at end of file +a6365c778f2a6d6fa78e8520553373898f382ce73bf6496533e26291648ef5d1 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 332fba3b85..f21559e8da 100644 --- a/src/select.c +++ b/src/select.c @@ -7382,12 +7382,13 @@ static u64 findConstIdxTerms( ** WHERE S.sid = R.sid AND R.day = '2022-10-25'; */ static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ - if( pWhere && p->pSrc->nSrc>0 ){ + if( pWhere && p->pSrc->nSrc>0 && pParse->db->mallocFailed==0 ){ if( pWhere->op==TK_AND ){ + Expr *pRight = pWhere->pRight; existsToJoin(pParse, p, pWhere->pLeft); - existsToJoin(pParse, p, pWhere->pRight); + existsToJoin(pParse, p, pRight); } - else if( pWhere->op==TK_EXISTS && (pWhere->flags & EP_xIsSelect) ){ + else if( pWhere->op==TK_EXISTS ){ Select *pSub = pWhere->x.pSelect; if( pSub->pSrc->nSrc==1 && (pSub->selFlags & (SF_Aggregate|SF_Correlated))==SF_Correlated @@ -7401,28 +7402,26 @@ static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ bTransform = 1; } for(pIdx=pTab->pIndex; pIdx && bTransform==0; pIdx=pIdx->pNext){ - if( pIdx->onError && pIdx->nKeyCol<64 ){ + if( pIdx->onError && pIdx->nKeyCol<=63 ){ u64 c = findConstIdxTerms(pParse, iCsr, pIdx, pSub->pWhere); - if( c==(1 << pIdx->nKeyCol)-1 ){ + if( c==((u64)1 << pIdx->nKeyCol)-1 ){ bTransform = 1; } } } if( bTransform ){ - p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); - pSub->pSrc = 0; - if( p->pWhere ){ - p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere); - }else{ - p->pWhere = pSub->pWhere; - } - pSub->pWhere = 0; - - sqlite3SelectDelete(pParse->db, pSub); memset(pWhere, 0, sizeof(*pWhere)); pWhere->op = TK_INTEGER; pWhere->u.iValue = 1; ExprSetProperty(pWhere, EP_IntValue); + + assert( p->pWhere!=0 ); + p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere); + + pSub->pWhere = 0; + pSub->pSrc = 0; + sqlite3SelectDelete(pParse->db, pSub); } } } diff --git a/test/existsexpr.test b/test/existsexpr.test index 4bd55db52d..344f8cff6e 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -17,9 +17,8 @@ set testprefix existsexpr do_execsql_test 1.0 { - CREATE TABLE x1(a, b); + CREATE TABLE x1(a, b, PRIMARY KEY(a)) WITHOUT ROWID; INSERT INTO x1 VALUES(1, 2), (3, 4), (5, 6); - CREATE UNIQUE INDEX x1a ON x1(a); CREATE INDEX x1b ON x1(b); CREATE TABLE x2(x, y); @@ -111,6 +110,261 @@ do_execsql_test 2.5.1 { SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.rowid=a); } {~/SUBQUERY/} +#------------------------------------------------------------------------- +proc do_subquery_test {tn bSub sql res} { + set r1(0) ~/SUBQUERY/ + set r1(1) /SUBQUERY/ + do_execsql_test $tn.1 "explain query plan $sql" $r1($bSub) + do_execsql_test $tn.2 $sql $res +} + +do_execsql_test 3.0 { + CREATE TABLE y1(a, b, c); + CREATE TABLE y2(x, y, z); + CREATE UNIQUE INDEX y2zy ON y2(z, y); + + INSERT INTO y1 VALUES(1, 1, 1); + INSERT INTO y1 VALUES(2, 2, 2); + INSERT INTO y1 VALUES(3, 3, 3); + INSERT INTO y1 VALUES(4, 4, 4); + + INSERT INTO y2 VALUES(1, 1, 1); + INSERT INTO y2 VALUES(3, 3, 3); +} + +do_subquery_test 3.1 0 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=a AND y=b AND x=z + ) +} { + 1 1 1 3 3 3 +} + +do_subquery_test 3.2 0 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=max(a,b) AND y=min(b,a) AND x=z + ) +} { + 1 1 1 3 3 3 +} + +do_subquery_test 3.3 0 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=max(a,b) AND y=min(b,a) AND c!=3 + ) +} { + 1 1 1 +} + +do_subquery_test 3.4 1 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=max(a,b) AND b=3 + ) +} { + 3 3 3 +} + +do_subquery_test 3.5 0 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=a-1 AND y=a-1 + ) +} { + 2 2 2 + 4 4 4 +} + +do_subquery_test 3.6 1 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 WHERE z=a-1 AND y+1=a + ) +} { + 2 2 2 + 4 4 4 +} + +do_subquery_test 3.7 1 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT count(*) FROM y2 WHERE z=a-1 AND y=a-1 + ) +} { + 1 1 1 + 2 2 2 + 3 3 3 + 4 4 4 +} + +do_subquery_test 3.8 1 { + SELECT * FROM y1 WHERE EXISTS ( SELECT a+1 FROM y2 ) +} { + 1 1 1 + 2 2 2 + 3 3 3 + 4 4 4 +} + +do_subquery_test 3.9 1 { + SELECT * FROM y1 WHERE EXISTS ( + SELECT 1 FROM y2 one, y2 two WHERE one.z=a-1 AND one.y=a-1 + ) +} { + 2 2 2 + 4 4 4 +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE tx1(a TEXT COLLATE nocase, b TEXT); + CREATE UNIQUE INDEX tx1ab ON tx1(a, b); + + INSERT INTO tx1 VALUES('a', 'a'); + INSERT INTO tx1 VALUES('B', 'b'); + INSERT INTO tx1 VALUES('c', 'c'); + INSERT INTO tx1 VALUES('D', 'd'); + INSERT INTO tx1 VALUES('e', 'e'); + + CREATE TABLE tx2(x, y); + INSERT INTO tx2 VALUES('A', 'a'); + INSERT INTO tx2 VALUES('b', 'b'); + INSERT INTO tx2 VALUES('C', 'c'); + INSERT INTO tx2 VALUES('D', 'd'); +} + +do_subquery_test 4.1 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x AND b=y + ) +} { + A a + b b + C c + D d +} + +do_subquery_test 4.2 1 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x AND b=y COLLATE nocase + ) +} { + A a + b b + C c + D d +} + +do_execsql_test 4.3 { + DROP INDEX tx1ab; + CREATE UNIQUE INDEX tx1ab ON tx1(a COLLATE binary, b); +} + +do_subquery_test 4.4 1 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x AND b=y + ) +} { + A a + b b + C c + D d +} + +do_subquery_test 4.4 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x COLLATE binary AND b=y + ) +} { + D d +} + +do_subquery_test 4.4 1 { + SELECT EXISTS ( SELECT x FROM tx1 ) FROM tx2 +} { + 1 1 1 1 +} + +do_subquery_test 4.4 1 { + SELECT (SELECT EXISTS ( SELECT x FROM tx1 ) WHERE 1) FROM tx2 +} { + 1 1 1 1 +} + +#------------------------------------------------------------------------- +proc cols {s f} { + set lCols [list] + for {set i $s} {$i<=$f} {incr i} { + lappend lCols [format "c%02d" $i] + } + join $lCols ", " +} +proc vals {n val} { + set lVal [list] + for {set i 0} {$i<$n} {incr i} { + lappend lVal $val + } + join $lVal ", " +} +proc exprs {s f} { + set lExpr [list] + for {set i $s} {$i<=$f} {incr i} { + lappend lExpr [format "c%02d = o" $i] + } + join $lExpr " AND " +} + + +do_execsql_test 5.0 " + CREATE TABLE a1( [cols 0 99] ); +" +do_execsql_test 5.1 " + -- 63 column index + CREATE UNIQUE INDEX a1idx1 ON a1( [cols 0 62] ); +" +do_execsql_test 5.2 " + -- 64 column index + CREATE UNIQUE INDEX a1idx2 ON a1( [cols 10 73] ); +" +do_execsql_test 5.2 " + -- 65 column index + CREATE UNIQUE INDEX a1idx3 ON a1( [cols 20 84] ); +" + +do_test 5.3 { + foreach v {1 2 3 4 5 6} { + execsql "INSERT INTO a1 VALUES( [vals 100 $v] )" + } +} {} + +do_execsql_test 5.4 { + CREATE TABLE a2(o); + INSERT INTO a2 VALUES(2), (5); +} + +do_subquery_test 5.5 0 " + SELECT o FROM a2 WHERE EXISTS ( + SELECT 1 FROM a1 WHERE [exprs 0 62] + ) +" { + 2 5 +} + +do_subquery_test 5.6 1 " + SELECT o FROM a2 WHERE EXISTS ( + SELECT 1 FROM a1 WHERE [exprs 10 73] + ) +" { + 2 5 +} + +do_subquery_test 5.7 1 " + SELECT o FROM a2 WHERE EXISTS ( + SELECT 1 FROM a1 WHERE [exprs 20 84] + ) +" { + 2 5 +} + + + finish_test diff --git a/test/existsfault.test b/test/existsfault.test new file mode 100644 index 0000000000..4b335d84cd --- /dev/null +++ b/test/existsfault.test @@ -0,0 +1,49 @@ +# 2024 May 25 +# +# 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 +source $testdir/lock_common.tcl +source $testdir/malloc_common.tcl +set testprefix existsfault + +db close +sqlite3_shutdown +sqlite3_config_lookaside 0 0 +sqlite3_initialize +autoinstall_test_functions +sqlite3 db test.db + +do_execsql_test 1.0 { + CREATE TABLE x1(a, b); + INSERT INTO x1 VALUES(1, 2), (3, 4), (5, 6); + CREATE UNIQUE INDEX x1a ON x1(a); + CREATE INDEX x1b ON x1(b); + + CREATE TABLE x2(x, y); + INSERT INTO x2 VALUES(1, 2), (3, 4), (5, 6); +} + +do_faultsim_test 1 -faults oom* -prep { + sqlite3 db test.db + execsql { SELECT * FROM sqlite_schema } +} -body { + execsql { + SELECT count(*) FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) AND y!=11 + } +} -test { + faultsim_test_result {0 3} +} + +finish_test + + From dc9a262319d734b9a8023e34ded1f426459766bd Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Jun 2024 19:31:18 +0000 Subject: [PATCH 03/88] Fix a crash that could occur when the SELECT in an EXISTS(SELECT ...) used an unknown collation sequence. FossilOrigin-Name: f3009a6d7facd1ead520d588c5ad089db76d8641cd3dae076f2405492d7defcd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- test/existsexpr.test | 12 ++++++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 55819af278..24efae1938 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sfor\sthe\schanges\son\sthis\sbranch. -D 2024-06-08T18:13:12.691 +C Fix\sa\scrash\sthat\scould\soccur\swhen\sthe\sSELECT\sin\san\sEXISTS(SELECT\s...)\sused\san\sunknown\scollation\ssequence. +D 2024-06-10T19:31:18.296 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,7 +755,7 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 06146768a11bfe8928fea0aabf8addedd4d146a8c4be70558f5c8ecdcc2ce338 +F src/select.c b3fa60ba7aab607daf0d15053a66073888f3dd8d6bb1c8000349bc22d85acd80 F src/shell.c.in 77d12a0dab8724819e64a14d5fbaad91a934be2b22ad329708fba9ba78993f04 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1114,7 +1114,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test b101143b177d623c35166589d3e6772021dfe4f625ac318c91726a998939cd19 +F test/existsexpr.test 7c0abb8383b492325d57e0546faf4ea52ad52c02877b797460330f17320a1314 F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -2197,8 +2197,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 972a33db0b0e924b78d5309d222d8ea298bd59c72da14ea2d14e8e2caaad1e0a -R 20ea5e8daae9a69a6e09a05cc19a6a37 +P a6365c778f2a6d6fa78e8520553373898f382ce73bf6496533e26291648ef5d1 +R 4addb7a3e408fa9c0e91b39c04b20512 U dan -Z cbb8e2989ade033c119abad0907d9ec3 +Z fa336d8505987cef2cdbba1866644a8f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ce5b16061c..f3378323f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6365c778f2a6d6fa78e8520553373898f382ce73bf6496533e26291648ef5d1 \ No newline at end of file +f3009a6d7facd1ead520d588c5ad089db76d8641cd3dae076f2405492d7defcd \ No newline at end of file diff --git a/src/select.c b/src/select.c index f21559e8da..ac8b1b6ae0 100644 --- a/src/select.c +++ b/src/select.c @@ -7347,7 +7347,7 @@ static u64 findConstIdxTerms( assert( pIdx->azColl[ii] ); if( pLeft->iColumn==pIdx->aiColumn[ii] ){ CollSeq *pColl = sqlite3ExprCompareCollSeq(pParse, pWhere); - if( sqlite3StrICmp(pColl->zName, pIdx->azColl[ii])==0 ){ + if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[ii])==0 ){ m |= ((u64)1 << ii); break; } diff --git a/test/existsexpr.test b/test/existsexpr.test index 344f8cff6e..836560f2d0 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -363,6 +363,18 @@ do_subquery_test 5.7 1 " 2 5 } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a, b UNIQUE, c UNIQUE); + CREATE TABLE t2(a INfEGER PRIMARY KEY, b); + CREATE UNIQUE INDEX t2b ON t2(b); +} + +do_catchsql_test 6.1 { + SELECT a FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c COLLATE f = a) +} {1 {no such collation sequence: f}} + finish_test From df77e56cdeeb46fab3deb9ded4d5c0e873f57ee9 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Jun 2024 19:45:33 +0000 Subject: [PATCH 04/88] Add missing calls to sqlite3exprSkipCollateAndLikely() to the enchancement on this branch. FossilOrigin-Name: 078537d057d638389e3ab3bc04bcac53f342c7bf1d8d75222296ef42d09e9ee7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 4 ++-- test/existsexpr.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 24efae1938..e555256083 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\soccur\swhen\sthe\sSELECT\sin\san\sEXISTS(SELECT\s...)\sused\san\sunknown\scollation\ssequence. -D 2024-06-10T19:31:18.296 +C Add\smissing\scalls\sto\ssqlite3exprSkipCollateAndLikely()\sto\sthe\senchancement\son\sthis\sbranch. +D 2024-06-10T19:45:33.614 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,7 +755,7 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c b3fa60ba7aab607daf0d15053a66073888f3dd8d6bb1c8000349bc22d85acd80 +F src/select.c 9c65721098bad3f2cf266ef8e6aa8c0d57a691a48c075d5e8b1a44fa4fa7e351 F src/shell.c.in 77d12a0dab8724819e64a14d5fbaad91a934be2b22ad329708fba9ba78993f04 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1114,7 +1114,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test 7c0abb8383b492325d57e0546faf4ea52ad52c02877b797460330f17320a1314 +F test/existsexpr.test 6a917db207ca95a9da8733a2c3aefc8541f81d41169a69deb125a56686c73ed0 F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -2197,8 +2197,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 a6365c778f2a6d6fa78e8520553373898f382ce73bf6496533e26291648ef5d1 -R 4addb7a3e408fa9c0e91b39c04b20512 +P f3009a6d7facd1ead520d588c5ad089db76d8641cd3dae076f2405492d7defcd +R 93b078b964e586d7ff51ddb903d178e0 U dan -Z fa336d8505987cef2cdbba1866644a8f +Z 3d590655f4ffe6769b9e658507fd34f2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f3378323f6..0d8e5a92ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3009a6d7facd1ead520d588c5ad089db76d8641cd3dae076f2405492d7defcd \ No newline at end of file +078537d057d638389e3ab3bc04bcac53f342c7bf1d8d75222296ef42d09e9ee7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index ac8b1b6ae0..69a07528fa 100644 --- a/src/select.c +++ b/src/select.c @@ -7332,8 +7332,8 @@ static u64 findConstIdxTerms( m = findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pLeft); m |= findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pRight); }else if( pWhere->op==TK_EQ ){ - Expr *pLeft = pWhere->pLeft; - Expr *pRight = pWhere->pRight; + Expr *pLeft = sqlite3ExprSkipCollateAndLikely(pWhere->pLeft); + Expr *pRight = sqlite3ExprSkipCollateAndLikely(pWhere->pRight); if( pRight->op==TK_COLUMN && pRight->iTable==iCsr ){ SWAP(Expr*, pLeft, pRight); } diff --git a/test/existsexpr.test b/test/existsexpr.test index 836560f2d0..a5f60b944b 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -241,6 +241,35 @@ do_subquery_test 4.1 0 { D d } +do_subquery_test 4.1.1 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE (a COLLATE nocase)=x AND b=y + ) +} { + A a b b C c D d +} +do_subquery_test 4.1.2 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x AND (b COLLATE binary)=y + ) +} { + A a b b C c D d +} +do_subquery_test 4.1.1 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE x=(a COLLATE nocase) AND b=y + ) +} { + A a b b C c D d +} +do_subquery_test 4.1.2 0 { + SELECT * FROM tx2 WHERE EXISTS ( + SELECT 1 FROM tx1 WHERE a=x AND y=(b COLLATE binary) + ) +} { + A a b b C c D d +} + do_subquery_test 4.2 1 { SELECT * FROM tx2 WHERE EXISTS ( SELECT 1 FROM tx1 WHERE a=x AND b=y COLLATE nocase From ddc62664bfb5e3237b20098b30e4a99815c322e0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 11 Jun 2024 18:22:48 +0000 Subject: [PATCH 05/88] Provide the ability to disable the exists-to-join optimization using SQLITE_TESTCTRL_OPTIMIZATIONS. Provide tree-trace output for the optimization. FossilOrigin-Name: 33a3f327855b427ae6ba0057218d043a1417bc9d780728f47f23acdd836e1686 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 11 +++++++++-- src/sqliteInt.h | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0b5c406027..13e08125d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\senhancements\sinto\sthe\sexists-to-join\sbranch. -D 2024-06-11T17:37:36.892 +C Provide\sthe\sability\sto\sdisable\sthe\sexists-to-join\soptimization\susing\nSQLITE_TESTCTRL_OPTIMIZATIONS.\s\sProvide\stree-trace\soutput\sfor\sthe\soptimization. +D 2024-06-11T18:22:48.334 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,12 +755,12 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 9c65721098bad3f2cf266ef8e6aa8c0d57a691a48c075d5e8b1a44fa4fa7e351 +F src/select.c decd5944639f604eba66bcf28161c1beb09b7762093aadc25313a0fe62ce9a5f F src/shell.c.in ad27d1d990e9e5fb7ae8fc38a717e91f55233714f59723e5618baf4a2a3d2b65 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h c62b054b581abb051018ddc503bc292f3103db1e5ee16346f1495d46c07c5d3b +F src/sqliteInt.h b0c079cec6aa6a133af52489c14a4d8c2d750889594299d83eab1ae1b12979c0 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -2197,8 +2197,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 078537d057d638389e3ab3bc04bcac53f342c7bf1d8d75222296ef42d09e9ee7 6935ac71bad3d36cc519f0325ae4447a674f257309d020cdc0741160fcce0580 -R b6e202e4f08c9d1d4b557c05911f57ed +P 5f25a9518a675efbd0525cc2f5595ee7bc7122be7cfecdf6b20c909185dea370 +R b17f1837a5067fb4548e9e703c412c5a U drh -Z 025c74f5e2115680217e065394f815d9 +Z e7e7ba1dc895b6e1b772b1a24ff19dc3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 78990c287e..f005164c32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f25a9518a675efbd0525cc2f5595ee7bc7122be7cfecdf6b20c909185dea370 \ No newline at end of file +33a3f327855b427ae6ba0057218d043a1417bc9d780728f47f23acdd836e1686 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 69a07528fa..e546a664cd 100644 --- a/src/select.c +++ b/src/select.c @@ -7421,7 +7421,14 @@ static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ pSub->pWhere = 0; pSub->pSrc = 0; - sqlite3SelectDelete(pParse->db, pSub); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100000 ){ + TREETRACE(0x100000,pParse,p, + ("After EXISTS-to-JOIN optimization:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif } } } @@ -7756,7 +7763,7 @@ int sqlite3Select( /* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt ** to change it into a join. */ - if( pParse->bHasExists ){ + if( pParse->bHasExists && OptimizationEnabled(db,SQLITE_ExistsToJoin) ){ existsToJoin(pParse, p, p->pWhere); pTabList = p->pSrc; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c976b928dd..6a1b22f92d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1126,6 +1126,7 @@ extern u32 sqlite3TreeTrace; ** 0x00020000 Transform DISTINCT into GROUP BY ** 0x00040000 SELECT tree dump after all code has been generated ** 0x00080000 NOT NULL strength reduction +** 0x00100000 EXISTS-to-JOIN optimization */ /* @@ -1924,6 +1925,7 @@ struct sqlite3 { #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ +#define SQLITE_ExistsToJoin 0x10000000 /* The EXISTS-to-JOIN optimization */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* From 0d92e66dfc42e23cf07fdf01b37f1bcbd0d8b6b9 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 12 Jun 2024 17:01:00 +0000 Subject: [PATCH 06/88] Do not attempt the exists-to-join optimization for expressions from the ON clause of joins. FossilOrigin-Name: 4666433cbd9af21c2e0440b10bcb39878624a39485e2bb514553b276acb8a401 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 6 +++++- test/existsexpr.test | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 13e08125d6..beca64a81a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sthe\sability\sto\sdisable\sthe\sexists-to-join\soptimization\susing\nSQLITE_TESTCTRL_OPTIMIZATIONS.\s\sProvide\stree-trace\soutput\sfor\sthe\soptimization. -D 2024-06-11T18:22:48.334 +C Do\snot\sattempt\sthe\sexists-to-join\soptimization\sfor\sexpressions\sfrom\sthe\sON\sclause\sof\sjoins. +D 2024-06-12T17:01:00.926 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,7 +755,7 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c decd5944639f604eba66bcf28161c1beb09b7762093aadc25313a0fe62ce9a5f +F src/select.c 757ea788e20f608d09bfef209d17bba87104cab920f80de77c92b38588ef64c5 F src/shell.c.in ad27d1d990e9e5fb7ae8fc38a717e91f55233714f59723e5618baf4a2a3d2b65 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1114,7 +1114,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test 6a917db207ca95a9da8733a2c3aefc8541f81d41169a69deb125a56686c73ed0 +F test/existsexpr.test bf1201621070e79c1060c1a8cf7d65d81fc6b336d94a371c63ecb08d357af2fd F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -2197,8 +2197,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 5f25a9518a675efbd0525cc2f5595ee7bc7122be7cfecdf6b20c909185dea370 -R b17f1837a5067fb4548e9e703c412c5a -U drh -Z e7e7ba1dc895b6e1b772b1a24ff19dc3 +P 33a3f327855b427ae6ba0057218d043a1417bc9d780728f47f23acdd836e1686 +R 25697789cb2a6d5a3b4b0fd17d4887cd +U dan +Z c7e8e1ad09260243da52b623b6dff2b7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f005164c32..26bcc7370b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33a3f327855b427ae6ba0057218d043a1417bc9d780728f47f23acdd836e1686 \ No newline at end of file +4666433cbd9af21c2e0440b10bcb39878624a39485e2bb514553b276acb8a401 \ No newline at end of file diff --git a/src/select.c b/src/select.c index e546a664cd..7a789196b6 100644 --- a/src/select.c +++ b/src/select.c @@ -7382,7 +7382,11 @@ static u64 findConstIdxTerms( ** WHERE S.sid = R.sid AND R.day = '2022-10-25'; */ static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ - if( pWhere && p->pSrc->nSrc>0 && pParse->db->mallocFailed==0 ){ + if( pWhere + && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) + && p->pSrc->nSrc>0 + && pParse->db->mallocFailed==0 + ){ if( pWhere->op==TK_AND ){ Expr *pRight = pWhere->pRight; existsToJoin(pParse, p, pWhere->pLeft); diff --git a/test/existsexpr.test b/test/existsexpr.test index a5f60b944b..81aa5799f0 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -404,6 +404,23 @@ do_catchsql_test 6.1 { SELECT a FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c COLLATE f = a) } {1 {no such collation sequence: f}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(x); + CREATE TABLE t2(y UNIQUE); + + INSERT INTO t1 VALUES(1), (2); + INSERT INTO t2 VALUES(1), (3); + + SELECT * FROM t1 one LEFT JOIN t1 two ON (one.x=two.x AND EXISTS ( + SELECT 1 FROM t2 WHERE y=one.x + )); +} { + 1 1 + 2 {} +} + finish_test From 62b954d545f52a8d59db654948f28ad6b6d899f6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 14 Jun 2024 18:06:25 +0000 Subject: [PATCH 07/88] Add tests for the change on this branch. FossilOrigin-Name: ae19ff9ba819439fd107e745b6e8e503e5b68bfdb9da58b74035413704ad3caf --- manifest | 11 ++--- manifest.uuid | 2 +- test/existsexpr2.test | 96 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 test/existsexpr2.test diff --git a/manifest b/manifest index beca64a81a..5d3e1df5e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sthe\sexists-to-join\soptimization\sfor\sexpressions\sfrom\sthe\sON\sclause\sof\sjoins. -D 2024-06-12T17:01:00.926 +C Add\stests\sfor\sthe\schange\son\sthis\sbranch. +D 2024-06-14T18:06:25.102 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1115,6 +1115,7 @@ F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/existsexpr.test bf1201621070e79c1060c1a8cf7d65d81fc6b336d94a371c63ecb08d357af2fd +F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11 F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 @@ -2197,8 +2198,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 33a3f327855b427ae6ba0057218d043a1417bc9d780728f47f23acdd836e1686 -R 25697789cb2a6d5a3b4b0fd17d4887cd +P 4666433cbd9af21c2e0440b10bcb39878624a39485e2bb514553b276acb8a401 +R a04eb111a75540deb83a6459885c7580 U dan -Z c7e8e1ad09260243da52b623b6dff2b7 +Z 384cdb2f34ec5a8891b2a14db482f8c6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 26bcc7370b..49d1e69efe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4666433cbd9af21c2e0440b10bcb39878624a39485e2bb514553b276acb8a401 \ No newline at end of file +ae19ff9ba819439fd107e745b6e8e503e5b68bfdb9da58b74035413704ad3caf \ No newline at end of file diff --git a/test/existsexpr2.test b/test/existsexpr2.test new file mode 100644 index 0000000000..f7644bf802 --- /dev/null +++ b/test/existsexpr2.test @@ -0,0 +1,96 @@ +# 2024 June 14 +# +# 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 +source $testdir/lock_common.tcl +set testprefix existsexpr2 + + +do_execsql_test 1.0 { + CREATE TABLE x1(a, b, PRIMARY KEY(a)) WITHOUT ROWID; + INSERT INTO x1 VALUES(1, 2), (3, 4), (5, 6); + CREATE INDEX x1b ON x1(b); + + CREATE TABLE x2(x, y); + INSERT INTO x2 VALUES(1, 2), (3, 4), (5, 6); +} + +do_execsql_test 1.1 { + SELECT * FROM x1 WHERE EXISTS (SELECT 1 FROM x2 WHERE a!=123) +} {1 2 3 4 5 6} + +do_execsql_test 1.2 { + CREATE TABLE x3(u, v); + CREATE INDEX x3u ON x3(u); + INSERT INTO x3 VALUES + (1, 1), (1, 2), (1, 3), + (2, 1), (2, 2), (2, 3); +} + +do_execsql_test 1.3 { + SELECT * FROM x1 WHERE EXISTS ( + SELECT 1 FROM x3 WHERE u IN (1, 2, 3, 4) AND v=b + ); +} { + 1 2 +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX t1ab ON t1(a,b); + + INSERT INTO t1 VALUES + ('abc', 1, 1), + ('abc', 2, 2), + ('abc', 2, 3), + + ('def', 1, 1), + ('def', 2, 2), + ('def', 2, 3); + + CREATE TABLE t2(x, y); + INSERT INTO t2 VALUES(1, 1), (2, 2), (3, 3); + + ANALYZE; + DELETE FROM sqlite_stat1; + INSERT INTO sqlite_stat1 VALUES('t1','t1ab','10000 5000 2'); + ANALYZE sqlite_master; +} + + +do_execsql_test 2.1 { + SELECT a,b,c FROM t1 WHERE b=2 ORDER BY a +} { + abc 2 2 + abc 2 3 + def 2 2 + def 2 3 +} + +do_execsql_test 2.2 { + SELECT x, y FROM t2 WHERE EXISTS ( + SELECT 1 FROM t1 WHERE b=x + ) +} { + 1 1 + 2 2 +} + + + +finish_test + + From 620a00ee32c64944289bc8ff8c37b23bb4e220a1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 20 Jun 2024 12:07:25 +0000 Subject: [PATCH 08/88] Do not attempt the exists-to-join optimization if the FROM clause is full. FossilOrigin-Name: 8e3a1d2850337a902ab36b1d6a0dad4ae35030b71d1e15547f6e7487c1f86d18 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5d3e1df5e2..e374d68b4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sthe\schange\son\sthis\sbranch. -D 2024-06-14T18:06:25.102 +C Do\snot\sattempt\sthe\sexists-to-join\soptimization\sif\sthe\sFROM\sclause\sis\sfull. +D 2024-06-20T12:07:25.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -755,7 +755,7 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 757ea788e20f608d09bfef209d17bba87104cab920f80de77c92b38588ef64c5 +F src/select.c 72883bd7dda5e67cdf097776ae5d83aab02fbad9c4fa3ae1e25516efb1401fd4 F src/shell.c.in ad27d1d990e9e5fb7ae8fc38a717e91f55233714f59723e5618baf4a2a3d2b65 F src/sqlite.h.in cbd3e4177791a61c056fd81e37a5b21bb6c8cb2ea8cac558c625974673f50acf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -2198,8 +2198,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 4666433cbd9af21c2e0440b10bcb39878624a39485e2bb514553b276acb8a401 -R a04eb111a75540deb83a6459885c7580 -U dan -Z 384cdb2f34ec5a8891b2a14db482f8c6 +P ae19ff9ba819439fd107e745b6e8e503e5b68bfdb9da58b74035413704ad3caf +R 2e2a21654277825e58e413fb627048c9 +U drh +Z 5d427b052ed84b4ca59ddb925bd74f93 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 49d1e69efe..3ef5d46fbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae19ff9ba819439fd107e745b6e8e503e5b68bfdb9da58b74035413704ad3caf \ No newline at end of file +8e3a1d2850337a902ab36b1d6a0dad4ae35030b71d1e15547f6e7487c1f86d18 diff --git a/src/select.c b/src/select.c index 7a789196b6..832b711b8b 100644 --- a/src/select.c +++ b/src/select.c @@ -7384,7 +7384,8 @@ static u64 findConstIdxTerms( static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){ if( pWhere && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) - && p->pSrc->nSrc>0 + && p->pSrc->nSrc>0 + && p->pSrc->nSrcdb->mallocFailed==0 ){ if( pWhere->op==TK_AND ){ From 311d73efc27a72478cdb6672ff2685306c2dea3e Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 28 Jun 2025 17:59:15 +0000 Subject: [PATCH 09/88] Improve the bytecode generated for comparisons so that if one operand is a subquery and the other operand evaluates to NULL, the subquery operand is not even computed. This fixes 5 of the 12 slow queries described in [forum:/forumpost/52651713ac|forum post 52651713ac]. FossilOrigin-Name: f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/expr.c | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 361c6e5174..fcdf5f0344 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Raise\san\serror\sright\saway\sif\sthe\snumber\sof\saggregate\sterms\sin\sa\squery\nexceeds\sthe\smaximum\snumber\sof\scolumns. -D 2025-06-27T19:02:21.291 +C Improve\sthe\sbytecode\sgenerated\sfor\scomparisons\sso\sthat\sif\sone\soperand\sis\na\ssubquery\sand\sthe\sother\soperand\sevaluates\sto\sNULL,\sthe\ssubquery\soperand\nis\snot\seven\scomputed.\s\sThis\sfixes\s5\sof\sthe\s12\sslow\squeries\sdescribed\nin\s[forum:/forumpost/52651713ac|forum\spost\s52651713ac]. +D 2025-06-28T17:59:15.236 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c dbb55f616dc6e5ad3507bb62ef609a48aaf1f909e40d6878d57d7626213933c5 +F src/expr.c b46621069e36a2fbc966215691e4775134e2cc6c7a6e9e54b01cbb70b51d57a5 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c9ddd15b0197e6e5c5a74581d94cf986523514ffdb28c66ba18de9a22aec97e9 -R e1a26ca0e980fdc17e9e03398afd0539 +P 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 +R c5ec83310afc6f17c7231575eaf1e606 +T *branch * optimize-null-values +T *sym-optimize-null-values * +T -sym-trunk * U drh -Z 007c4fc453decb57a623a0c9c1fba3c7 +Z 4eeee81d77d56831be900c22e39d8eec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cb6314c3f1..19505125a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 +f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0 diff --git a/src/expr.c b/src/expr.c index 6dcf8c3ac3..b4461cf5c6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6088,10 +6088,48 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { + int r2Done = 0; + int addrBypass = 0; if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; testcase( jumpIfNull==0 ); + /* + ** If the left operand is a (possibly expensive) subquery and the + ** right operand is not and the right operation might be NULL and + ** the operator is not IS or IS NOT, then compute the right operand + ** first and skip the computation of the left operand if the right + ** operand is NULL. + */ + if( jumpIfNull!=SQLITE_NULLEQ + && ExprHasProperty(pExpr->pLeft, EP_Subquery) + && !ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pRight) + ){ + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrBypass = sqlite3VdbeAddOp2(v, OP_IsNull, r2, dest); + VdbeCoverageIf(v, jumpIfNull==SQLITE_JUMPIFNULL); + VdbeCoverageIf(v, jumpIfNull!=SQLITE_JUMPIFNULL); + if( jumpIfNull==SQLITE_JUMPIFNULL ) addrBypass = 0; + r2Done = 1; + } r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + if( !r2Done ){ + /* + ** If the right operand is a subquery and the left operand is not + ** and the left operand might be NULL and the comparison operator + ** is not IS or IS NOT, then check the left operand to see if it is + ** NULL and skip the computation of the right operand if it is. + */ + if( jumpIfNull!=SQLITE_NULLEQ + && ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pLeft) + ){ + addrBypass = sqlite3VdbeAddOp2(v, OP_IsNull, r1, dest); + VdbeCoverageIf(v, jumpIfNull==SQLITE_JUMPIFNULL); + VdbeCoverageIf(v, jumpIfNull!=SQLITE_JUMPIFNULL); + if( jumpIfNull==SQLITE_JUMPIFNULL ) addrBypass = 0; + } + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + } codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); @@ -6106,6 +6144,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); + if( addrBypass ) sqlite3VdbeJumpHere(v, addrBypass); break; } case TK_ISNULL: From f0991c416b683ba2f60c049cd2252fb03342cd7f Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 29 Jun 2025 07:32:20 +0000 Subject: [PATCH 10/88] Minor API doc typo fixes from brickviking. FossilOrigin-Name: c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 30 +++++++++++++++--------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 361c6e5174..93d7cf1e20 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Raise\san\serror\sright\saway\sif\sthe\snumber\sof\saggregate\sterms\sin\sa\squery\nexceeds\sthe\smaximum\snumber\sof\scolumns. -D 2025-06-27T19:02:21.291 +C Minor\sAPI\sdoc\stypo\sfixes\sfrom\sbrickviking. +D 2025-06-29T07:32:20.051 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -787,7 +787,7 @@ F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 -F src/sqlite.h.in ab255d9c4944db23ac5a2f3f6ff691b24a9a15b40ac06cef7725639373821df5 +F src/sqlite.h.in 66504dee4c75af4da6d38b07268ad43e51b35fab0de8de13b3d2d76d86356f2c F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqliteInt.h 005542f8760edf9b62f014abccb876cf64533b64475a40a89402054d62535288 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c9ddd15b0197e6e5c5a74581d94cf986523514ffdb28c66ba18de9a22aec97e9 -R e1a26ca0e980fdc17e9e03398afd0539 -U drh -Z 007c4fc453decb57a623a0c9c1fba3c7 +P 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 +R 3e132e460d089303bf7323749c68a0f5 +U stephan +Z 83c85e5970373de1e91193c3207b4c7f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cb6314c3f1..92850fd7df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 +c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4f0072af16..8b12afdd1e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9058,13 +9058,13 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_SORT]]
SQLITE_STMTSTATUS_SORT
**
^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to -** improvement performance through careful use of indices.
+** improve performance through careful use of indices. ** ** [[SQLITE_STMTSTATUS_AUTOINDEX]]
SQLITE_STMTSTATUS_AUTOINDEX
**
^This is the number of rows inserted into transient indices that ** were created automatically in order to help joins run faster. ** A non-zero value in this counter may indicate an opportunity to -** improvement performance by adding permanent indices that do not +** improve performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run.
** ** [[SQLITE_STMTSTATUS_VM_STEP]]
SQLITE_STMTSTATUS_VM_STEP
@@ -9073,19 +9073,19 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 -** then the value returned by this statement status code is undefined. +** then the value returned by this statement status code is undefined. ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
SQLITE_STMTSTATUS_REPREPARE
**
^This is the number of times that the prepare statement has been ** automatically regenerated due to schema changes or changes to -** [bound parameters] that might affect the query plan. +** [bound parameters] that might affect the query plan.
** ** [[SQLITE_STMTSTATUS_RUN]]
SQLITE_STMTSTATUS_RUN
**
^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. ** The counter is incremented on the first [sqlite3_step()] call of each -** cycle. +** cycle.
** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] ** [[SQLITE_STMTSTATUS_FILTER HIT]] @@ -9095,7 +9095,7 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** step was bypassed because a Bloom filter returned not-found. The ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of ** times that the Bloom filter returned a find, and thus the join step -** had to be processed as normal. +** had to be processed as normal. ** ** [[SQLITE_STMTSTATUS_MEMUSED]]
SQLITE_STMTSTATUS_MEMUSED
**
^This is the approximate number of bytes of heap memory @@ -9200,9 +9200,9 @@ struct sqlite3_pcache_page { ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will always a power of two. ^The +** be allocated by the cache. ^szPage will always be a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage -** associated with each page cache entry. ^The szExtra parameter will +** associated with each page cache entry. ^The szExtra parameter will be ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying ** database page on disk. The value passed into szExtra depends @@ -9210,17 +9210,17 @@ struct sqlite3_pcache_page { ** ^The third argument to xCreate(), bPurgeable, is true if the cache being ** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based with the value of bPurgeable; +** does not have to do anything special based upon the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to ** false will always have the "discard" flag set to true. -** ^Hence, a cache created with bPurgeable false will +** ^Hence, a cache created with bPurgeable set to false will ** never contain any unpinned pages. ** ** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the -** suggested maximum cache-size (number of pages stored by) the cache +** suggested maximum cache-size (number of pages stored) for the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this @@ -9247,12 +9247,12 @@ struct sqlite3_pcache_page { ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag -** parameter to help it determined what action to take: +** parameter to help it determine what action to take: ** ** **
createFlag Behavior when page is not already in cache **
0 Do not allocate a new page. Return NULL. -**
1 Allocate a new page if it easy and convenient to do so. +**
1 Allocate a new page if it is easy and convenient to do so. ** Otherwise return NULL. **
2 Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. @@ -9269,7 +9269,7 @@ struct sqlite3_pcache_page { ** as its second argument. If the third parameter, discard, is non-zero, ** then the page must be evicted from the cache. ** ^If the discard parameter is -** zero, then the page may be discarded or retained at the discretion of +** zero, then the page may be discarded or retained at the discretion of the ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** @@ -9287,7 +9287,7 @@ struct sqlite3_pcache_page { ** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal ** to the value of the iLimit parameter passed to xTruncate(). If any -** of these pages are pinned, they are implicitly unpinned, meaning that +** of these pages are pinned, they become implicitly unpinned, meaning that ** they can be safely discarded. ** ** [[the xDestroy() page cache method]] From e24f20a4f5a6d26cdaece58eff77619a4ee757b9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 10:30:47 +0000 Subject: [PATCH 11/88] Factor out the code that tries to avoid evaluating subquery operands if the other operand is NULL into a subroutine, so that it can be more easily reused by other parts of the code generator. FossilOrigin-Name: 3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6 --- manifest | 15 +++--- manifest.uuid | 2 +- src/expr.c | 135 +++++++++++++++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index fcdf5f0344..e4cf97a0e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sbytecode\sgenerated\sfor\scomparisons\sso\sthat\sif\sone\soperand\sis\na\ssubquery\sand\sthe\sother\soperand\sevaluates\sto\sNULL,\sthe\ssubquery\soperand\nis\snot\seven\scomputed.\s\sThis\sfixes\s5\sof\sthe\s12\sslow\squeries\sdescribed\nin\s[forum:/forumpost/52651713ac|forum\spost\s52651713ac]. -D 2025-06-28T17:59:15.236 +C Factor\sout\sthe\scode\sthat\stries\sto\savoid\sevaluating\ssubquery\soperands\sif\sthe\nother\soperand\sis\sNULL\sinto\sa\ssubroutine,\sso\sthat\sit\scan\sbe\smore\seasily\sreused\nby\sother\sparts\sof\sthe\scode\sgenerator. +D 2025-06-30T10:30:47.908 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c b46621069e36a2fbc966215691e4775134e2cc6c7a6e9e54b01cbb70b51d57a5 +F src/expr.c f007ab177a9900d10893a58bf6b756e89144df635bab61b25f37a17390f12778 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 -R c5ec83310afc6f17c7231575eaf1e606 -T *branch * optimize-null-values -T *sym-optimize-null-values * -T -sym-trunk * +P f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0 +R 2a36b21b6d3bc1bf7db15e8f66e788a3 U drh -Z 4eeee81d77d56831be900c22e39d8eec +Z 4ecc3e0b30247a36c4e1fea0e6dc5b85 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 19505125a7..2be7100258 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0 +3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6 diff --git a/src/expr.c b/src/expr.c index b4461cf5c6..de729ea62f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5830,6 +5830,67 @@ static void exprCodeBetween( testcase( xJump==0 ); } +/* +** Compute the two operands of a binary operator. +** +** If either operand contains a subquery, then the code strives to +** compute the operand containing the subquery second. If the other +** operand evalutes to NULL, then a jump is made. The address of the +** IsNull operand that does this jump is returned. The caller can use +** this to optimize the computation so as to avoid doing the potentially +** expensive subquery. +** +** If no optimization opportunities exist, return 0. +*/ +static int exprComputeOperands( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The comparison expression */ + int *pR1, /* OUT: Register holding the left operand */ + int *pR2, /* OUT: Register holding the right operand */ + int *pFree1, /* OUT: Temp register to free if not zero */ + int *pFree2 /* OUT: Another temp register to free if not zero */ +){ + int addrIsNull; + int r1, r2; + Vdbe *v = pParse->pVdbe; + + assert( v!=0 ); + /* + ** If the left operand contains a (possibly expensive) subquery and the + ** right operand does not and the right operation might be NULL, + ** then compute the right operand first and do an IsNull jump if the + ** right operand evalutes to NULL. + */ + if( ExprHasProperty(pExpr->pLeft, EP_Subquery) + && !ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pRight) + ){ + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + }else{ + addrIsNull = 0; + } + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); + if( addrIsNull==0 ){ + /* + ** If the right operand contains a subquery and the left operand does not + ** and the left operand might be NULL, then check the left operand do + ** an IsNull check on the left operand before computing the right + ** operand. + */ + if( ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pLeft) + ){ + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); VdbeCoverage(v); + } + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + } + *pR1 = r1; + *pR2 = r2; + return addrIsNull; +} + + /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution @@ -6076,75 +6137,47 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } case TK_IS: - case TK_ISNOT: + case TK_ISNOT: { testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_ISNOT ); + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; - jumpIfNull = SQLITE_NULLEQ; - /* no break */ deliberate_fall_through + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ, + ExprHasProperty(pExpr,EP_Commuted)); + testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + break; + } case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { - int r2Done = 0; - int addrBypass = 0; + int addrIsNull; if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; - testcase( jumpIfNull==0 ); - /* - ** If the left operand is a (possibly expensive) subquery and the - ** right operand is not and the right operation might be NULL and - ** the operator is not IS or IS NOT, then compute the right operand - ** first and skip the computation of the left operand if the right - ** operand is NULL. - */ - if( jumpIfNull!=SQLITE_NULLEQ - && ExprHasProperty(pExpr->pLeft, EP_Subquery) - && !ExprHasProperty(pExpr->pRight, EP_Subquery) - && sqlite3ExprCanBeNull(pExpr->pRight) - ){ - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - addrBypass = sqlite3VdbeAddOp2(v, OP_IsNull, r2, dest); - VdbeCoverageIf(v, jumpIfNull==SQLITE_JUMPIFNULL); - VdbeCoverageIf(v, jumpIfNull!=SQLITE_JUMPIFNULL); - if( jumpIfNull==SQLITE_JUMPIFNULL ) addrBypass = 0; - r2Done = 1; - } - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - if( !r2Done ){ - /* - ** If the right operand is a subquery and the left operand is not - ** and the left operand might be NULL and the comparison operator - ** is not IS or IS NOT, then check the left operand to see if it is - ** NULL and skip the computation of the right operand if it is. - */ - if( jumpIfNull!=SQLITE_NULLEQ - && ExprHasProperty(pExpr->pRight, EP_Subquery) - && sqlite3ExprCanBeNull(pExpr->pLeft) - ){ - addrBypass = sqlite3VdbeAddOp2(v, OP_IsNull, r1, dest); - VdbeCoverageIf(v, jumpIfNull==SQLITE_JUMPIFNULL); - VdbeCoverageIf(v, jumpIfNull!=SQLITE_JUMPIFNULL); - if( jumpIfNull==SQLITE_JUMPIFNULL ) addrBypass = 0; - } - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - } + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); testcase( regFree1==0 ); testcase( regFree2==0 ); - if( addrBypass ) sqlite3VdbeJumpHere(v, addrBypass); + if( addrIsNull ){ + if( jumpIfNull ){ + sqlite3VdbeChangeP2(v, addrIsNull, dest); + }else{ + sqlite3VdbeJumpHere(v, addrIsNull); + } + } break; } case TK_ISNULL: From b8c81790b241e62c0d550565ebfb9d7f8baed77d Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Jun 2025 11:00:59 +0000 Subject: [PATCH 12/88] Minor API doc typo fixes from brickviking. FossilOrigin-Name: b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 --- manifest | 10 ++++----- manifest.uuid | 2 +- src/sqlite.h.in | 54 ++++++++++++++++++++++++------------------------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 93d7cf1e20..69225deb3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ C Minor\sAPI\sdoc\stypo\sfixes\sfrom\sbrickviking. -D 2025-06-29T07:32:20.051 +D 2025-06-30T11:00:59.442 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -787,7 +787,7 @@ F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 -F src/sqlite.h.in 66504dee4c75af4da6d38b07268ad43e51b35fab0de8de13b3d2d76d86356f2c +F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqliteInt.h 005542f8760edf9b62f014abccb876cf64533b64475a40a89402054d62535288 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 -R 3e132e460d089303bf7323749c68a0f5 +P c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532 +R d7a5649d84482afb1911b4bf92ab7f49 U stephan -Z 83c85e5970373de1e91193c3207b4c7f +Z d71a9678ab9d14d6cf50fe9f605c6dd8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 92850fd7df..d0d4e9bef5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532 +b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 8b12afdd1e..836c09e2aa 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9586,7 +9586,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked -** when the blocking connections current transaction is concluded. ^The +** when the blocking connection's current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** @@ -9606,7 +9606,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback is canceled. ^The blocked connection's ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -10004,7 +10004,7 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** support constraints. In this configuration (which is the default) if ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been -** specified as part of the users SQL statement, regardless of the actual +** specified as part of the user's SQL statement, regardless of the actual ** ON CONFLICT mode specified. ** ** If X is non-zero, then the virtual table implementation guarantees @@ -10038,7 +10038,7 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
SQLITE_VTAB_INNOCUOUS
**
Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a @@ -10206,7 +10206,7 @@ const char *sqlite3_vtab_collation(sqlite3_index_info*,int); **
** ** ^For the purposes of comparing virtual table output values to see if the -** values are same value for sorting purposes, two NULL values are considered +** values are the same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" ** (or "IS NOT DISTINCT FROM") and not "==". ** @@ -10216,7 +10216,7 @@ const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** ** ^A virtual table implementation is always free to return rows in any order ** it wants, as long as the "orderByConsumed" flag is not set. ^When the -** the "orderByConsumed" flag is unset, the query planner will add extra +** "orderByConsumed" flag is unset, the query planner will add extra ** [bytecode] to ensure that the final results returned by the SQL query are ** ordered correctly. The use of the "orderByConsumed" flag and the ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful @@ -10313,7 +10313,7 @@ int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint -** processing use the [sqlite3_vtab_in()] interface in the +** processing using the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint ** processing, then these routines return [SQLITE_ERROR].)^ @@ -10368,7 +10368,7 @@ int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface -** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if ** something goes wrong. ** ** The sqlite3_vtab_rhs_value() interface is usually only successful if @@ -10396,8 +10396,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); ** KEYWORDS: {conflict resolution mode} ** ** These constants are returned by [sqlite3_vtab_on_conflict()] to -** inform a [virtual table] implementation what the [ON CONFLICT] mode -** is for the SQL statement being evaluated. +** inform a [virtual table] implementation of the [ON CONFLICT] mode +** for the SQL statement being evaluated. ** ** Note that the [SQLITE_IGNORE] constant is also used as a potential ** return value from the [sqlite3_set_authorizer()] callback and that @@ -10437,39 +10437,39 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); ** [[SQLITE_SCANSTAT_EST]]
SQLITE_SCANSTAT_EST
**
^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each -** iteration of the X-th loop. If the query planner's estimates was accurate, +** iteration of the X-th loop. If the query planner's estimate was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the ** product of this value for all prior loops with the same SELECTID will -** be the NLOOP value for the current loop. +** be the NLOOP value for the current loop.
** ** [[SQLITE_SCANSTAT_NAME]]
SQLITE_SCANSTAT_NAME
**
^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table -** used for the X-th loop. +** used for the X-th loop.
** ** [[SQLITE_SCANSTAT_EXPLAIN]]
SQLITE_SCANSTAT_EXPLAIN
**
^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] -** description for the X-th loop. +** description for the X-th loop.
** ** [[SQLITE_SCANSTAT_SELECTID]]
SQLITE_SCANSTAT_SELECTID
**
^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the ** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query. +** column of an [EXPLAIN QUERY PLAN] query.
** ** [[SQLITE_SCANSTAT_PARENTID]]
SQLITE_SCANSTAT_PARENTID
**
The "int" variable pointed to by the V parameter will be set to the -** the id of the parent of the current query element, if applicable, or +** id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. +** returned in the second column of an [EXPLAIN QUERY PLAN] query.
** ** [[SQLITE_SCANSTAT_NCYCLE]]
SQLITE_SCANSTAT_NCYCLE
**
The sqlite3_int64 output value is set to the number of cycles, ** according to the processor time-stamp counter, that elapsed while the ** query element was being processed. This value is not available for ** all query elements - if it is unavailable the output variable is -** set to -1. +** set to -1.
** */ #define SQLITE_SCANSTAT_NLOOP 0 @@ -10510,8 +10510,8 @@ int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may be -** to query for statistics regarding the entire query. ^If idx is out of range +** for. Query elements are numbered starting from zero. A value of -1 may +** retrieve statistics for the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. @@ -10668,8 +10668,8 @@ int sqlite3_db_cacheflush(sqlite3*); ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, -** the pre-update hook is invoked with SQLITE_DELETE. This is because the -** in this case the new values are not available. In this case, when a +** the pre-update hook is invoked with SQLITE_DELETE, because +** the new values are not yet available. In this case, when a ** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the @@ -10922,7 +10922,7 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written -** to disk if that database where backed up to disk. +** to disk if that database were backed up to disk. ** ** The usual case is that sqlite3_serialize() copies the serialization of ** the database into memory obtained from [sqlite3_malloc64()] and returns @@ -10931,7 +10931,7 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations ** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite -** is currently using for that database, or NULL if the no such contiguous +** is currently using for that database, or NULL if no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same @@ -11002,7 +11002,7 @@ unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** -** It is not possible to deserialized into the TEMP database. If the +** It is not possible to deserialize into the TEMP database. If the ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** @@ -11024,7 +11024,7 @@ int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ - sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szDb, /* Number of bytes in the deserialization */ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); @@ -11032,7 +11032,7 @@ int sqlite3_deserialize( /* ** CAPI3REF: Flags for sqlite3_deserialize() ** -** The following are allowed values for 6th argument (the F argument) to +** The following are allowed values for the 6th argument (the F argument) to ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization From e2e81e69830bd25ff82bb8ac60d039a8e0efe971 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 11:04:55 +0000 Subject: [PATCH 13/88] Slightly smaller and faster version of the previous check-in. FossilOrigin-Name: f6e6fd02f4ad49c390a2d3c9626d57f9b2fff1f67eb361b30074cc1f5121810e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 32 +++++++++++++++++--------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index e4cf97a0e0..e463cc2d0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sthe\scode\sthat\stries\sto\savoid\sevaluating\ssubquery\soperands\sif\sthe\nother\soperand\sis\sNULL\sinto\sa\ssubroutine,\sso\sthat\sit\scan\sbe\smore\seasily\sreused\nby\sother\sparts\sof\sthe\scode\sgenerator. -D 2025-06-30T10:30:47.908 +C Slightly\ssmaller\sand\sfaster\sversion\sof\sthe\sprevious\scheck-in. +D 2025-06-30T11:04:55.886 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c f007ab177a9900d10893a58bf6b756e89144df635bab61b25f37a17390f12778 +F src/expr.c bfcf223fec3118214c2cc41c6aa520c716cb0e67a673258cd6fab3d143724c15 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0 -R 2a36b21b6d3bc1bf7db15e8f66e788a3 +P 3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6 +R 2d8283b273252189c8c03b9b869c5bf9 U drh -Z 4ecc3e0b30247a36c4e1fea0e6dc5b85 +Z f639db3f82a44bb4f9d7dfb2e1c4da9d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2be7100258..1d72a14d1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6 +f6e6fd02f4ad49c390a2d3c9626d57f9b2fff1f67eb361b30074cc1f5121810e diff --git a/src/expr.c b/src/expr.c index de729ea62f..a2df740af3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6137,20 +6137,12 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } case TK_IS: - case TK_ISNOT: { + case TK_ISNOT: testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_ISNOT ); - if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ, - ExprHasProperty(pExpr,EP_Commuted)); - testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - break; - } + jumpIfNull = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through case TK_LT: case TK_LE: case TK_GT: @@ -6159,16 +6151,26 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_EQ: { int addrIsNull; if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; - addrIsNull = exprComputeOperands(pParse, pExpr, - &r1, &r2, ®Free1, ®Free2); + if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); if( addrIsNull ){ From bbcf035954589f550620a87077c057973ba1d176 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Jun 2025 11:46:10 +0000 Subject: [PATCH 14/88] Preliminary refactoring of the XDG_CONFIG_HOME support to support the pending addition of other XDG-configurable options. In response to [forum:31db1a23f9 | forum post 31db1a23f9]. FossilOrigin-Name: 69b9244e3ad95edae38d8e66cedafbc1d7724ae0dd72eeee0fdbff913983598e --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/shell.c.in | 31 ++++++++++++++++++------------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 69225deb3f..1ff571dcf0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sAPI\sdoc\stypo\sfixes\sfrom\sbrickviking. -D 2025-06-30T11:00:59.442 +C Preliminary\srefactoring\sof\sthe\sXDG_CONFIG_HOME\ssupport\sto\ssupport\sthe\spending\saddition\sof\sother\sXDG-configurable\soptions.\sIn\sresponse\sto\s[forum:31db1a23f9\s|\sforum\spost\s31db1a23f9]. +D 2025-06-30T11:46:10.395 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -786,7 +786,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 -F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 +F src/shell.c.in 98cc5a8ef982e9c60e0d8146ed8c38774a0f80f23c104a115c27f05893d3641d F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532 -R d7a5649d84482afb1911b4bf92ab7f49 +P b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 +R 6309a1fd152193cda47202f25b8c3c35 +T *branch * shell-xdg-vars +T *sym-shell-xdg-vars * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z d71a9678ab9d14d6cf50fe9f605c6dd8 +Z 195b94022bc466347bd2a5713b9a2796 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d0d4e9bef5..1bc3ddd926 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 +69b9244e3ad95edae38d8e66cedafbc1d7724ae0dd72eeee0fdbff913983598e diff --git a/src/shell.c.in b/src/shell.c.in index 33dd30697d..6302a9a17c 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12759,30 +12759,34 @@ static char *find_home_dir(int clearFlag){ } /* -** On non-Windows platforms, look for $XDG_CONFIG_HOME. -** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return -** the path to it. If there is no $(XDG_CONFIG_HOME) then -** look for $(HOME)/.config/sqlite3/sqliterc and if found -** return that. If none of these are found, return 0. +** On non-Windows platforms, look for $zEnvVar, which must be the name +** of an XDG_... environment variable. If ${zEnvVar}/${zBaseName} is +** found, return the path to it. If ${zEnvVar} is not set then look +** for ${HOME}/${zSubdir}/${zBaseName} and if found return that. If +** none of these are found, return 0. +** +** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir +** will conventionally be ".config" or ".local". ** ** The string returned is obtained from sqlite3_malloc() and ** should be freed by the caller. */ -static char *find_xdg_config(void){ +static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, + const char *zBaseName){ #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ || defined(__RTP__) || defined(_WRS_KERNEL) return 0; #else char *zConfig = 0; - const char *zXdgHome; + const char *zXdgDir; - zXdgHome = getenv("XDG_CONFIG_HOME"); - if( zXdgHome==0 ){ + zXdgDir = getenv(zEnvVar); + if( zXdgDir==0 ){ const char *zHome = getenv("HOME"); if( zHome==0 ) return 0; - zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome); + zConfig = sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName); }else{ - zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); + zConfig = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); } shell_check_oom(zConfig); if( access(zConfig,0)!=0 ){ @@ -12795,7 +12799,7 @@ static char *find_xdg_config(void){ /* ** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from the first of find_xdg_config() +** parameter is NULL, take input from the first of find_xdg_file() ** or ~/.sqliterc which is found. ** ** Returns the number of errors. @@ -12811,7 +12815,8 @@ static void process_sqliterc( int savedLineno = p->lineno; if( sqliterc == NULL ){ - sqliterc = zBuf = find_xdg_config(); + sqliterc = zBuf = find_xdg_file("XDG_CONFIG_HOME", + ".config", "sqlite3/sqliterc"); } if( sqliterc == NULL ){ home_dir = find_home_dir(0); From 280559b4460fde73316d3e2bce7ee4bd3465cd52 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 12:14:47 +0000 Subject: [PATCH 15/88] For all binary operators, try to avoid computing subquery operands if the other operand is NULL. FossilOrigin-Name: d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f --- manifest | 12 +-- manifest.uuid | 2 +- src/expr.c | 251 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 168 insertions(+), 97 deletions(-) diff --git a/manifest b/manifest index e463cc2d0a..e91cca371a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\sversion\sof\sthe\sprevious\scheck-in. -D 2025-06-30T11:04:55.886 +C For\sall\sbinary\soperators,\stry\sto\savoid\scomputing\ssubquery\soperands\sif\sthe\nother\soperand\sis\sNULL. +D 2025-06-30T12:14:47.305 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c bfcf223fec3118214c2cc41c6aa520c716cb0e67a673258cd6fab3d143724c15 +F src/expr.c d726acf67585c14473e354c3d1123a4290e357bdfd389056a05df15b70f66d49 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6 -R 2d8283b273252189c8c03b9b869c5bf9 +P f6e6fd02f4ad49c390a2d3c9626d57f9b2fff1f67eb361b30074cc1f5121810e +R 886172909745da80cda276284a701cfd U drh -Z f639db3f82a44bb4f9d7dfb2e1c4da9d +Z 78219ecf578f4ce2acfc88c5fa4f82e5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1d72a14d1a..de2b008d69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6e6fd02f4ad49c390a2d3c9626d57f9b2fff1f67eb361b30074cc1f5121810e +d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f diff --git a/src/expr.c b/src/expr.c index a2df740af3..6cb9c2aa13 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2373,6 +2373,81 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ return pExpr; } +/* +** Return true if it might be advantageous to compute the right operand +** of expression pExpr first, before the left operand. +** +** Normally the left operand is computed before the right operand. But if +** the left operand contains a subquery and the right does not, then it +** might be more efficient to compute the right operand first. +*/ +static int exprEvalRhsFirst(Expr *pExpr){ + if( ExprHasProperty(pExpr->pLeft, EP_Subquery) + && !ExprHasProperty(pExpr->pRight, EP_Subquery) + ){ + return 1; + }else{ + return 0; + } +} + +/* +** Compute the two operands of a binary operator. +** +** If either operand contains a subquery, then the code strives to +** compute the operand containing the subquery second. If the other +** operand evalutes to NULL, then a jump is made. The address of the +** IsNull operand that does this jump is returned. The caller can use +** this to optimize the computation so as to avoid doing the potentially +** expensive subquery. +** +** If no optimization opportunities exist, return 0. +*/ +static int exprComputeOperands( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The comparison expression */ + int *pR1, /* OUT: Register holding the left operand */ + int *pR2, /* OUT: Register holding the right operand */ + int *pFree1, /* OUT: Temp register to free if not zero */ + int *pFree2 /* OUT: Another temp register to free if not zero */ +){ + int addrIsNull; + int r1, r2; + Vdbe *v = pParse->pVdbe; + + assert( v!=0 ); + /* + ** If the left operand contains a (possibly expensive) subquery and the + ** right operand does not and the right operation might be NULL, + ** then compute the right operand first and do an IsNull jump if the + ** right operand evalutes to NULL. + */ + if( exprEvalRhsFirst(pExpr) && sqlite3ExprCanBeNull(pExpr->pRight) ){ + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + }else{ + addrIsNull = 0; + } + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); + if( addrIsNull==0 ){ + /* + ** If the right operand contains a subquery and the left operand does not + ** and the left operand might be NULL, then check the left operand do + ** an IsNull check on the left operand before computing the right + ** operand. + */ + if( ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pLeft) + ){ + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); VdbeCoverage(v); + } + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + } + *pR1 = r1; + *pR2 = r2; + return addrIsNull; +} + /* ** pExpr is a TK_FUNCTION node. Try to determine whether or not the ** function is a constant function. A function is constant if all of @@ -4961,11 +5036,17 @@ expr_code_doover: case TK_NE: case TK_EQ: { Expr *pLeft = pExpr->pLeft; + int addrIsNull = 0; if( sqlite3ExprIsVector(pLeft) ){ codeVectorCompare(pParse, pExpr, target, op, p5); }else{ - r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + if( ExprHasProperty(pExpr, EP_Subquery) && p5!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + } sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg); codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2, sqlite3VdbeCurrentAddr(v)+2, p5, @@ -4980,9 +5061,15 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg); }else{ sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2); + if( addrIsNull ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addrIsNull); + sqlite3VdbeAddOp2(v, OP_Null, 0, inReg); + } } testcase( regFree1==0 ); testcase( regFree2==0 ); + } break; } @@ -4998,6 +5085,7 @@ expr_code_doover: case TK_LSHIFT: case TK_RSHIFT: case TK_CONCAT: { + int addrIsNull; assert( TK_AND==OP_And ); testcase( op==TK_AND ); assert( TK_OR==OP_Or ); testcase( op==TK_OR ); assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); @@ -5009,11 +5097,22 @@ expr_code_doover: assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + if( ExprHasProperty(pExpr, EP_Subquery) ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } sqlite3VdbeAddOp3(v, op, r2, r1, target); testcase( regFree1==0 ); testcase( regFree2==0 ); + if( addrIsNull ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addrIsNull); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } break; } case TK_UMINUS: { @@ -5830,67 +5929,6 @@ static void exprCodeBetween( testcase( xJump==0 ); } -/* -** Compute the two operands of a binary operator. -** -** If either operand contains a subquery, then the code strives to -** compute the operand containing the subquery second. If the other -** operand evalutes to NULL, then a jump is made. The address of the -** IsNull operand that does this jump is returned. The caller can use -** this to optimize the computation so as to avoid doing the potentially -** expensive subquery. -** -** If no optimization opportunities exist, return 0. -*/ -static int exprComputeOperands( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* The comparison expression */ - int *pR1, /* OUT: Register holding the left operand */ - int *pR2, /* OUT: Register holding the right operand */ - int *pFree1, /* OUT: Temp register to free if not zero */ - int *pFree2 /* OUT: Another temp register to free if not zero */ -){ - int addrIsNull; - int r1, r2; - Vdbe *v = pParse->pVdbe; - - assert( v!=0 ); - /* - ** If the left operand contains a (possibly expensive) subquery and the - ** right operand does not and the right operation might be NULL, - ** then compute the right operand first and do an IsNull jump if the - ** right operand evalutes to NULL. - */ - if( ExprHasProperty(pExpr->pLeft, EP_Subquery) - && !ExprHasProperty(pExpr->pRight, EP_Subquery) - && sqlite3ExprCanBeNull(pExpr->pRight) - ){ - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); - }else{ - addrIsNull = 0; - } - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); - if( addrIsNull==0 ){ - /* - ** If the right operand contains a subquery and the left operand does not - ** and the left operand might be NULL, then check the left operand do - ** an IsNull check on the left operand before computing the right - ** operand. - */ - if( ExprHasProperty(pExpr->pRight, EP_Subquery) - && sqlite3ExprCanBeNull(pExpr->pLeft) - ){ - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); VdbeCoverage(v); - } - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); - } - *pR1 = r1; - *pR2 = r2; - return addrIsNull; -} - - /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution @@ -5923,17 +5961,27 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); if( pAlt!=pExpr ){ sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); - }else if( op==TK_AND ){ - int d2 = sqlite3VdbeMakeLabel(pParse); - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, - jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); }else{ - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + Expr *pFirst, *pSecond; + if( exprEvalRhsFirst(pExpr) ){ + pFirst = pExpr->pRight; + pSecond = pExpr->pLeft; + }else{ + pFirst = pExpr->pLeft; + pSecond = pExpr->pRight; + } + if( op==TK_AND ){ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pFirst, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + }else{ + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pFirst, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull); + } } break; } @@ -5972,10 +6020,16 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { + int addrIsNull; if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; - testcase( jumpIfNull==0 ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); @@ -5990,6 +6044,13 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); + if( addrIsNull ){ + if( jumpIfNull ){ + sqlite3VdbeChangeP2(v, addrIsNull, dest); + }else{ + sqlite3VdbeJumpHere(v, addrIsNull); + } + } break; } case TK_ISNULL: @@ -6097,17 +6158,27 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); if( pAlt!=pExpr ){ sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); - }else if( pExpr->op==TK_AND ){ - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); }else{ - int d2 = sqlite3VdbeMakeLabel(pParse); - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, - jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); + Expr *pFirst, *pSecond; + if( exprEvalRhsFirst(pExpr) ){ + pFirst = pExpr->pRight; + pSecond = pExpr->pLeft; + }else{ + pFirst = pExpr->pLeft; + pSecond = pExpr->pRight; + } + if( pExpr->op==TK_AND ){ + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pFirst, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull); + }else{ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pFirst, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + } } break; } @@ -6166,11 +6237,11 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); assert(TK_NE==OP_Ne); testcase(op==OP_Ne); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); if( addrIsNull ){ From 2752d1331dd76d418ee1df0a79c3c1eca758ac5c Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Jun 2025 15:21:46 +0000 Subject: [PATCH 16/88] Add support for using $XDG_STATE_HOME/sqlite_history or ~/.local/state/sqlite_history before fallback back to the historical default of ~/.sqlite_history. Update sqlite3.1 (man page) with the new semantics. FossilOrigin-Name: 6b780655ccd68d068b6ee6621e56ac94c000916b7341651dc79725a0800cd1c0 --- manifest | 17 ++++----- manifest.uuid | 2 +- sqlite3.1 | 28 ++++++++++++--- src/shell.c.in | 97 +++++++++++++++++++++++++++++--------------------- 4 files changed, 89 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index 1ff571dcf0..3c96f8063d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Preliminary\srefactoring\sof\sthe\sXDG_CONFIG_HOME\ssupport\sto\ssupport\sthe\spending\saddition\sof\sother\sXDG-configurable\soptions.\sIn\sresponse\sto\s[forum:31db1a23f9\s|\sforum\spost\s31db1a23f9]. -D 2025-06-30T11:46:10.395 +C Add\ssupport\sfor\susing\s$XDG_STATE_HOME/sqlite_history\sor\s~/.local/state/sqlite_history\sbefore\sfallback\sback\sto\sthe\shistorical\sdefault\sof\s~/.sqlite_history.\sUpdate\ssqlite3.1\s(man\spage)\swith\sthe\snew\ssemantics. +D 2025-06-30T15:21:46.262 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -717,7 +717,7 @@ F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8 F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b -F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc +F sqlite3.1 9e426a150af072be26b0661bcd54567692d979e99bc7daf55b22b952ff8e41a6 F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d @@ -786,7 +786,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 -F src/shell.c.in 98cc5a8ef982e9c60e0d8146ed8c38774a0f80f23c104a115c27f05893d3641d +F src/shell.c.in 1cf75c1b4aee3fb3dbcedb59c0512977450ada75d2ca00bb08df1adf0055db0b F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 -R 6309a1fd152193cda47202f25b8c3c35 -T *branch * shell-xdg-vars -T *sym-shell-xdg-vars * -T -sym-trunk * Cancelled\sby\sbranch. +P 69b9244e3ad95edae38d8e66cedafbc1d7724ae0dd72eeee0fdbff913983598e +R b75f67e480beb6664bd060c4305917e3 U stephan -Z 195b94022bc466347bd2a5713b9a2796 +Z 13d46cdb1a0ac8d1c628b18b42886e33 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1bc3ddd926..9fa37d6a51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69b9244e3ad95edae38d8e66cedafbc1d7724ae0dd72eeee0fdbff913983598e +6b780655ccd68d068b6ee6621e56ac94c000916b7341651dc79725a0800cd1c0 diff --git a/sqlite3.1 b/sqlite3.1 index 08b1ff262b..3332a164b3 100644 --- a/sqlite3.1 +++ b/sqlite3.1 @@ -137,17 +137,37 @@ continue prompt = " ...> " .sp .fi -o If the file +o If the environment variable XDG_CONFIG_HOME is set then .B ${XDG_CONFIG_HOME}/sqlite3/sqliterc -or +is checked, else +.B ~/.local/config/sqlite3/sqliterc +is checked. If the selected file does not exist then the fallback of .B ~/.sqliterc -exists, the first of those to be found is processed during startup. -It should generally only contain meta-commands. +is used. It should generally only contain meta-commands. o If the -init option is present, the specified file is processed. o All other command line options are processed. +.SH HISTORY FILE +.B sqlite3 +may be configured to use a history file to save SQL statements and +meta-commands entered interactively. These statements and commands can be +retrieved, edited and, reused at the main and continue prompts. If the +environment variable +.B SQLITE_HISTORY +is set, it will be used as the name of the history file, whether it +already exists or not. If it is not set but the XDG_STATE_HOME +environment variable is then +.B ${XDG_STATE_HOME}/sqlite_history +is used. If XDG_STATE_HOME is not set then +.B ~/.local/state/sqlite_history +is used. If the selected file does not exist then +.B ~/.sqlite_history +will be used as the history file. If any history file is found, it +will be written if the shell exits interactive mode normally, +regardless of whether it existed previously, though saving will +silently fail if the history file's directory does not exist. .SH SEE ALSO https://sqlite.org/cli.html .br diff --git a/src/shell.c.in b/src/shell.c.in index 6302a9a17c..790106cdb9 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12759,17 +12759,25 @@ static char *find_home_dir(int clearFlag){ } /* -** On non-Windows platforms, look for $zEnvVar, which must be the name -** of an XDG_... environment variable. If ${zEnvVar}/${zBaseName} is -** found, return the path to it. If ${zEnvVar} is not set then look -** for ${HOME}/${zSubdir}/${zBaseName} and if found return that. If -** none of these are found, return 0. +** On non-Windows platforms, look for the first file found out of: +** +** - ${zEnvVar}/${zBaseName} +** - ${HOME}/${zSubdir}/${zBaseName} +** +** $zEnvVar is intended to be the name of an XDG_... environment +** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is +** NULL or getenv(zEnvVar) is NULL then fall back to the second +** option. If the selected option is not found in the filesystem, +** return 0. +** +** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName} +** becomes the fallback. ** ** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir -** will conventionally be ".config" or ".local". +** will conventionally be ".config" or ".local/state". ** -** The string returned is obtained from sqlite3_malloc() and -** should be freed by the caller. +** The returned string is obtained from sqlite3_malloc() and should be +** sqlite3_free()'d by the caller. */ static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, const char *zBaseName){ @@ -12777,46 +12785,51 @@ static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, || defined(__RTP__) || defined(_WRS_KERNEL) return 0; #else - char *zConfig = 0; + char *zConfigFile = 0; const char *zXdgDir; - zXdgDir = getenv(zEnvVar); - if( zXdgDir==0 ){ - const char *zHome = getenv("HOME"); - if( zHome==0 ) return 0; - zConfig = sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName); + zXdgDir = zEnvVar ? getenv(zEnvVar) : 0; + if( zXdgDir ){ + zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); }else{ - zConfig = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); + const char * zHome = find_home_dir(0); + if( zHome==0 ) return 0; + zConfigFile = (zSubdir && *zSubdir) + ? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName) + : sqlite3_mprintf("%s/%s", zHome, zBaseName); } - shell_check_oom(zConfig); - if( access(zConfig,0)!=0 ){ - sqlite3_free(zConfig); - zConfig = 0; + shell_check_oom(zConfigFile); + if( access(zConfigFile,0)!=0 ){ + sqlite3_free(zConfigFile); + zConfigFile = 0; } - return zConfig; + return zConfigFile; #endif } /* -** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from the first of find_xdg_file() -** or ~/.sqliterc which is found. +** Read input from the file sqliterc_override. If that parameter is +** NULL, take it from find_xdg_file(), if found, or fall back to +** ~/.sqliterc. ** -** Returns the number of errors. +** Failure to read the config is only considered a failure if +** sqliterc_override is not NULL, in which case this function may emit +** a warning or, if ::bail_on_error is true, fail fatally if the file +** named by sqliterc_override is not found. */ static void process_sqliterc( ShellState *p, /* Configuration data */ const char *sqliterc_override /* Name of config file. NULL to use default */ ){ char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf = 0; + char *sqliterc = sqliterc_override; FILE *inSaved = p->in; int savedLineno = p->lineno; if( sqliterc == NULL ){ - sqliterc = zBuf = find_xdg_file("XDG_CONFIG_HOME", - ".config", "sqlite3/sqliterc"); + sqliterc = find_xdg_file("XDG_CONFIG_HOME", + ".local/config", + "sqlite3/sqliterc"); } if( sqliterc == NULL ){ home_dir = find_home_dir(0); @@ -12825,11 +12838,10 @@ static void process_sqliterc( " cannot read ~/.sqliterc\n"); return; } - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); - shell_check_oom(zBuf); - sqliterc = zBuf; + sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir); + shell_check_oom(sqliterc); } - p->in = sqlite3_fopen(sqliterc,"rb"); + p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0; if( p->in ){ if( stdin_is_interactive ){ sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); @@ -12842,7 +12854,9 @@ static void process_sqliterc( } p->in = inSaved; p->lineno = savedLineno; - sqlite3_free(zBuf); + if( sqliterc != sqliterc_override ){ + sqlite3_free(sqliterc); + } } /* @@ -13610,7 +13624,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( stdin_is_interactive ){ char *zHome; char *zHistory; - int nHistory; sqlite3_fprintf(stdout, "SQLite version %s %.19s\n" /*extra-version-info*/ "Enter \".help\" for usage hints.\n", @@ -13623,11 +13636,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } zHistory = getenv("SQLITE_HISTORY"); if( zHistory ){ - zHistory = strdup(zHistory); - }else if( (zHome = find_home_dir(0))!=0 ){ - nHistory = strlen30(zHome) + 20; - if( (zHistory = malloc(nHistory))!=0 ){ - sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); + zHistory = sqlite3_mprintf("%s", zHistory); + shell_check_oom(zHistory); + }else{ + zHistory = find_xdg_file("XDG_STATE_HOME", + ".local/state", + "sqlite_history"); + if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){ + zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome); + shell_check_oom(zHistory); } } if( zHistory ){ shell_read_history(zHistory); } @@ -13643,7 +13660,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( zHistory ){ shell_stifle_history(2000); shell_write_history(zHistory); - free(zHistory); + sqlite3_free(zHistory); } }else{ data.in = stdin; From 1bd6b415e90f5ce85b54046d50abc23dd0f41e03 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Jun 2025 15:56:10 +0000 Subject: [PATCH 17/88] Correct ~/.local/config/... to ~/.config/... when looking for sqliterc when XDG_CONFIG_HOME is not set. Internal doc touchups. FossilOrigin-Name: ebb346c5aa427b9e84a035278ee245d54810d9954efef12b898f2d7bc0ff630c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3c96f8063d..5c85b7714b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\susing\s$XDG_STATE_HOME/sqlite_history\sor\s~/.local/state/sqlite_history\sbefore\sfallback\sback\sto\sthe\shistorical\sdefault\sof\s~/.sqlite_history.\sUpdate\ssqlite3.1\s(man\spage)\swith\sthe\snew\ssemantics. -D 2025-06-30T15:21:46.262 +C Correct\s~/.local/config/...\sto\s~/.config/...\swhen\slooking\sfor\ssqliterc\swhen\sXDG_CONFIG_HOME\sis\snot\sset.\sInternal\sdoc\stouchups. +D 2025-06-30T15:56:10.103 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -786,7 +786,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 -F src/shell.c.in 1cf75c1b4aee3fb3dbcedb59c0512977450ada75d2ca00bb08df1adf0055db0b +F src/shell.c.in 56f3719f22b1dcab01b4c52dc21224bbc46dcc52a0e95407293736fc88fd41c1 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 69b9244e3ad95edae38d8e66cedafbc1d7724ae0dd72eeee0fdbff913983598e -R b75f67e480beb6664bd060c4305917e3 +P 6b780655ccd68d068b6ee6621e56ac94c000916b7341651dc79725a0800cd1c0 +R 797b3e78135d622f3aa0a1b4105d4fa3 U stephan -Z 13d46cdb1a0ac8d1c628b18b42886e33 +Z bfe5fd02ba4d5c951c96e8138fec5fad # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9fa37d6a51..6777f3edc1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b780655ccd68d068b6ee6621e56ac94c000916b7341651dc79725a0800cd1c0 +ebb346c5aa427b9e84a035278ee245d54810d9954efef12b898f2d7bc0ff630c diff --git a/src/shell.c.in b/src/shell.c.in index 790106cdb9..ccdf89a2f0 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12759,7 +12759,7 @@ static char *find_home_dir(int clearFlag){ } /* -** On non-Windows platforms, look for the first file found out of: +** On non-Windows platforms, look for: ** ** - ${zEnvVar}/${zBaseName} ** - ${HOME}/${zSubdir}/${zBaseName} @@ -12828,7 +12828,7 @@ static void process_sqliterc( if( sqliterc == NULL ){ sqliterc = find_xdg_file("XDG_CONFIG_HOME", - ".local/config", + ".config", "sqlite3/sqliterc"); } if( sqliterc == NULL ){ From ba56f7020d5829aa9b4b9a7556ca23785fa771f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 20:19:19 +0000 Subject: [PATCH 18/88] Compute WhereLevel.addrBrk and .addrHalt early so that those labels can be used to abort loops early. Use this to improve performance on two more of the cases described by [forum:/forumpost/52651713ac|forum post 52651713ac]. FossilOrigin-Name: 6fc0b9ac23be6840542982de4bb282ebca1db8b5ab3baefdde95a997c1506e81 --- manifest | 20 +++++++++++--------- manifest.uuid | 2 +- src/where.c | 16 ++++++++++++++-- src/whereInt.h | 1 + src/wherecode.c | 21 ++++++++++++--------- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 055652fcb7..a99c608631 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strive\sto\sskip\sthe\sevaluation\sof\sscalar\ssubqueries\sthat\sare\spart\sof\sa\nlarger\sexpression\sif\sthe\sresult\sfrom\sthe\sscalar\ssubquery\sdoes\snot\schange\sthe\nresult\sof\sthe\soverall\sexpression. -D 2025-06-30T16:41:40.414 +C Compute\sWhereLevel.addrBrk\sand\s.addrHalt\searly\sso\sthat\sthose\slabels\scan\sbe\nused\sto\sabort\sloops\searly.\s\sUse\sthis\sto\simprove\sperformance\son\stwo\smore\nof\sthe\scases\sdescribed\sby\s[forum:/forumpost/52651713ac|forum\spost\s52651713ac]. +D 2025-06-30T20:19:19.423 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -867,9 +867,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c a99fa3061a0155d2cb0e2c91df76dbf834750272a8d79ec5e2dce3ed4e6abad6 -F src/whereInt.h 02b646ea41a8342815b3628f8064c32618ea2e0f20b83216ea08cad11f0ac5aa -F src/wherecode.c 9710e62379c000189476404f923d4d1b192d0def222fdd287b820cc085a0d555 +F src/where.c baedbf818b67006033204fd9814bf1dc80bec728ed0340cf49146be36ddd5f40 +F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da +F src/wherecode.c 0ee8afb68c04adaba81329f5c358010b2d8943d00a55161a34081acf830daa11 F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807 F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -2208,9 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f -R 9194e4789912b64a71b73947ca782430 -T +closed d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f +P 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 +R d7249f5cf7b6d480f743946f8ed64b97 +T *branch * empty-table-optimizations +T *sym-empty-table-optimizations * +T -sym-trunk * U drh -Z 98e7e495521ce39084e96bf3212efc13 +Z 7f9eb68d1bb4b376d2d8134bae280e6b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2bedf7c1b1..918ff018c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 +6fc0b9ac23be6840542982de4bb282ebca1db8b5ab3baefdde95a997c1506e81 diff --git a/src/where.c b/src/where.c index 11e24a8d39..824cfcd8c9 100644 --- a/src/where.c +++ b/src/where.c @@ -1201,7 +1201,9 @@ static SQLITE_NOINLINE void constructAutomaticIndex( VdbeCoverage(v); VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); }else{ - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); + assert( pLevel->addrHalt ); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind,pLevel->iTabCur,pLevel->addrHalt); + VdbeCoverage(v); } if( pPartial ){ iContinue = sqlite3VdbeMakeLabel(pParse); @@ -1229,11 +1231,14 @@ static SQLITE_NOINLINE void constructAutomaticIndex( pSrc->u4.pSubq->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); pSrc->fg.viaCoroutine = 0; + sqlite3VdbeJumpHere(v, addrTop); }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + if( (pSrc->fg.jointype & JT_LEFT)!=0 ){ + sqlite3VdbeJumpHere(v, addrTop); + } } - sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); /* Jump here when skipping the initialization */ @@ -7070,6 +7075,12 @@ WhereInfo *sqlite3WhereBegin( pTab = pTabItem->pSTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; + pLevel->addrBrk = sqlite3VdbeMakeLabel(pParse); + if( ii==0 || (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ + pLevel->addrHalt = pLevel->addrBrk; + }else{ + pLevel->addrHalt = pWInfo->a[ii-1].addrHalt; + } if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ /* Do nothing */ }else @@ -7200,6 +7211,7 @@ WhereInfo *sqlite3WhereBegin( && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 ){ WhereRightJoin *pRJ = pLevel->pRJ; + pLevel->addrHalt = pLevel->addrBrk; pRJ->iMatch = pParse->nTab++; pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); diff --git a/src/whereInt.h b/src/whereInt.h index 3a9353e070..09e02c8c73 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -75,6 +75,7 @@ struct WhereLevel { int iTabCur; /* The VDBE cursor used to access the table */ int iIdxCur; /* The VDBE cursor used to access pIdx */ int addrBrk; /* Jump here to break out of the loop */ + int addrHalt; /* Abort the query due to empty table or similar */ int addrNxt; /* Jump here to start the next IN combination */ int addrSkip; /* Jump here for next iteration of skip-scan */ int addrCont; /* Jump here to continue with the next loop cycle */ diff --git a/src/wherecode.c b/src/wherecode.c index 9581ac3891..c5fa7a213a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1400,6 +1400,7 @@ static SQLITE_NOINLINE void filterPullDown( int addrNxt, /* Jump here to bypass inner loops */ Bitmask notReady /* Loops that are not ready */ ){ + int saved_addrBrk; while( ++iLevel < pWInfo->nLevel ){ WhereLevel *pLevel = &pWInfo->a[iLevel]; WhereLoop *pLoop = pLevel->pWLoop; @@ -1408,7 +1409,7 @@ static SQLITE_NOINLINE void filterPullDown( /* ,--- Because sqlite3ConstructBloomFilter() has will not have set ** vvvvv--' pLevel->regFilter if this were true. */ if( NEVER(pLoop->prereq & notReady) ) continue; - assert( pLevel->addrBrk==0 ); + saved_addrBrk = pLevel->addrBrk; pLevel->addrBrk = addrNxt; if( pLoop->wsFlags & WHERE_IPK ){ WhereTerm *pTerm = pLoop->aLTerm[0]; @@ -1438,7 +1439,7 @@ static SQLITE_NOINLINE void filterPullDown( VdbeCoverage(pParse->pVdbe); } pLevel->regFilter = 0; - pLevel->addrBrk = 0; + pLevel->addrBrk = saved_addrBrk; } } @@ -1485,7 +1486,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3 *db; /* Database connection */ SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ - int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ int iReleaseReg = 0; /* Temp register to free before returning */ @@ -1529,7 +1529,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** there are no IN operators in the constraints, the "addrNxt" label ** is the same as "addrBrk". */ - addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + addrBrk = pLevel->addrNxt = pLevel->addrBrk; addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); /* If this is the right table of a LEFT OUTER JOIN, allocate and @@ -1545,13 +1545,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "init LEFT JOIN match flag")); } - /* Compute a safe address to jump to if we discover that the table for - ** this loop is empty and can never contribute content. */ +#ifdef SQLITE_DEBUG + /* Re-compute the address to jump to if we discover that the table for + ** this loop is empty and can never contribute content. Verify that the + ** computation here agrees with the one in sqlite3WhereBegin(). */ for(j=iLevel; j>0; j--){ if( pWInfo->a[j].iLeftJoin ) break; if( pWInfo->a[j].pRJ ) break; } - addrHalt = pWInfo->a[j].addrBrk; + assert( pWInfo->a[j].addrBrk==pLevel->addrHalt ); +#endif /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ @@ -1791,7 +1794,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, pX->op==TK_GE); sqlite3ReleaseTempReg(pParse, rTemp); }else{ - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, pLevel->addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); } @@ -2586,7 +2589,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( codeCursorHint(pTabItem, pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev],iCur,pLevel->addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; From 3d21dcc924fb1049c7e0cbc42a21ebfe17d472b6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 21:07:08 +0000 Subject: [PATCH 19/88] More aggressive optimization of addrHalt for RIGHT JOIN. FossilOrigin-Name: 5e51d1c0dfcafef9e71c99de3f626dee157c935724b84c6e0c630299a880446f --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/where.c | 3 ++- src/wherecode.c | 11 ----------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index a99c608631..88cc0f7f5e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Compute\sWhereLevel.addrBrk\sand\s.addrHalt\searly\sso\sthat\sthose\slabels\scan\sbe\nused\sto\sabort\sloops\searly.\s\sUse\sthis\sto\simprove\sperformance\son\stwo\smore\nof\sthe\scases\sdescribed\sby\s[forum:/forumpost/52651713ac|forum\spost\s52651713ac]. -D 2025-06-30T20:19:19.423 +C More\saggressive\soptimization\sof\saddrHalt\sfor\sRIGHT\sJOIN. +D 2025-06-30T21:07:08.690 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -867,9 +867,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c baedbf818b67006033204fd9814bf1dc80bec728ed0340cf49146be36ddd5f40 +F src/where.c f58d41d0923eeb21cab8e4fc87a0b36c0724ff4f279ce95ab2731b4696b8e75a F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da -F src/wherecode.c 0ee8afb68c04adaba81329f5c358010b2d8943d00a55161a34081acf830daa11 +F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807 F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 -R d7249f5cf7b6d480f743946f8ed64b97 -T *branch * empty-table-optimizations -T *sym-empty-table-optimizations * -T -sym-trunk * +P 6fc0b9ac23be6840542982de4bb282ebca1db8b5ab3baefdde95a997c1506e81 +R 6c3da4fefe78ebf60c93e1bf3ae9f682 U drh -Z 7f9eb68d1bb4b376d2d8134bae280e6b +Z c1632b7819f69e809c6c7ab2b9282264 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 918ff018c7..c009925a2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fc0b9ac23be6840542982de4bb282ebca1db8b5ab3baefdde95a997c1506e81 +5e51d1c0dfcafef9e71c99de3f626dee157c935724b84c6e0c630299a880446f diff --git a/src/where.c b/src/where.c index 824cfcd8c9..ddf3f74996 100644 --- a/src/where.c +++ b/src/where.c @@ -7078,6 +7078,8 @@ WhereInfo *sqlite3WhereBegin( pLevel->addrBrk = sqlite3VdbeMakeLabel(pParse); if( ii==0 || (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->addrHalt = pLevel->addrBrk; + }else if( pWInfo->a[ii-1].pRJ ){ + pLevel->addrHalt = pWInfo->a[ii-1].addrBrk; }else{ pLevel->addrHalt = pWInfo->a[ii-1].addrHalt; } @@ -7211,7 +7213,6 @@ WhereInfo *sqlite3WhereBegin( && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 ){ WhereRightJoin *pRJ = pLevel->pRJ; - pLevel->addrHalt = pLevel->addrBrk; pRJ->iMatch = pParse->nTab++; pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); diff --git a/src/wherecode.c b/src/wherecode.c index c5fa7a213a..cc672aa839 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1545,17 +1545,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "init LEFT JOIN match flag")); } -#ifdef SQLITE_DEBUG - /* Re-compute the address to jump to if we discover that the table for - ** this loop is empty and can never contribute content. Verify that the - ** computation here agrees with the one in sqlite3WhereBegin(). */ - for(j=iLevel; j>0; j--){ - if( pWInfo->a[j].iLeftJoin ) break; - if( pWInfo->a[j].pRJ ) break; - } - assert( pWInfo->a[j].addrBrk==pLevel->addrHalt ); -#endif - /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ int regYield; From d82c6a2cf7394354ed1a17ad26d42b02766bb0d2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 1 Jul 2025 12:43:13 +0000 Subject: [PATCH 20/88] When attempting to optimize "expr AND false" to "false" and "expr IN ()" to "false", take care not to delete aggregate functions in the "expr" as doing so can change the meaning of the query. See [forum:/forumpost/f4878de3e7dd4764|forum thread f4878de3e7]. FossilOrigin-Name: 77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715 --- manifest | 21 ++++++++++----------- manifest.uuid | 2 +- src/expr.c | 2 +- src/parse.y | 19 ++++++++++++++----- test/altertab2.test | 2 +- test/altertab3.test | 12 ++---------- test/parser1.test | 22 ++++++++++++++++++++++ 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 055652fcb7..2ad2bf276f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strive\sto\sskip\sthe\sevaluation\sof\sscalar\ssubqueries\sthat\sare\spart\sof\sa\nlarger\sexpression\sif\sthe\sresult\sfrom\sthe\sscalar\ssubquery\sdoes\snot\schange\sthe\nresult\sof\sthe\soverall\sexpression. -D 2025-06-30T16:41:40.414 +C When\sattempting\sto\soptimize\s"expr\sAND\sfalse"\sto\s"false"\sand\n"expr\sIN\s()"\sto\s"false",\stake\scare\snot\sto\sdelete\saggregate\sfunctions\nin\sthe\s"expr"\sas\sdoing\sso\scan\schange\sthe\smeaning\sof\sthe\squery.\nSee\s[forum:/forumpost/f4878de3e7dd4764|forum\sthread\sf4878de3e7]. +D 2025-07-01T12:43:13.553 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c d726acf67585c14473e354c3d1123a4290e357bdfd389056a05df15b70f66d49 +F src/expr.c 18108701c8b2fcb995143f0217f650d03359f93e2af9e181876436fb71ad4593 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -775,7 +775,7 @@ F src/os_win.c b8d3cfdf2f40e2f9715b7d8df64f3c0c7ee18743a2dd0c4fc70c1d57fa1aadc7 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 F src/pager.c 23c0f17deb892da6b32fef1f465507df7ab5cd01d774288cb43695658a649259 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 -F src/parse.y e426d7323311554c75b0aebc426d0fe3c88d9777ffefed236f343ad9e661dc4c +F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd @@ -898,8 +898,8 @@ F test/altermalloc2.test 17fb3724c4b004c469c27dc4ef181608aa644555fbd3f3236767584 F test/altermalloc3.test 8040e486368403f2fdd6fc3998258b499bd4cc2f3ddbb5f8f874cd436f076e81 F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27 -F test/altertab2.test 4bad0fa9b1ad6e62d07bc2ddb0807fb98ba80ee06d6593db2e514ec1821cae3a -F test/altertab3.test b331ae34e69594e19605e3297805202d6156fcc8f75379dfd972a2e51cae8721 +F test/altertab2.test 0889ba0700cc1cdb7bc7d25975aa61fece34f621de963d0886e2395716b38576 +F test/altertab3.test 471b8898d10bbc6488db9c23dc76811f405de6707d2d342b1b8b6fd1f13cd3c8 F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b @@ -1529,7 +1529,7 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 -F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035ce4b3 +F test/parser1.test 131f4733472252d53d8ed681115257866f55740ab697fa05900d766049348f27 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463 @@ -2208,9 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02 d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f -R 9194e4789912b64a71b73947ca782430 -T +closed d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f +P 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 +R 5553c1556e276f88c28d502c01300a73 U drh -Z 98e7e495521ce39084e96bf3212efc13 +Z e4ebde7f728ace48d0401e6104bc5bfa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2bedf7c1b1..b3e5a34f7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 +77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715 diff --git a/src/expr.c b/src/expr.c index 6cb9c2aa13..9ed0a121ec 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1144,7 +1144,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ return pLeft; }else{ u32 f = pLeft->flags | pRight->flags; - if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse && !IN_RENAME_OBJECT ){ sqlite3ExprDeferredDelete(pParse, pLeft); diff --git a/src/parse.y b/src/parse.y index a5691cad4b..617eb7303b 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1429,12 +1429,21 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ** expr1 IN () ** expr1 NOT IN () ** - ** simplify to constants 0 (false) and 1 (true), respectively, - ** regardless of the value of expr1. + ** simplify to constants 0 (false) and 1 (true), respectively. + ** + ** Except, do not apply this optimization if expr1 contains a function + ** because that function might be an aggregate (we don't know yet whether + ** it is or not) and if it is an aggregate, that could change the meaning + ** of the whole query. */ - sqlite3ExprUnmapAndDelete(pParse, A); - A = sqlite3Expr(pParse->db, TK_STRING, N ? "true" : "false"); - if( A ) sqlite3ExprIdToTrueFalse(A); + Expr *pB = sqlite3Expr(pParse->db, TK_STRING, N ? "true" : "false"); + if( pB ) sqlite3ExprIdToTrueFalse(pB); + if( !ExprHasProperty(A, EP_HasFunc) ){ + sqlite3ExprUnmapAndDelete(pParse, A); + A = pB; + }else{ + A = sqlite3PExpr(pParse, N ? TK_OR : TK_AND, pB, A); + } }else{ Expr *pRHS = Y->a[0].pExpr; if( Y->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && A->op!=TK_VECTOR ){ diff --git a/test/altertab2.test b/test/altertab2.test index 56e42f1a69..f2a1d74c40 100644 --- a/test/altertab2.test +++ b/test/altertab2.test @@ -358,7 +358,7 @@ do_catchsql_test 8.6 { CREATE INDEX i0 ON t0(likelihood(1,2) AND 0); ALTER TABLE t0 RENAME TO t1; SELECT sql FROM sqlite_master WHERE name='i0'; -} {1 {error in index i0: second argument to likelihood() must be a constant between 0.0 and 1.0}} +} {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}} reset_db diff --git a/test/altertab3.test b/test/altertab3.test index 5f5c11b0bb..92060fb41c 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -190,14 +190,14 @@ do_execsql_test 8.1 { } do_execsql_test 8.2.1 { CREATE TABLE t2 (c0); - CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ())); + CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 1.0) IN ())); ALTER TABLE t2 RENAME COLUMN c0 TO c1; } do_execsql_test 8.2.2 { SELECT sql FROM sqlite_master WHERE tbl_name = 't2'; } { {CREATE TABLE t2 (c1)} - {CREATE INDEX i2 ON t2((LIKELIHOOD(c0, 100) IN ()))} + {CREATE INDEX i2 ON t2((LIKELIHOOD(c1, 1.0) IN ()))} } do_test 8.2.3 { sqlite3 db2 test.db @@ -662,14 +662,6 @@ do_execsql_test 27.2 { {CREATE TABLE t1(a, b AS ((WITH w1 (xyz) AS ( SELECT t1.b FROM t1 ) SELECT 123) IN ()))} } -do_execsql_test 27.3 { - CREATE TABLE t0(c0 , c1 AS (CASE TRUE NOT IN () WHEN NULL THEN CASE + 0xa ISNULL WHEN NOT + 0x9 THEN t0.c1 ELSE CURRENT_TIME LIKE CAST (t0.c1 REGEXP '-([1-9]\d*.\d*|0\.\d*[1-9]\d*)'ESCAPE (c1) COLLATE BINARY BETWEEN c1 AND c1 NOT IN (WITH t4 (c0) AS (WITH t3 (c0) AS NOT MATERIALIZED (WITH RECURSIVE t2 (c0) AS (WITH RECURSIVE t1 AS (VALUES (x'717171ff71717171' ) ) SELECT DISTINCT t0.c0 FROM t0 NOT INDEXED WHERE t0.c0 =t0.c0 GROUP BY 0x9 ) SELECT DISTINCT t0.c0 FROM t0 NOT INDEXED WHERE t0.c0 =t0.c1 ) SELECT DISTINCT t0.c0 FROM t0 NOT INDEXED WHERE t0.c0 =t0.c0 GROUP BY typeof(0x9 ) ) SELECT DISTINCT t0.c0 FROM t0 NOT INDEXED WHERE t0.c0 =t0.c0 GROUP BY typeof(typeof(0x9 ) ) ) IN t0 BETWEEN typeof(typeof(typeof(hex(*) FILTER (WHERE + x'5ccd1e68' ) ) ) ) AND 1 >0xa AS BLOB (+4.4E4 , -0xe ) ) END <> c1 IN () END ) VIRTUAL , c35 PRIMARY KEY , c60 , c64 NUMERIC (-6.8 , -0xE ) ) WITHOUT ROWID ; -} {} - -do_execsql_test 27.4 { - ALTER TABLE t0 DROP COLUMN c60; -} {} - #------------------------------------------------------------------------- reset_db do_execsql_test 28.1 { diff --git a/test/parser1.test b/test/parser1.test index ad95b49091..b8d3d8b420 100644 --- a/test/parser1.test +++ b/test/parser1.test @@ -100,4 +100,26 @@ do_execsql_test parser1-3.1 { PRAGMA foreign_key_list(t301); } {0 0 t300 c2 id RESTRICT CASCADE NONE 1 0 t300 c1 id RESTRICT CASCADE NONE} +# 2025-07-01 https://sqlite.org/forum/forumpost/f4878de3e7dd4764 +# Do not allow parse-time optimizations to omit aggregate functions, +# because doing so can change the meaning of the query. +# +unset -nocomplain zero +set zero [expr {0+0}] +do_execsql_test parser1-4.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + SELECT max(x) AND $zero FROM t1; +} 0 +do_execsql_test parser1-4.2 { + SELECT max(x) AND 0 FROM t1; +} 0 +do_execsql_test parser1-4.3 { + SELECT max(x) IN () FROM t1; +} 0 +do_execsql_test parser1-4.4 { + SELECT max(x) NOT IN () FROM t1; +} 1 + + finish_test From 526399b0fde79944b81d6af74d779d0131b70721 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 1 Jul 2025 16:21:47 +0000 Subject: [PATCH 21/88] Avoid an assert() failure in fts5 that may occur when processing corrupt records. FossilOrigin-Name: 8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9 --- ext/fts5/fts5_index.c | 24 ++-- ext/fts5/test/fts5corrupt3.test | 213 ++++++++++++++++++++++++++++++++ manifest | 16 +-- manifest.uuid | 2 +- 4 files changed, 235 insertions(+), 20 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index a912543717..1c3053386d 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2481,18 +2481,20 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = pLast; pIter->iLeafPgno = pgnoLast; - iOff = fts5LeafFirstRowidOff(pLast); - if( iOff>pLast->szLeaf ){ - FTS5_CORRUPT_ITER(p, pIter); - return; - } - iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid); - pIter->iLeafOffset = iOff; + if( p->rc==SQLITE_OK ){ + iOff = fts5LeafFirstRowidOff(pLast); + if( iOff>pLast->szLeaf ){ + FTS5_CORRUPT_ITER(p, pIter); + return; + } + iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid); + pIter->iLeafOffset = iOff; - if( fts5LeafIsTermless(pLast) ){ - pIter->iEndofDoclist = pLast->nn+1; - }else{ - pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); + if( fts5LeafIsTermless(pLast) ){ + pIter->iEndofDoclist = pLast->nn+1; + }else{ + pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); + } } } diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index ea7030a75f..66acf07ee3 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -15909,8 +15909,221 @@ do_catchsql_test 82.4 { SAVEPOINT b; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 83.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-c4a4c5492615bd.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S +| 112: 0e e8 0e 8b 0e 33 0e 0f 00 01 00 00 00 00 00 00 .....3.......... +| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................ +| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb +| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb +| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table +| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf +| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE +| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR +| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI +| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...! +| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs +| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR +| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d +| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG +| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i....... +| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i +| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE +| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid, +| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM +| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t +| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO +| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl +| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data. +| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1 +| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE +| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b +| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T..... +| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA +| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE +| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a +| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3 +| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..) +| page 2 offset 4096 +| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L.... +| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........ +| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........ +| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........ +| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........ +| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 00 4a ef fa cc 0a ad ...~.H....J..... +| 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 09 00 00 00 00 00 ...m.M.+........ +| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................ +| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........ +| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>... +| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh +| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............< +| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n +| 2464: 75 6d 62 03 07 01 04 09 1b 8c 80 80 80 80 0e 03 umb............. +| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the..... +| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe........... +| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num... +| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab......... +| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh.. +| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts......... +| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta.. +| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............ +| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu... +| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of.......... +| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft. +| 2656: 02 02 01 02 69 73 02 06 01 01 03 04 07 18 8c 80 ....is.......... +| 2672: 80 80 22 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t.. +| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w......... +| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n... +| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o.......... +| 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f. +| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i........... +| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the. +| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where..... +| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0....... +| 2816: 06 30 74 61 62 6c 65 03 01 f3 07 1c 8c 80 80 80 .0table......... +| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe +| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of...... +| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........ +| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n.............. +| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux. +| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*. +| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$.......... +| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................ +| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row +| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther.... +| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0...... +| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........ +| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row +| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the...... +| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........ +| 3072: 33 61 72 65 02 02 b3 01 03 62 65 74 02 02 07 08 3are.....bet.... +| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2 +| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and.. +| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<.... +| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro... +| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 0f .............6.. +| 3168: f0 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be.. +| 3184: 03 05 07 1b 88 80 80 80 80 0a 03 00 3c dd 00 00 ............<... +| 3200: 18 c2 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an. +| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8. +| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r.. +| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4. +| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i.... +| 3280: 06 04 06 19 88 80 90 80 80 07 03 00 38 00 00 00 ............8... +| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a..... +| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<... +| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11. +| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0. +| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the..... +| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>..... +| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows +| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<.. +| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between..... +| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............: +| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and....... +| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re.............. +| 3488: 34 00 00 0c 52 02 30 31 02 06 01 01 04 01 01 32 4...R.01.......2 +| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................ +| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<.. +| 3536: 00 16 05 34 74 61 62 6c 01 06 00 f1 05 02 03 65 ...4tabl.......e +| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............< +| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p +| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res............. +| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter..... +| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he.............. +| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre.... +| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............ +| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for.. +| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts........... +| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th.. +| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 74 .....3eac......t +| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta +| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........ +| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in. +| 3776: 06 01 01 02 11 02 70 62 01 02 05 04 09 18 84 80 ......pb........ +| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo. +| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t........... +| 3824: 80 80 08 03 00 3c 0d c0 00 16 12 31 74 01 0a 04 .....<.....1t... +| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea....... +| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i. +| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p......... +| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e... +| 3904: 01 01 66 01 08 02 5b 01 04 04 06 1b 84 80 80 80 ..f...[......... +| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term. +| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he.......... +| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab +| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le.............. +| 3984: 00 30 00 00 00 11 01 f8 30 70 72 65 73 65 6e 74 .0......0present +| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<.. +| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in +| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............: +| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f +| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or.............. +| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................ +| page 3 offset 8192 +| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O......... +| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................ +| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._ +| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&.... +| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................ +| 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 96 0e 00 00 00 ................ +| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ +| 3664: 04 01 10 01 03 34 74 20 07 04 02 4e 01 03 34 1e .....4t ...N..4. +| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th....... +| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w..... +| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n... +| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t.. +| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1. +| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th....... +| 3776: 30 74 08 19 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu.... +| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n........... +| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 .. +| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar +| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t....... +| 3856: 32 69 18 09 04 01 12 01 02 32 60 82 16 08 04 01 2i.......2`..... +| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n.. +| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12 +| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther.... +| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n.. +| 3936: 04 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a +| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t. +| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te. +| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f. +| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t +| 4016: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f +| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i +| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te +| 4064: 0a 07 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p +| 4080: 06 08 04 09 12 01 30 66 74 04 05 04 09 0c 01 02 ......0ft....... +| page 4 offset 12288 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................ +| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................ +| page 5 offset 16384 +| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p +| 4080: 67 83 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 g.z.....version. +| page 6 offset 20480 +| 0: 0d 00 00 00 03 0f f2 00 0f fc 0f 00 00 00 00 00 ................ +| 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ +| end crash-c4a4c5492615bd.db +}]} {} +do_catchsql_test 83.1 { + SELECT * FROM t1('R*R*R*R*R*R*R*R*') WHERE (a,b)<=(current_date,0 BETWEEN 'a'<>11 AND '') ORDER BY rowid DESC; +} {/.*fts5: corruption found/} + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 2ad2bf276f..a0320c0f9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sattempting\sto\soptimize\s"expr\sAND\sfalse"\sto\s"false"\sand\n"expr\sIN\s()"\sto\s"false",\stake\scare\snot\sto\sdelete\saggregate\sfunctions\nin\sthe\s"expr"\sas\sdoing\sso\scan\schange\sthe\smeaning\sof\sthe\squery.\nSee\s[forum:/forumpost/f4878de3e7dd4764|forum\sthread\sf4878de3e7]. -D 2025-07-01T12:43:13.553 +C Avoid\san\sassert()\sfailure\sin\sfts5\sthat\smay\soccur\swhen\sprocessing\scorrupt\srecords. +D 2025-07-01T16:21:47.061 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c 1906bb292b65121aa7d88cabb2a486bea58de75c600271e5011fb86ccc2e427a +F ext/fts5/fts5_index.c fe99dbb3622609e358113cfc8f49aa7a4e6312cba047e7abd0f867b7d6c4c9d5 F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -162,7 +162,7 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b F ext/fts5/test/fts5contentless5.test 38cd0392c730dc7090c550321ce3c24ba4c392bc97308b51a4180e9959dca7b5 F ext/fts5/test/fts5corrupt.test 237fce1c3261bb3a5bec333b0f0dbf5b105ec32627ef14cccbda3cfe13833193 F ext/fts5/test/fts5corrupt2.test 4a03a158c2cb617c9f76d26b35c1ef2534124bc0bbddcea38dfd5b170ebea27b -F ext/fts5/test/fts5corrupt3.test e4852b2472dd25556431fd48fe88e4d0c8cf3e18e010c5ea308345e1cdf97bd5 +F ext/fts5/test/fts5corrupt3.test 03a6118a8fe5a7c217c28c92b6b25ba04643640a4ac0a1d2b8d10de8191dc5f4 F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a0ff2f26e0c2e222abe F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296 -R 5553c1556e276f88c28d502c01300a73 -U drh -Z e4ebde7f728ace48d0401e6104bc5bfa +P 77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715 +R ee4381fcf8913d6297e7cb466e0d9225 +U dan +Z 34708df4029e1ab6d72f50ff836e4341 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b3e5a34f7d..46ca21df06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715 +8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9 From 5e71497404b8a03d25b324b14dafa0496dc665c7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 1 Jul 2025 17:36:55 +0000 Subject: [PATCH 22/88] Cache and reuse virtual table cursors in the bytecode engine. FossilOrigin-Name: 2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 9 ++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a0320c0f9e..244c6b5bf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sassert()\sfailure\sin\sfts5\sthat\smay\soccur\swhen\sprocessing\scorrupt\srecords. -D 2025-07-01T16:21:47.061 +C Cache\sand\sreuse\svirtual\stable\scursors\sin\sthe\sbytecode\sengine. +D 2025-07-01T17:36:55.244 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -852,7 +852,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 -F src/vdbe.c 7e29623ca387880b8893e69135a0ff240c3dcaf0710f7a46a5f95b062cf93883 +F src/vdbe.c d2c13c0001f5ec40ec1f010a7f9badcff3ce09bbd7a78528682ad49d8566df54 F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715 -R ee4381fcf8913d6297e7cb466e0d9225 -U dan -Z 34708df4029e1ab6d72f50ff836e4341 +P 8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9 +R a0d75f1fb250395135fba17ef3bc4dc0 +U drh +Z 8fcf407f538f5f9f65ff8d90a37c91a0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 46ca21df06..cec73c0740 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9 +2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514 diff --git a/src/vdbe.c b/src/vdbe.c index 9e696d0c37..0020b52bf0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -8269,7 +8269,14 @@ case OP_VOpen: { /* ncycle */ const sqlite3_module *pModule; assert( p->bIsReader ); - pCur = 0; + pCur = p->apCsr[pOp->p1]; + if( pCur!=0 + && ALWAYS( pCur->eCurType==CURTYPE_VTAB ) + && ALWAYS( pCur->uc.pVCur->pVtab==pOp->p4.pVtab->pVtab ) + ){ + /* This opcode is a no-op if the cursor is already open */ + break; + } pVCur = 0; pVtab = pOp->p4.pVtab->pVtab; if( pVtab==0 || NEVER(pVtab->pModule==0) ){ From 46bfcc1a2171a4c6d1eec034d2f96181f987801d Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 1 Jul 2025 20:32:45 +0000 Subject: [PATCH 23/88] Improved byte-code comments for the short-circuit optimization of [0083d5169a46104a], to aid in debugging. FossilOrigin-Name: 113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 244c6b5bf3..e3075f56a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cache\sand\sreuse\svirtual\stable\scursors\sin\sthe\sbytecode\sengine. -D 2025-07-01T17:36:55.244 +C Improved\sbyte-code\scomments\sfor\sthe\sshort-circuit\soptimization\sof\n[0083d5169a46104a],\sto\said\sin\sdebugging. +D 2025-07-01T20:32:45.457 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 18108701c8b2fcb995143f0217f650d03359f93e2af9e181876436fb71ad4593 +F src/expr.c e3d3b6e60b86fac772bd4d4f0c6fe1d01bef3851754a9c1215d2f8574296cbd2 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9 -R a0d75f1fb250395135fba17ef3bc4dc0 +P 2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514 +R 514121d017fa6dee51263403393090a8 U drh -Z 8fcf407f538f5f9f65ff8d90a37c91a0 +Z 688f46cf0060385046556b19c2a8341b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cec73c0740..db1994fb89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514 +113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea diff --git a/src/expr.c b/src/expr.c index 9ed0a121ec..c8dfd3af33 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2424,7 +2424,9 @@ static int exprComputeOperands( */ if( exprEvalRhsFirst(pExpr) && sqlite3ExprCanBeNull(pExpr->pRight) ){ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); + VdbeComment((v, "skip left operand")); + VdbeCoverage(v); }else{ addrIsNull = 0; } @@ -2439,7 +2441,9 @@ static int exprComputeOperands( if( ExprHasProperty(pExpr->pRight, EP_Subquery) && sqlite3ExprCanBeNull(pExpr->pLeft) ){ - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); VdbeCoverage(v); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); + VdbeComment((v, "skip right operand")); + VdbeCoverage(v); } r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); } @@ -5112,6 +5116,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeJumpHere(v, addrIsNull); sqlite3VdbeAddOp2(v, OP_Null, 0, target); + VdbeComment((v, "short-circut value")); } break; } From 2427ce16d9a340ff9790f62db1371f5ef83f8afe Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 1 Jul 2025 23:17:36 +0000 Subject: [PATCH 24/88] Improved comments on bytecode used to implement aggregate queries, to aid in debugging. FossilOrigin-Name: a1a8b85cdba64a17dcdcd4e6b42b872957cec2dc05b0ac34dfcd82f59344034b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e3075f56a4..d9ed7e38a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sbyte-code\scomments\sfor\sthe\sshort-circuit\soptimization\sof\n[0083d5169a46104a],\sto\said\sin\sdebugging. -D 2025-07-01T20:32:45.457 +C Improved\scomments\son\sbytecode\sused\sto\simplement\saggregate\squeries,\sto\said\nin\sdebugging. +D 2025-07-01T23:17:36.521 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 +F src/select.c a59865dac1ab591f253ae29f12bed7de848692064f2bd752f97271332fa13430 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514 -R 514121d017fa6dee51263403393090a8 +P 113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea +R 84ef00e957455655fffca42a9ae3db46 U drh -Z 688f46cf0060385046556b19c2a8341b +Z e67f7b514a444aef3e345291ef72798f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db1994fb89..1b87282d84 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea +a1a8b85cdba64a17dcdcd4e6b42b872957cec2dc05b0ac34dfcd82f59344034b diff --git a/src/select.c b/src/select.c index 6c0e7c92d4..2723d069b2 100644 --- a/src/select.c +++ b/src/select.c @@ -8537,12 +8537,12 @@ int sqlite3Select( ** for the next GROUP BY batch. */ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); - VdbeComment((v, "output one row")); + VdbeComment((v, "output one row of %d", p->selId)); sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - VdbeComment((v, "reset accumulator")); + VdbeComment((v, "reset accumulator %d", p->selId)); /* Update the aggregate accumulators based on the content of ** the current row @@ -8550,7 +8550,7 @@ int sqlite3Select( sqlite3VdbeJumpHere(v, addr1); updateAccumulator(pParse, iUseFlag, pAggInfo, eDist); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); - VdbeComment((v, "indicate data in accumulator")); + VdbeComment((v, "indicate data in accumulator %d", p->selId)); /* End of the loop */ @@ -8567,7 +8567,7 @@ int sqlite3Select( /* Output the final row of result */ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); - VdbeComment((v, "output final row")); + VdbeComment((v, "output final row of %d", p->selId)); /* Jump over the subroutines */ @@ -8588,7 +8588,7 @@ int sqlite3Select( addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); - VdbeComment((v, "Groupby result generator entry point")); + VdbeComment((v, "Groupby result generator entry point %d", p->selId)); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, pAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); @@ -8596,14 +8596,14 @@ int sqlite3Select( &sDistinct, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - VdbeComment((v, "end groupby result generator")); + VdbeComment((v, "end groupby result generator %d", p->selId)); /* Generate a subroutine that will reset the group-by accumulator */ sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, pAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); - VdbeComment((v, "indicate accumulator empty")); + VdbeComment((v, "indicate accumulator %d empty", p->selId)); sqlite3VdbeAddOp1(v, OP_Return, regReset); if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ From caf047365280f9e92e2bca250d79aeb20e78fb7e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 2 Jul 2025 02:03:43 +0000 Subject: [PATCH 25/88] Ensure that Expr.op2 values for TK_AGG_FUNCTION nodes are adjusted when query flattening. FossilOrigin-Name: d27d34fb746280e7e81335db4e195914b15403ef0da7b2955550553dd78fbe9a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d9ed7e38a8..14cbb1d475 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sbytecode\sused\sto\simplement\saggregate\squeries,\sto\said\nin\sdebugging. -D 2025-07-01T23:17:36.521 +C Ensure\sthat\sExpr.op2\svalues\sfor\sTK_AGG_FUNCTION\snodes\sare\sadjusted\swhen\nquery\sflattening. +D 2025-07-02T02:03:43.743 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c a59865dac1ab591f253ae29f12bed7de848692064f2bd752f97271332fa13430 +F src/select.c 0258c6c36372e64e3ecc5f9ed4ebb598c0688e112e28f9c9c0f9b61dc6500609 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea -R 84ef00e957455655fffca42a9ae3db46 +P a1a8b85cdba64a17dcdcd4e6b42b872957cec2dc05b0ac34dfcd82f59344034b +R ebff75d00bdb4eab7ae7336179a6a5fb U drh -Z e67f7b514a444aef3e345291ef72798f +Z b88c62926e04b0e9a5b2b8bb036a8c63 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1b87282d84..f417453c51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1a8b85cdba64a17dcdcd4e6b42b872957cec2dc05b0ac34dfcd82f59344034b +d27d34fb746280e7e81335db4e195914b15403ef0da7b2955550553dd78fbe9a diff --git a/src/select.c b/src/select.c index 2723d069b2..95b2925e36 100644 --- a/src/select.c +++ b/src/select.c @@ -3872,6 +3872,7 @@ typedef struct SubstContext { int iTable; /* Replace references to this table */ int iNewTable; /* New table number */ int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + int nSelDepth; /* Depth of sub-query recursion. Top==1 */ ExprList *pEList; /* Replacement expressions */ ExprList *pCList; /* Collation sequences for replacement expr */ } SubstContext; @@ -3979,6 +3980,9 @@ static Expr *substExpr( if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ pExpr->iTable = pSubst->iNewTable; } + if( pExpr->op==TK_AGG_FUNCTION && pExpr->op2>=pSubst->nSelDepth ){ + pExpr->op2--; + } pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); pExpr->pRight = substExpr(pSubst, pExpr->pRight); if( ExprUseXSelect(pExpr) ){ @@ -4016,6 +4020,7 @@ static void substSelect( SrcItem *pItem; int i; if( !p ) return; + pSubst->nSelDepth++; do{ substExprList(pSubst, p->pEList); substExprList(pSubst, p->pGroupBy); @@ -4033,6 +4038,7 @@ static void substSelect( } } }while( doPrior && (p = p->pPrior)!=0 ); + pSubst->nSelDepth--; } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ @@ -4774,6 +4780,7 @@ static int flattenSubquery( x.iTable = iParent; x.iNewTable = iNewParent; x.isOuterJoin = isOuterJoin; + x.nSelDepth = 0; x.pEList = pSub->pEList; x.pCList = findLeftmostExprlist(pSub); substSelect(&x, pParent, 0); From 216676664d6ac56d83adc0f8214d032f6d6da1bf Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 2 Jul 2025 13:19:24 +0000 Subject: [PATCH 26/88] If the LHS for an EXCEPT or INTERSECT operator is empty, skip over the computation of the RHS. FossilOrigin-Name: 13f096ae8a850a05d4a8684561066f11693ee66289e6568c44ef32822cca06f6 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/btree.c | 17 +++++++++++++++++ src/btree.h | 1 + src/select.c | 8 ++++++++ src/vdbe.c | 25 +++++++++++++++++++++++++ 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index be3c7806be..e5a30cdedc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sbytecode\sfor\sjoins\ssuch\sthat\sit\sexits\searlier\sif\sit\sdetermines\nthat\sno\soutput\sis\spossible. -D 2025-07-02T11:47:54.123 +C If\sthe\sLHS\sfor\san\sEXCEPT\sor\sINTERSECT\soperator\sis\sempty,\sskip\sover\sthe\ncomputation\sof\sthe\sRHS. +D 2025-07-02T13:19:24.955 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,8 +726,8 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 81fb44041929a605e293185bd4091cb24c468a108afe8ba1d93a81a8823de47f -F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 +F src/btree.c 20c243f1531c806b112dc5f2cd8e2e81618284d8d04897755338ca40e7eaf29b +F src/btree.h 53a4f92a4c79470c18f88e0cf42755e2a74833044b0b4610aa328083379c7767 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 0258c6c36372e64e3ecc5f9ed4ebb598c0688e112e28f9c9c0f9b61dc6500609 +F src/select.c 68b43b6a2de2440fb05aa4745e164fc2347d739b990b63ba494a7b18fc55b200 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -852,7 +852,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 -F src/vdbe.c d2c13c0001f5ec40ec1f010a7f9badcff3ce09bbd7a78528682ad49d8566df54 +F src/vdbe.c 5fb85ec6f2f6cdfb8efac6c4dd4f7eed388dfb5041bf71e1c55f213eb0ed5421 F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d27d34fb746280e7e81335db4e195914b15403ef0da7b2955550553dd78fbe9a 63306e447efb3ac17e789a331ed3bb65459eb8b79d66e9c185ba3bd852f34ce3 -R b92b209ccf559f2de96150026272807a +P 2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 +R c6049700927657d653d5f08e5f12e785 +T *branch * empty-table-optimizations +T *sym-empty-table-optimizations * +T -sym-trunk * U drh -Z 48380f5a742f367bd4ced6b10cb684be +Z de7126eae59d141656689f55b14fd34e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ed9a080860..3c576ca032 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 +13f096ae8a850a05d4a8684561066f11693ee66289e6568c44ef32822cca06f6 diff --git a/src/btree.c b/src/btree.c index 1806a914a6..1dc7b851f2 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5667,6 +5667,23 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ return rc; } +/* Return true if the BTree pointed to by cursor pCur contains zero +** rows of content. Return false if the table contains content or if +** if there is some kind of error. This routine is used as an optimization. +** Returning false (a false negative) will always result in a correct +** answer, though perhaps more slowly. But a false positive (an incorrect +** return of true) can yield an incorrect answer. +*/ +int sqlite3BtreeIsEmpty(BtCursor *pCur){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + if( pCur->eState==CURSOR_VALID ) return 0; + rc = moveToRoot(pCur); + return rc==SQLITE_EMPTY; +} + #ifdef SQLITE_DEBUG /* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that ** this flags are true for a consistent database. diff --git a/src/btree.h b/src/btree.h index 241261dc6a..23fb127911 100644 --- a/src/btree.h +++ b/src/btree.h @@ -317,6 +317,7 @@ struct BtreePayload { int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, int flags, int seekResult); int sqlite3BtreeFirst(BtCursor*, int *pRes); +int sqlite3BtreeIsEmpty(BtCursor *pCur); int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int flags); int sqlite3BtreeEof(BtCursor*); diff --git a/src/select.c b/src/select.c index 95b2925e36..e2dd24b3ef 100644 --- a/src/select.c +++ b/src/select.c @@ -3036,7 +3036,9 @@ static int multiSelect( int priorOp; /* The SRT_ operation to apply to prior selects */ Expr *pLimit; /* Saved values of p->nLimit */ int addr; + int emptyBypass = 0; /* IfEmpty opcode to bypass RHS */ SelectDest uniondest; + testcase( p->op==TK_EXCEPT ); testcase( p->op==TK_UNION ); @@ -3075,6 +3077,8 @@ static int multiSelect( */ if( p->op==TK_EXCEPT ){ op = SRT_Except; + emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab); + VdbeCoverage(v); }else{ assert( p->op==TK_UNION ); op = SRT_Union; @@ -3117,6 +3121,7 @@ static int multiSelect( sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); + if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); } break; @@ -3128,6 +3133,7 @@ static int multiSelect( int addr; SelectDest intersectdest; int r1; + int emptyBypass; /* INTERSECT is different from the others since it requires ** two temporary tables. Hence it has its own case. Begin @@ -3151,6 +3157,7 @@ static int multiSelect( if( rc ){ goto multi_select_end; } + emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v); /* Code the current SELECT into temporary table "tab2" */ @@ -3194,6 +3201,7 @@ static int multiSelect( sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeJumpHere(v, emptyBypass); sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); break; } diff --git a/src/vdbe.c b/src/vdbe.c index 0020b52bf0..895ef109c2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6398,6 +6398,31 @@ case OP_Rewind: { /* jump0, ncycle */ break; } +/* Opcode: IfEmpty P1 P2 * * * +** Synopsis: if( empty(P1) ) goto P2 +** +** Check to see if the b-tree table that cursor P1 references is empty +** and jump to P2 if it is. +*/ +case OP_IfEmpty: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p2>=0 && pOp->p2nOp ); + + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + res = sqlite3BtreeIsEmpty(pCrsr); + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + /* Opcode: Next P1 P2 P3 * P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its From 33f327370541a8b66a355f588f9198b9241660a9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 2 Jul 2025 14:53:48 +0000 Subject: [PATCH 27/88] Early exit if one of the inner loops of a 3-way or larger join is an empty table. FossilOrigin-Name: eaad6ac707a5960d9518d4049b7b1759e7512727ce87be3c402408144bda0a97 --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/btree.c | 25 ++++++++++++++++--------- src/btree.h | 2 +- src/select.c | 2 +- src/vdbe.c | 3 ++- src/where.c | 6 ++++++ 7 files changed, 37 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index e5a30cdedc..e505968bd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\sLHS\sfor\san\sEXCEPT\sor\sINTERSECT\soperator\sis\sempty,\sskip\sover\sthe\ncomputation\sof\sthe\sRHS. -D 2025-07-02T13:19:24.955 +C Early\sexit\sif\sone\sof\sthe\sinner\sloops\sof\sa\s3-way\sor\slarger\sjoin\sis\san\nempty\stable. +D 2025-07-02T14:53:48.889 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,8 +726,8 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 20c243f1531c806b112dc5f2cd8e2e81618284d8d04897755338ca40e7eaf29b -F src/btree.h 53a4f92a4c79470c18f88e0cf42755e2a74833044b0b4610aa328083379c7767 +F src/btree.c 96fcbe6db6af625e5a14c34d8f13688d1d22c5f924a436b12395aaf09ec65944 +F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 68b43b6a2de2440fb05aa4745e164fc2347d739b990b63ba494a7b18fc55b200 +F src/select.c 0d30f9718594b6c208373c28c174432dda5c555bd18a5a3d37fd623fdb64aafb F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -852,7 +852,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 -F src/vdbe.c 5fb85ec6f2f6cdfb8efac6c4dd4f7eed388dfb5041bf71e1c55f213eb0ed5421 +F src/vdbe.c e505b8b879a330e8dafbe3ed9582eae2fc671b44a64748d1b58c07e4e0f527da F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df @@ -867,7 +867,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c f58d41d0923eeb21cab8e4fc87a0b36c0724ff4f279ce95ab2731b4696b8e75a +F src/where.c e03e764dcbc205d40b01a033b744c583b090f29df56d2efaa1a12a79d8a1b053 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 -R c6049700927657d653d5f08e5f12e785 -T *branch * empty-table-optimizations -T *sym-empty-table-optimizations * -T -sym-trunk * +P 13f096ae8a850a05d4a8684561066f11693ee66289e6568c44ef32822cca06f6 +R 004cef124bcae73b595e9860d518af27 U drh -Z de7126eae59d141656689f55b14fd34e +Z 93bde8048b1cba4fc1e568dc39724e75 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3c576ca032..3c9b3a2f20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13f096ae8a850a05d4a8684561066f11693ee66289e6568c44ef32822cca06f6 +eaad6ac707a5960d9518d4049b7b1759e7512727ce87be3c402408144bda0a97 diff --git a/src/btree.c b/src/btree.c index 1dc7b851f2..cef65846a3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5667,21 +5667,28 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ return rc; } -/* Return true if the BTree pointed to by cursor pCur contains zero -** rows of content. Return false if the table contains content or if -** if there is some kind of error. This routine is used as an optimization. -** Returning false (a false negative) will always result in a correct -** answer, though perhaps more slowly. But a false positive (an incorrect -** return of true) can yield an incorrect answer. +/* Set *pRes to 1 (true) if the BTree pointed to by cursor pCur contains zero +** rows of content. Set *pRes to 0 (false) if the table contains content. +** Return SQLITE_OK on success or some error code (ex: SQLITE_NOMEM) if +** something goes wrong. */ -int sqlite3BtreeIsEmpty(BtCursor *pCur){ +int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){ int rc; assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - if( pCur->eState==CURSOR_VALID ) return 0; + if( pCur->eState==CURSOR_VALID ){ + *pRes = 0; + return SQLITE_OK; + } rc = moveToRoot(pCur); - return rc==SQLITE_EMPTY; + if( rc==SQLITE_EMPTY ){ + *pRes = 1; + rc = SQLITE_OK; + }else{ + *pRes = 0; + } + return rc; } #ifdef SQLITE_DEBUG diff --git a/src/btree.h b/src/btree.h index 23fb127911..96f4c4c607 100644 --- a/src/btree.h +++ b/src/btree.h @@ -317,7 +317,7 @@ struct BtreePayload { int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, int flags, int seekResult); int sqlite3BtreeFirst(BtCursor*, int *pRes); -int sqlite3BtreeIsEmpty(BtCursor *pCur); +int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes); int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int flags); int sqlite3BtreeEof(BtCursor*); diff --git a/src/select.c b/src/select.c index e2dd24b3ef..017fde9013 100644 --- a/src/select.c +++ b/src/select.c @@ -3099,6 +3099,7 @@ static int multiSelect( if( p->op==TK_UNION ){ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); } + if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->iLimit = 0; @@ -3121,7 +3122,6 @@ static int multiSelect( sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); - if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); } break; diff --git a/src/vdbe.c b/src/vdbe.c index 895ef109c2..9e456a1cd5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6417,7 +6417,8 @@ case OP_IfEmpty: { /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); pCrsr = pC->uc.pCursor; assert( pCrsr ); - res = sqlite3BtreeIsEmpty(pCrsr); + rc = sqlite3BtreeIsEmpty(pCrsr, &res); + if( rc ) goto abort_due_to_error; VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; diff --git a/src/where.c b/src/where.c index ddf3f74996..28af499989 100644 --- a/src/where.c +++ b/src/where.c @@ -7134,6 +7134,12 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, (const u8*)&pTabItem->colUsed, P4_INT64); #endif + if( ii>=2 + && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 + && pLevel->addrHalt==pWInfo->a[0].addrHalt + ){ + sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pLevel->addrHalt); + } }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } From eb27359e5e6e0258947ef85124229ca632d838af Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 2 Jul 2025 17:43:59 +0000 Subject: [PATCH 28/88] Fix VDBE coverage FossilOrigin-Name: ff593a16d61cc5c588d1737deb822abb90b1759475a4cabfcf608978b1191487 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- src/where.c | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e505968bd6..e466a39061 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Early\sexit\sif\sone\sof\sthe\sinner\sloops\sof\sa\s3-way\sor\slarger\sjoin\sis\san\nempty\stable. -D 2025-07-02T14:53:48.889 +C Fix\sVDBE\scoverage +D 2025-07-02T17:43:59.873 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 0d30f9718594b6c208373c28c174432dda5c555bd18a5a3d37fd623fdb64aafb +F src/select.c fc2fe502971df1205a3231d3b3c8b0cc9ed4779cecbd060952c9558e22b6b02d F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -867,7 +867,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c e03e764dcbc205d40b01a033b744c583b090f29df56d2efaa1a12a79d8a1b053 +F src/where.c b11e56a24d01ae9b293f702c9de6dd16ced6b886be0d7cccb8bdeb62c8d92362 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 13f096ae8a850a05d4a8684561066f11693ee66289e6568c44ef32822cca06f6 -R 004cef124bcae73b595e9860d518af27 +P eaad6ac707a5960d9518d4049b7b1759e7512727ce87be3c402408144bda0a97 +R 19ae64c3af637e68252816fb2a35fc7d U drh -Z 93bde8048b1cba4fc1e568dc39724e75 +Z 04fda6f3c6a7b8123cd1480694a7568d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3c9b3a2f20..faaf6064f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eaad6ac707a5960d9518d4049b7b1759e7512727ce87be3c402408144bda0a97 +ff593a16d61cc5c588d1737deb822abb90b1759475a4cabfcf608978b1191487 diff --git a/src/select.c b/src/select.c index 017fde9013..d35103cddf 100644 --- a/src/select.c +++ b/src/select.c @@ -3189,7 +3189,7 @@ static int multiSelect( iBreak = sqlite3VdbeMakeLabel(pParse); iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Rewind, tab1); r1 = sqlite3GetTempReg(pParse); iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); diff --git a/src/where.c b/src/where.c index 28af499989..4a0c3988cb 100644 --- a/src/where.c +++ b/src/where.c @@ -7139,6 +7139,7 @@ WhereInfo *sqlite3WhereBegin( && pLevel->addrHalt==pWInfo->a[0].addrHalt ){ sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pLevel->addrHalt); + VdbeCoverage(v); } }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); From debc8f7bb7b62fb865251e140510d853b138b88b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Jul 2025 00:17:27 +0000 Subject: [PATCH 29/88] Minor tweaks to the exists-to-join optimization. FossilOrigin-Name: 9cb600ad576c68647ed943a0773019312c5f01c9c1ca9ff0bf1214b03a531b48 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 8 ++++++-- src/select.c | 2 +- src/shell.c.in | 1 + 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 8caec32f55..7774b2396b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sthe\sexists-to-join\soptimization\sthat\shas\sbeen\smodified\nto\srelax\sthe\srequirement\sof\shaving\san\sindexed\sjoin\sconstraint. -D 2025-07-02T20:46:02.299 +C Minor\stweaks\sto\sthe\sexists-to-join\soptimization. +D 2025-07-03T00:17:27.518 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -783,10 +783,10 @@ F src/pragma.c 30b535d0a66348df844ee36f890617b4cf45e9a22dcbc47ec3ca92909c50aaf1 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 9583e6eb8066400d377db9b130ebf46d461b59fccf1d018a5010d55b9bea217c +F src/resolve.c 5b14cad58bc21341fbaea76d7e781187559627a461745ece00c2655ba7c083ec F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 30d7e450179a123c2a4dd9000592da196f5a6766688773cb11b921294afa11bf -F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 +F src/select.c d956136defc62a9b11d61b18c5c3559231055c0ea32f6b11d13c740a7467aeb0 +F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ff593a16d61cc5c588d1737deb822abb90b1759475a4cabfcf608978b1191487 9084a4c8726a2c7ba1c381886e29c7b86121d531282be0d63d5988d84f6f448d -R f60eba1acfa64dc97c08e5ab9333e9b4 +P 1c1aef2b7feae29066d0330699ab634ef41f5b60cdcd479a60cb1a5409553138 +R 690f317201b055306be94336494e9b81 U drh -Z 4c3d6c95c910f93bc2abb148fe548800 +Z 608e6ffa5985c7c132d45ebfd75d87f4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 70909c9c3e..7b5464b41b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c1aef2b7feae29066d0330699ab634ef41f5b60cdcd479a60cb1a5409553138 +9cb600ad576c68647ed943a0773019312c5f01c9c1ca9ff0bf1214b03a531b48 diff --git a/src/resolve.c b/src/resolve.c index 562ca5e008..bbd1021e0b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1358,11 +1358,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ return WRC_Prune; } #ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + assert( ExprUseXSelect(pExpr) ); + pParse->bHasExists = 1; + /* no break */ deliberate_fall_through case TK_SELECT: - case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); #endif case TK_IN: { testcase( pExpr->op==TK_IN ); + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); if( ExprUseXSelect(pExpr) ){ int nRef = pNC->nRef; testcase( pNC->ncFlags & NC_IsCheck ); @@ -1379,7 +1384,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); pExpr->x.pSelect->selFlags |= SF_Correlated; - if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1; } pNC->ncFlags |= NC_Subquery; } diff --git a/src/select.c b/src/select.c index fd99dc91fe..9c79f6c67c 100644 --- a/src/select.c +++ b/src/select.c @@ -7437,7 +7437,7 @@ static SQLITE_NOINLINE void existsToJoin( else if( pWhere->op==TK_EXISTS ){ Select *pSub = pWhere->x.pSelect; if( pSub->pSrc->nSrc==1 - && (pSub->selFlags & (SF_Aggregate|SF_Correlated))==SF_Correlated + && (pSub->selFlags & SF_Aggregate)==0 && pSub->pWhere ){ memset(pWhere, 0, sizeof(*pWhere)); diff --git a/src/shell.c.in b/src/shell.c.in index 33dd30697d..5cda6a1a1b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -11710,6 +11710,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { 0x08000000, 1, "OnePass" }, { 0x10000000, 1, "OrderBySubq" }, { 0x20000000, 1, "StarQuery" }, + { 0x40000000, 1, "ExistsToJoin" }, { 0xffffffff, 0, "All" }, }; unsigned int curOpt; From bfb4993364a2f20929ae306156d0030269ca5cb4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Jul 2025 11:52:17 +0000 Subject: [PATCH 30/88] Fix an uninitialized variable added yesterday by [d27d34fb746280e7]. This problem was discovered overnight by [https://github.com/google/oss-fuzz|OSSFuzz]. FossilOrigin-Name: 6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index be3c7806be..bf56baa156 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sbytecode\sfor\sjoins\ssuch\sthat\sit\sexits\searlier\sif\sit\sdetermines\nthat\sno\soutput\sis\spossible. -D 2025-07-02T11:47:54.123 +C Fix\san\suninitialized\svariable\sadded\syesterday\sby\s[d27d34fb746280e7].\nThis\sproblem\swas\sdiscovered\sovernight\sby\s\n[https://github.com/google/oss-fuzz|OSSFuzz]. +D 2025-07-03T11:52:17.583 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 0258c6c36372e64e3ecc5f9ed4ebb598c0688e112e28f9c9c0f9b61dc6500609 +F src/select.c 700e98061a61bf8e8b0f2707ed22ffc44c7a7b660dbf7c569430e04d2f95d8a5 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d27d34fb746280e7e81335db4e195914b15403ef0da7b2955550553dd78fbe9a 63306e447efb3ac17e789a331ed3bb65459eb8b79d66e9c185ba3bd852f34ce3 -R b92b209ccf559f2de96150026272807a +P 2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 +R 1edf105752f8a1297dddf11638994a45 U drh -Z 48380f5a742f367bd4ced6b10cb684be +Z 4ca8b7187871a2cc09690de9bf418693 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ed9a080860..3cd0cbc0ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 +6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114 diff --git a/src/select.c b/src/select.c index 95b2925e36..1e54747fcb 100644 --- a/src/select.c +++ b/src/select.c @@ -5366,6 +5366,7 @@ static int pushDownWhereTerms( x.iTable = pSrc->iCursor; x.iNewTable = pSrc->iCursor; x.isOuterJoin = 0; + x.nSelDepth = 0; x.pEList = pSubq->pEList; x.pCList = findLeftmostExprlist(pSubq); pNew = substExpr(&x, pNew); From 1ff6f19d8b8199f49cd67171ae03873766d12c3f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Jul 2025 14:10:03 +0000 Subject: [PATCH 31/88] Enhancements to the xBestIndex output from the ext/misc/vtablog.c extension. FossilOrigin-Name: 8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de --- ext/misc/vtablog.c | 58 +++++++++++++++++++++++++++++++++++++++++++--- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c index e8f084e1b2..8e4631595d 100644 --- a/ext/misc/vtablog.c +++ b/ext/misc/vtablog.c @@ -435,6 +435,39 @@ static int vtablogFilter( return SQLITE_OK; } +/* +** Return an sqlite3_index_info operator name in static space. +** The name is possibly overwritten on subsequent calls. +*/ +static char *vtablogOpName(unsigned char op){ + static char zUnknown[30]; + char *zOut; + switch( op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: zOut = "EQ"; break; + case SQLITE_INDEX_CONSTRAINT_GT: zOut = "GT"; break; + case SQLITE_INDEX_CONSTRAINT_LE: zOut = "LE"; break; + case SQLITE_INDEX_CONSTRAINT_LT: zOut = "LT"; break; + case SQLITE_INDEX_CONSTRAINT_GE: zOut = "GE"; break; + case SQLITE_INDEX_CONSTRAINT_MATCH: zOut = "MATCH"; break; + case SQLITE_INDEX_CONSTRAINT_LIKE: zOut = "LIKE"; break; + case SQLITE_INDEX_CONSTRAINT_GLOB: zOut = "GLOB"; break; + case SQLITE_INDEX_CONSTRAINT_REGEXP: zOut = "REGEXP"; break; + case SQLITE_INDEX_CONSTRAINT_NE: zOut = "NE"; break; + case SQLITE_INDEX_CONSTRAINT_ISNOT: zOut = "ISNOT"; break; + case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: zOut = "ISNOTNULL"; break; + case SQLITE_INDEX_CONSTRAINT_ISNULL: zOut = "ISNULL"; break; + case SQLITE_INDEX_CONSTRAINT_IS: zOut = "IS"; break; + case SQLITE_INDEX_CONSTRAINT_LIMIT: zOut = "LIMIT"; break; + case SQLITE_INDEX_CONSTRAINT_OFFSET: zOut = "OFFSET"; break; + case SQLITE_INDEX_CONSTRAINT_FUNCTION: zOut = "FUNCTION"; break; + default: + sqlite3_snprintf(sizeof(zUnknown),zUnknown,"%d",op); + zOut = zUnknown; + break; + } + return zOut; +} + /* ** SQLite will invoke this method one or more times while planning a query ** that uses the vtablog virtual table. This routine needs to create @@ -451,14 +484,33 @@ static int vtablogBestIndex( printf(" colUsed: 0x%016llx\n", p->colUsed); printf(" nConstraint: %d\n", p->nConstraint); for(i=0; inConstraint; i++){ + sqlite3_value *pVal = 0; + int rc; + char zRhs[50]; + rc = sqlite3_vtab_rhs_value(p, i, &pVal); + if( rc==SQLITE_OK ){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: sqlite3_snprintf(50,zRhs,"NULL"); break; + case SQLITE_INTEGER: sqlite3_snprintf(50,zRhs,"%lld", + sqlite3_value_int64(pVal)); break; + case SQLITE_FLOAT: sqlite3_snprintf(50,zRhs,"%g", + sqlite3_value_double(pVal)); break; + case SQLITE_TEXT: sqlite3_snprintf(50,zRhs,"TEXT"); break; + default: sqlite3_snprintf(50,zRhs,"BLOB"); break; + } + }else{ + sqlite3_snprintf(50,zRhs,"N/A"); + } printf( - " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", + " constraint[%d]: col=%d termid=%d op=%s usabled=%d coll=%s rhs=%s\n", i, p->aConstraint[i].iColumn, p->aConstraint[i].iTermOffset, - p->aConstraint[i].op, + vtablogOpName(p->aConstraint[i].op), p->aConstraint[i].usable, - sqlite3_vtab_collation(p,i)); + sqlite3_vtab_collation(p,i), + zRhs + ); } printf(" nOrderBy: %d\n", p->nOrderBy); for(i=0; inOrderBy; i++){ diff --git a/manifest b/manifest index bf56baa156..c3d677cc50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\suninitialized\svariable\sadded\syesterday\sby\s[d27d34fb746280e7].\nThis\sproblem\swas\sdiscovered\sovernight\sby\s\n[https://github.com/google/oss-fuzz|OSSFuzz]. -D 2025-07-03T11:52:17.583 +C Enhancements\sto\sthe\sxBestIndex\soutput\sfrom\sthe\sext/misc/vtablog.c\nextension. +D 2025-07-03T14:10:03.834 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -456,7 +456,7 @@ F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505 F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c 0b23c0a69a2b63dc0ef0af44f9c1fc977300c480a1f7a9814500369d8211f56e F ext/misc/vfstrace.c 0e4b8b17ac0675ea90f6d168d8214687e06ca3efbc0060aad4814994d82b41fb -F ext/misc/vtablog.c a197addbbd1e267a5476274b74953e1b6f050e28516f0a5fe7d6382753165ee6 +F ext/misc/vtablog.c ee27ec6595751db0ce4b8c2a2b72f6eca4d018d9d33e139dbd477e8d173f7b0e F ext/misc/vtshim.c e5bce24ab8c532f4fdc600148718fe1802cb6ed57417f1c1032d8961f72b0e8f F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367 -R 1edf105752f8a1297dddf11638994a45 +P 6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114 +R 50c4d2dc6029c61dab20b65ad02b720b U drh -Z 4ca8b7187871a2cc09690de9bf418693 +Z 46c80e4b7ddf6a82d5b12bfb66b8a7fe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3cd0cbc0ec..24b6ee8c9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114 +8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de From c525e6e81793b6b133fcadfd32d49b6b63bb80ab Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Jul 2025 14:28:47 +0000 Subject: [PATCH 32/88] Make handling of LIMIT clauses in correlated sub-queries on virtual tables more efficient. FossilOrigin-Name: 7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522 --- manifest | 19 +++++++------ manifest.uuid | 2 +- src/whereexpr.c | 20 +++++++++++--- test/bestindexC.test | 63 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c3d677cc50..5afef166f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\sxBestIndex\soutput\sfrom\sthe\sext/misc/vtablog.c\nextension. -D 2025-07-03T14:10:03.834 +C Make\shandling\sof\sLIMIT\sclauses\sin\scorrelated\ssub-queries\son\svirtual\stables\smore\sefficient. +D 2025-07-03T14:28:47.394 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -870,7 +870,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c f58d41d0923eeb21cab8e4fc87a0b36c0724ff4f279ce95ab2731b4696b8e75a F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 -F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807 +F src/whereexpr.c c3ff4d8f1ae5cb9fb41460f9d960b1f519b6115585375790c53833e5642fc1f4 F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -962,7 +962,7 @@ F test/bestindex8.test b63a4f171a2c83d481bb14c431a8b72e85d27b2ffdaa0435a95d58ca9 F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce -F test/bestindexC.test 2df6ada16d8f00d9bb6a9664d9c323560aeed0e0ebc7a32b99d85d70037fd250 +F test/bestindexC.test d1e2cf074374fbfb665b0fc55668ccd6594ea1185311f8b10b36d76f7ff62145 F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114 -R 50c4d2dc6029c61dab20b65ad02b720b -U drh -Z 46c80e4b7ddf6a82d5b12bfb66b8a7fe +P 8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de +R e658b60bbaff41edf3575ab8234dd2ce +T *branch * vtab-limit-fixes +T *sym-vtab-limit-fixes * +T -sym-trunk * +U dan +Z 1a479787ca24abd6eb4307ae89399fce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24b6ee8c9a..7c4e111263 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de +7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522 diff --git a/src/whereexpr.c b/src/whereexpr.c index 53c8508e56..fc7a30a42d 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1652,7 +1652,7 @@ static void whereAddLimitExpr( ** ** 1. The SELECT statement has a LIMIT clause, and ** 2. The SELECT statement is not an aggregate or DISTINCT query, and -** 3. The SELECT statement has exactly one object in its from clause, and +** 3. The SELECT statement has exactly one object in its FROM clause, and ** that object is a virtual table, and ** 4. There are no terms in the WHERE clause that will not be passed ** to the virtual table xBestIndex method. @@ -1689,8 +1689,22 @@ void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ ** (leftCursor==iCsr) test below. */ continue; } - if( pWC->a[ii].leftCursor!=iCsr ) return; - if( pWC->a[ii].prereqRight!=0 ) return; + if( pWC->a[ii].leftCursor==iCsr && pWC->a[ii].prereqRight==0 ) continue; + + /* If this term has a parent with exactly one child, and the parent will + ** be passed through to xBestIndex, then this term can be ignored. */ + if( pWC->a[ii].iParent>=0 ){ + WhereTerm *pParent = &pWC->a[ pWC->a[ii].iParent ]; + if( pParent->leftCursor==iCsr + && pParent->prereqRight==0 + && ALWAYS(pParent->nChild==1) + ){ + continue; + } + } + + /* This term will not be passed through. Do not add a LIMIT clause. */ + return; } /* Check condition (5). Return early if it is not met. */ diff --git a/test/bestindexC.test b/test/bestindexC.test index 48f3a27655..4c4a7efe57 100644 --- a/test/bestindexC.test +++ b/test/bestindexC.test @@ -349,4 +349,67 @@ do_execsql_test 5.9 { three six seven } +#-------------------------------------------------------------------------- + +reset_db +register_tcl_module db + +proc quote {str} { + return "'[string map {' ''} $str]'" +} + +proc vtab_command {lVal method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c, d)" + } + + xBestIndex { + set hdl [lindex $args 0] + set clist [$hdl constraints] + + set idx 0 + set idxnum 0 + + foreach c $clist { + array set a $c + if {$a(usable)==0} continue + + if {$a(op)=="limit"} { + set idxnum 1 + } + + incr idx + } + + return "cost 1000 rows 1000 idxnum $idxnum" + + } + + xFilter { + foreach {idxnum idxstr lArg} $args {} + return [list sql "SELECT 0, $idxnum, $idxnum, $idxnum, $idxnum"] + } + } + + return {} +} + +do_execsql_test 6.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(2, 2); + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command t1); +} + +do_execsql_test 6.1 { SELECT * FROM x1 LIMIT 5 } {1 1 1 1} + +do_execsql_test 6.2 { SELECT * FROM x1 WHERE b=c LIMIT 5 } {0 0 0 0} + +do_execsql_test 6.3 { + SELECT (SELECT a FROM x1 WHERE t1.x=t1.y LIMIT 10) FROM t1 +} {0} + + finish_test + + From 0e6e05d4d55032126e2ce1edeabd2fd4be16049a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Jul 2025 15:32:27 +0000 Subject: [PATCH 33/88] Make the value of an explicit LIMIT clause on a scalar sub-query available to xBestIndex for simple "LIMIT 0" and "LIMIT 1" queries. FossilOrigin-Name: 33b6a63caafccc61b3193714911cd8b5dd9b7f1798054b8c7845b23688d531f2 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/expr.c | 26 ++++++++++++++++---------- test/bestindexC.test | 15 +++++++++++++-- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 5afef166f6..10466dc458 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\shandling\sof\sLIMIT\sclauses\sin\scorrelated\ssub-queries\son\svirtual\stables\smore\sefficient. -D 2025-07-03T14:28:47.394 +C Make\sthe\svalue\sof\san\sexplicit\sLIMIT\sclause\son\sa\sscalar\ssub-query\savailable\sto\sxBestIndex\sfor\ssimple\s"LIMIT\s0"\sand\s"LIMIT\s1"\squeries. +D 2025-07-03T15:32:27.267 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c e3d3b6e60b86fac772bd4d4f0c6fe1d01bef3851754a9c1215d2f8574296cbd2 +F src/expr.c 3f460c3d98b33b57e7c4665b05542f1eff62f9a524108df6d47d2ffe19473dcf F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -962,7 +962,7 @@ F test/bestindex8.test b63a4f171a2c83d481bb14c431a8b72e85d27b2ffdaa0435a95d58ca9 F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce -F test/bestindexC.test d1e2cf074374fbfb665b0fc55668ccd6594ea1185311f8b10b36d76f7ff62145 +F test/bestindexC.test 95b4a527b1a5d07951d731604a6d4cf7e5a806b39cea0e7819d4c9667e11c3fc F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de -R e658b60bbaff41edf3575ab8234dd2ce -T *branch * vtab-limit-fixes -T *sym-vtab-limit-fixes * -T -sym-trunk * +P 7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522 +R 27bb9d5812e0bc3cf60a3ade19ad2828 U dan -Z 1a479787ca24abd6eb4307ae89399fce +Z 03a23b4c5763fbd269b6e68a8e19d37c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7c4e111263..bf299eee90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522 +33b6a63caafccc61b3193714911cd8b5dd9b7f1798054b8c7845b23688d531f2 diff --git a/src/expr.c b/src/expr.c index c8dfd3af33..ebac654a2e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3896,17 +3896,23 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ VdbeComment((v, "Init EXISTS result")); } if( pSel->pLimit ){ - /* The subquery already has a limit. If the pre-existing limit is X - ** then make the new limit X<>0 so that the new limit is either 1 or 0 */ - sqlite3 *db = pParse->db; - pLimit = sqlite3Expr(db, TK_INTEGER, "0"); - if( pLimit ){ - pLimit->affExpr = SQLITE_AFF_NUMERIC; - pLimit = sqlite3PExpr(pParse, TK_NE, - sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); + /* The subquery already has a limit. If the pre-existing limit X is + ** not already integer value 1 or 0, then make the new limit X<>0 so that + ** the new limit is either 1 or 0 */ + Expr *pLeft = pSel->pLimit->pLeft; + if( ExprHasProperty(pLeft, EP_IntValue)==0 + || (pLeft->u.iValue!=1 && pLeft->u.iValue!=0) + ){ + sqlite3 *db = pParse->db; + pLimit = sqlite3Expr(db, TK_INTEGER, "0"); + if( pLimit ){ + pLimit->affExpr = SQLITE_AFF_NUMERIC; + pLimit = sqlite3PExpr(pParse, TK_NE, + sqlite3ExprDup(db, pLeft, 0), pLimit); + } + sqlite3ExprDeferredDelete(pParse, pLeft); + pSel->pLimit->pLeft = pLimit; } - sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); - pSel->pLimit->pLeft = pLimit; }else{ /* If there is no pre-existing limit add a limit of 1 */ pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); diff --git a/test/bestindexC.test b/test/bestindexC.test index 4c4a7efe57..8b96a19e6c 100644 --- a/test/bestindexC.test +++ b/test/bestindexC.test @@ -376,7 +376,7 @@ proc vtab_command {lVal method args} { if {$a(usable)==0} continue if {$a(op)=="limit"} { - set idxnum 1 + set idxnum [$hdl rhs_value $idx 555] } incr idx @@ -401,7 +401,7 @@ do_execsql_test 6.0 { CREATE VIRTUAL TABLE x1 USING tcl(vtab_command t1); } -do_execsql_test 6.1 { SELECT * FROM x1 LIMIT 5 } {1 1 1 1} +do_execsql_test 6.1 { SELECT * FROM x1 LIMIT 50 } {50 50 50 50} do_execsql_test 6.2 { SELECT * FROM x1 WHERE b=c LIMIT 5 } {0 0 0 0} @@ -409,6 +409,17 @@ do_execsql_test 6.3 { SELECT (SELECT a FROM x1 WHERE t1.x=t1.y LIMIT 10) FROM t1 } {0} +do_execsql_test 6.4 { + SELECT (SELECT a FROM x1 WHERE x1.a=1) FROM t1 +} {1} + +do_execsql_test 6.5 { + SELECT (SELECT a FROM x1 WHERE x1.a=1 LIMIT 1) FROM t1 +} {1} + +do_execsql_test 6.6 { + SELECT (SELECT a FROM x1 WHERE x1.a=555 LIMIT 2) FROM t1 +} {555} finish_test From a24a397b8bf509b7548cad3bb156102a5452526f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Jul 2025 15:50:18 +0000 Subject: [PATCH 34/88] Improvements to sqlite3_vtab_rhs_value() logging in the ext/misc/vtablog.c extension. FossilOrigin-Name: 25131ee84f53dab1191e02c19cefd256aed2828c7edea325fcc0ba3b0a668583 --- ext/misc/vtablog.c | 28 +++++++++------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c index 8e4631595d..e8e29a86ee 100644 --- a/ext/misc/vtablog.c +++ b/ext/misc/vtablog.c @@ -485,32 +485,22 @@ static int vtablogBestIndex( printf(" nConstraint: %d\n", p->nConstraint); for(i=0; inConstraint; i++){ sqlite3_value *pVal = 0; - int rc; - char zRhs[50]; - rc = sqlite3_vtab_rhs_value(p, i, &pVal); - if( rc==SQLITE_OK ){ - switch( sqlite3_value_type(pVal) ){ - case SQLITE_NULL: sqlite3_snprintf(50,zRhs,"NULL"); break; - case SQLITE_INTEGER: sqlite3_snprintf(50,zRhs,"%lld", - sqlite3_value_int64(pVal)); break; - case SQLITE_FLOAT: sqlite3_snprintf(50,zRhs,"%g", - sqlite3_value_double(pVal)); break; - case SQLITE_TEXT: sqlite3_snprintf(50,zRhs,"TEXT"); break; - default: sqlite3_snprintf(50,zRhs,"BLOB"); break; - } - }else{ - sqlite3_snprintf(50,zRhs,"N/A"); - } + int rc = sqlite3_vtab_rhs_value(p, i, &pVal); printf( - " constraint[%d]: col=%d termid=%d op=%s usabled=%d coll=%s rhs=%s\n", + " constraint[%d]: col=%d termid=%d op=%s usabled=%d coll=%s rhs=", i, p->aConstraint[i].iColumn, p->aConstraint[i].iTermOffset, vtablogOpName(p->aConstraint[i].op), p->aConstraint[i].usable, - sqlite3_vtab_collation(p,i), - zRhs + sqlite3_vtab_collation(p,i) ); + if( rc==SQLITE_OK ){ + vtablogQuote(pVal); + printf("\n"); + }else{ + printf("N/A\n"); + } } printf(" nOrderBy: %d\n", p->nOrderBy); for(i=0; inOrderBy; i++){ diff --git a/manifest b/manifest index 10466dc458..067a40c6b6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\svalue\sof\san\sexplicit\sLIMIT\sclause\son\sa\sscalar\ssub-query\savailable\sto\sxBestIndex\sfor\ssimple\s"LIMIT\s0"\sand\s"LIMIT\s1"\squeries. -D 2025-07-03T15:32:27.267 +C Improvements\sto\ssqlite3_vtab_rhs_value()\slogging\sin\sthe\next/misc/vtablog.c\sextension. +D 2025-07-03T15:50:18.737 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -456,7 +456,7 @@ F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505 F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c 0b23c0a69a2b63dc0ef0af44f9c1fc977300c480a1f7a9814500369d8211f56e F ext/misc/vfstrace.c 0e4b8b17ac0675ea90f6d168d8214687e06ca3efbc0060aad4814994d82b41fb -F ext/misc/vtablog.c ee27ec6595751db0ce4b8c2a2b72f6eca4d018d9d33e139dbd477e8d173f7b0e +F ext/misc/vtablog.c 62d54fb0f4ff9df72ffa44f4a226451a964e1d96ac550f2b8906feebdad00b58 F ext/misc/vtshim.c e5bce24ab8c532f4fdc600148718fe1802cb6ed57417f1c1032d8961f72b0e8f F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522 -R 27bb9d5812e0bc3cf60a3ade19ad2828 -U dan -Z 03a23b4c5763fbd269b6e68a8e19d37c +P 33b6a63caafccc61b3193714911cd8b5dd9b7f1798054b8c7845b23688d531f2 +R 03da53ec2c5bbfaf5954c2ff4dc81144 +U drh +Z 144b12a9e1e61db61bb4478b5371f987 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bf299eee90..1736696637 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33b6a63caafccc61b3193714911cd8b5dd9b7f1798054b8c7845b23688d531f2 +25131ee84f53dab1191e02c19cefd256aed2828c7edea325fcc0ba3b0a668583 From 1b62720fa8e0a344681ffb4d1518c4551564c2a8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 4 Jul 2025 10:26:55 +0000 Subject: [PATCH 35/88] Improve the early-termination optimization so that it works in queries which use the LIKE optimization in the outer loop. FossilOrigin-Name: b4e4d148243cfcb09aa0aaca30e83812b42e2780073e55c0e8c6e3da16243dfc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 77bee83097..8f4d2219c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\sfixes\sand\senhancements\sinto\sthe\sempty-table-optimizations\sbranch -D 2025-07-03T20:51:08.444 +C Improve\sthe\searly-termination\soptimization\sso\sthat\sit\sworks\sin\squeries\nwhich\suse\sthe\sLIKE\soptimization\sin\sthe\souter\sloop. +D 2025-07-04T10:26:55.842 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -867,7 +867,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 458b2089adc9ad65b2585fdf705b716e74abef146f20472962368cd784898f65 +F src/where.c f8139d355555e305aa5cf40ddf0f94ca606341d5196c6c597a79e6b1f7a173ee F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 2917e70e12f7b238285240e564329374f20e4270fe90c36e0d19b6770754a7c4 F src/whereexpr.c c3ff4d8f1ae5cb9fb41460f9d960b1f519b6115585375790c53833e5642fc1f4 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9cb600ad576c68647ed943a0773019312c5f01c9c1ca9ff0bf1214b03a531b48 960a8e6fc91f47add3a089dc6cef013109deadf809994c5149ad3bdfb3884de0 -R 16f14c5f6cd8a80b6f70e6c8ec90dbe2 +P d4f47e04f5880e99a53089e2dd5cde64a7ea44f059d9906b5d11324896546714 +R a697518c4d8b922117d5dad06f7688c7 U drh -Z c17d256ee21406dce84038f025b1e634 +Z ef38abde98882fa21d988c824ad69a24 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 600147ed5c..ab2837e8bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4f47e04f5880e99a53089e2dd5cde64a7ea44f059d9906b5d11324896546714 +b4e4d148243cfcb09aa0aaca30e83812b42e2780073e55c0e8c6e3da16243dfc diff --git a/src/where.c b/src/where.c index 69b206a22e..059b0e89ea 100644 --- a/src/where.c +++ b/src/where.c @@ -7139,7 +7139,7 @@ WhereInfo *sqlite3WhereBegin( && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 && pLevel->addrHalt==pWInfo->a[0].addrHalt ){ - sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pLevel->addrHalt); + sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pWInfo->iBreak); VdbeCoverage(v); } }else{ From 478dfc7e74921f391732e03b486c786d4c7bd49b Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 4 Jul 2025 11:06:34 +0000 Subject: [PATCH 36/88] Do not allow the EXISTS-to-JOIN optimization if the EXISTS clause is based on a view, since that view might expand into a join. FossilOrigin-Name: 872c41feddafcc21a02f1229ce017ceea9f8e309a4dd5b6e323477d67f975947 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8f4d2219c7..0ed185a563 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\searly-termination\soptimization\sso\sthat\sit\sworks\sin\squeries\nwhich\suse\sthe\sLIKE\soptimization\sin\sthe\souter\sloop. -D 2025-07-04T10:26:55.842 +C Do\snot\sallow\sthe\sEXISTS-to-JOIN\soptimization\sif\sthe\sEXISTS\sclause\sis\sbased\non\sa\sview,\ssince\sthat\sview\smight\sexpand\sinto\sa\sjoin. +D 2025-07-04T11:06:34.046 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5b14cad58bc21341fbaea76d7e781187559627a461745ece00c2655ba7c083ec F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c be5543b598cc0d217b34ddf804aaab7f5cf63d74958bf6e2a2f3523f4b07fced +F src/select.c 6ce33294314f05898a35205566a7d7d5034f8a6f7ad9cb9e3804f4765a100290 F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d4f47e04f5880e99a53089e2dd5cde64a7ea44f059d9906b5d11324896546714 -R a697518c4d8b922117d5dad06f7688c7 +P b4e4d148243cfcb09aa0aaca30e83812b42e2780073e55c0e8c6e3da16243dfc +R 3690d7e51c5bb54cabac58a689eae722 U drh -Z ef38abde98882fa21d988c824ad69a24 +Z c7e5a37e4d84ec49607cdfc27b218111 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ab2837e8bd..eb7428f280 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4e4d148243cfcb09aa0aaca30e83812b42e2780073e55c0e8c6e3da16243dfc +872c41feddafcc21a02f1229ce017ceea9f8e309a4dd5b6e323477d67f975947 diff --git a/src/select.c b/src/select.c index ff45394008..750de5e8ff 100644 --- a/src/select.c +++ b/src/select.c @@ -7437,9 +7437,10 @@ static SQLITE_NOINLINE void existsToJoin( } else if( pWhere->op==TK_EXISTS ){ Select *pSub = pWhere->x.pSelect; - if( pSub->pSrc->nSrc==1 + if( pSub->pSrc->nSrc==1 && (pSub->selFlags & SF_Aggregate)==0 && pSub->pWhere + && !pSub->pSrc->a[0].fg.isSubquery ){ memset(pWhere, 0, sizeof(*pWhere)); pWhere->op = TK_INTEGER; From a12e92d2f7ce61552fee3f404a67bb156a22c42e Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 4 Jul 2025 11:48:11 +0000 Subject: [PATCH 37/88] Remove an ALWAYS() added by [960a8e6fc91f4] that turns out to be false in some cases of malformed SQL. FossilOrigin-Name: cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/whereexpr.c | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0bb98b5b83..569b1b2b19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfew\scases\swhere\sLIMIT\sclauses\sthat\swere\spart\sof\sscalar\ssub-queries\son\svirtual\stables\swere\snot\sbeing\spassed\sto\sxBestIndex\smethods\scorrectly. -D 2025-07-03T16:05:41.252 +C Remove\san\sALWAYS()\sadded\sby\s[960a8e6fc91f4]\sthat\sturns\sout\sto\sbe\sfalse\nin\ssome\scases\sof\smalformed\sSQL. +D 2025-07-04T11:48:11.940 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -870,7 +870,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c f58d41d0923eeb21cab8e4fc87a0b36c0724ff4f279ce95ab2731b4696b8e75a F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 -F src/whereexpr.c c3ff4d8f1ae5cb9fb41460f9d960b1f519b6115585375790c53833e5642fc1f4 +F src/whereexpr.c d007dc41364de5902181739632380afd671e14f0c5cc9978e64a2c6df8f28c6c F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -2208,9 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de 25131ee84f53dab1191e02c19cefd256aed2828c7edea325fcc0ba3b0a668583 -R 03da53ec2c5bbfaf5954c2ff4dc81144 -T +closed 25131ee84f53dab1191e02c19cefd256aed2828c7edea325fcc0ba3b0a668583 -U dan -Z 169d778787b3864e08d84b0f7a4d552a +P 960a8e6fc91f47add3a089dc6cef013109deadf809994c5149ad3bdfb3884de0 +R 2b767023b56fca9880f54e3c3dd53ae7 +U drh +Z fdc5ecc6df8a387611d532c479013302 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e9ea7fa4a..8514d2385e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -960a8e6fc91f47add3a089dc6cef013109deadf809994c5149ad3bdfb3884de0 +cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5 diff --git a/src/whereexpr.c b/src/whereexpr.c index fc7a30a42d..e4be8d9d67 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1697,7 +1697,7 @@ void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ WhereTerm *pParent = &pWC->a[ pWC->a[ii].iParent ]; if( pParent->leftCursor==iCsr && pParent->prereqRight==0 - && ALWAYS(pParent->nChild==1) + && pParent->nChild==1 ){ continue; } From e33ea17d24d9afe35b7ced85754e92ac513120e9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 4 Jul 2025 12:25:24 +0000 Subject: [PATCH 38/88] Fix harmless compiler warnings. FossilOrigin-Name: 13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc --- ext/fts5/fts5_index.c | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/expr.c | 1 + 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1c3053386d..5a50637486 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5847,7 +5847,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( } nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); - assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); + assert( nByte==(i64)SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ diff --git a/manifest b/manifest index 569b1b2b19..dd9a55e145 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sALWAYS()\sadded\sby\s[960a8e6fc91f4]\sthat\sturns\sout\sto\sbe\sfalse\nin\ssome\scases\sof\smalformed\sSQL. -D 2025-07-04T11:48:11.940 +C Fix\sharmless\scompiler\swarnings. +D 2025-07-04T12:25:24.884 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c fe99dbb3622609e358113cfc8f49aa7a4e6312cba047e7abd0f867b7d6c4c9d5 +F ext/fts5/fts5_index.c ed562b75c87efaa80c40e55f6c1102904728e35baa293c371f96b1c8e151399d F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -726,7 +726,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 81fb44041929a605e293185bd4091cb24c468a108afe8ba1d93a81a8823de47f +F src/btree.c 783f9999f9ca56846619ba902f5970e181d897c23cc923c915fef225af6dda8a F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f @@ -736,7 +736,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 3f460c3d98b33b57e7c4665b05542f1eff62f9a524108df6d47d2ffe19473dcf +F src/expr.c 12d8a79f6a0eb9bfae2d468a6d5bd7b9a0ff00988b3f5326ec9bbaad61bbf385 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 960a8e6fc91f47add3a089dc6cef013109deadf809994c5149ad3bdfb3884de0 -R 2b767023b56fca9880f54e3c3dd53ae7 +P cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5 +R dcce4951e27b93fcf8c3ca4486981e14 U drh -Z fdc5ecc6df8a387611d532c479013302 +Z 588ae666a6340faba85996112e26e13c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8514d2385e..957933770e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5 +13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc diff --git a/src/btree.c b/src/btree.c index 1806a914a6..00cdc9760e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1929,10 +1929,10 @@ static int freeSpace(MemPage *pPage, int iStart, int iSize){ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); - assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); + assert( CORRUPT_DB || iEnd <= (int)pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ - assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); + assert( CORRUPT_DB || iStart<=(int)pPage->pBt->usableSize-4 ); /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. diff --git a/src/expr.c b/src/expr.c index ebac654a2e..3f040309a7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2428,6 +2428,7 @@ static int exprComputeOperands( VdbeComment((v, "skip left operand")); VdbeCoverage(v); }else{ + r2 = 0; /* Silence a false-positive uninit-var warning in MSVC */ addrIsNull = 0; } r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); From d9eae6b75a37e63c30c3c05c5c1fc7ed425589cd Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 4 Jul 2025 17:20:37 +0000 Subject: [PATCH 39/88] Propagate the -ldl and -lpthread flags, if needed, into sqlite3.pc, per request in [forum:44a58c807353162f | forum post 44a58c807353162f]. FossilOrigin-Name: 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 --- manifest | 14 +++++++------- manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dd9a55e145..df4924ae49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2025-07-04T12:25:24.884 +C Propagate\sthe\s-ldl\sand\s-lpthread\sflags,\sif\sneeded,\sinto\ssqlite3.pc,\sper\srequest\sin\s[forum:44a58c807353162f\s|\sforum\spost\s44a58c807353162f]. +D 2025-07-04T17:20:37.961 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -718,7 +718,7 @@ F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 +F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398 F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5 -R dcce4951e27b93fcf8c3ca4486981e14 -U drh -Z 588ae666a6340faba85996112e26e13c +P 13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc +R 099a06c2d2154ffe42a8ab041db48e77 +U stephan +Z 5b5dde027d1afefeb6302b541ead0c38 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 957933770e..0c574d6d2a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc +64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 diff --git a/sqlite3.pc.in b/sqlite3.pc.in index a9f941b1e4..723dd51563 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_ICU@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_DLOPEN@ @LDFLAGS_PTHREAD@ @LDFLAGS_ICU@ Cflags: -I${includedir} From 27408ab9c941219b563d74dc1c5218ee9a6bb382 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 4 Jul 2025 18:32:18 +0000 Subject: [PATCH 40/88] Add 'reconfigure' target to Makefile.in to re-run the configure script with the same flags it was generated with. FossilOrigin-Name: c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 --- Makefile.in | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 995bbde449..d462d811ed 100644 --- a/Makefile.in +++ b/Makefile.in @@ -264,7 +264,9 @@ AS_AUTO_DEF = $(TOP)/auto.def # invoked with to produce this makefile. # AS_AUTORECONFIG = @SQLITE_AUTORECONFIG@ - +.PHONY: reconfigure +reconfigure: + $(AS_AUTORECONFIG) USE_AMALGAMATION ?= @USE_AMALGAMATION@ LINK_TOOLS_DYNAMICALLY ?= @LINK_TOOLS_DYNAMICALLY@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ diff --git a/manifest b/manifest index df4924ae49..423c865285 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Propagate\sthe\s-ldl\sand\s-lpthread\sflags,\sif\sneeded,\sinto\ssqlite3.pc,\sper\srequest\sin\s[forum:44a58c807353162f\s|\sforum\spost\s44a58c807353162f]. -D 2025-07-04T17:20:37.961 +C Add\s'reconfigure'\starget\sto\sMakefile.in\sto\sre-run\sthe\sconfigure\sscript\swith\sthe\ssame\sflags\sit\swas\sgenerated\swith. +D 2025-07-04T18:32:18.912 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in d8bc4aee9fb645c9f2ff0e3a30585d17a0df076bb6a33f0f20bab4999abb45a0 +F Makefile.in a6c14b6906f5322920dd5d1ff9a84808337911068f2a6e777ec7088a87cbc3a8 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc ec2011bbdfc917d6a1c7c173dabb29c14ead0dd8e2e0b67278a00ae4ba576a77 F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc -R 099a06c2d2154ffe42a8ab041db48e77 +P 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 +R 2e84b390408477c8e70efdd22e84c169 U stephan -Z 5b5dde027d1afefeb6302b541ead0c38 +Z a6be9728f4a0aec0de70108286e76b7e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0c574d6d2a..08e4c43bce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 +c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 From 8bc112e3e453a9e574a800e7edab3afecb064449 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 5 Jul 2025 23:33:21 +0000 Subject: [PATCH 41/88] Enhance the EXISTS-to-JOIN optimization so that it works on EXISTS subqueries that do not have a WHERE clause, and so that it works on nested EXISTS subqueries. FossilOrigin-Name: c1d5295724f9cf7f49e0786d28016eff2d268a2b670f934d24c76787626089db --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 22 +++++++++++++++------- test/existsexpr.test | 2 +- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 3afc7c8322..700cfd8a47 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sfixes\sfrom\strunk\sinto\sthe\sempty-table-optimizations\sbranch -D 2025-07-04T14:24:18.375 +C Enhance\sthe\sEXISTS-to-JOIN\soptimization\sso\sthat\sit\sworks\son\sEXISTS\ssubqueries\nthat\sdo\snot\shave\sa\sWHERE\sclause,\sand\sso\sthat\sit\sworks\son\snested\sEXISTS\nsubqueries. +D 2025-07-05T23:33:21.216 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5b14cad58bc21341fbaea76d7e781187559627a461745ece00c2655ba7c083ec F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 6ce33294314f05898a35205566a7d7d5034f8a6f7ad9cb9e3804f4765a100290 +F src/select.c b1d4e1f21a32b4f33d3bf02c4167ac8da5aafb97210a0b13a9119d68183db37d F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -1140,7 +1140,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test d87e7ee394935f9b4a9a1a488f3faa55abd20dd85152efaf2034881a079c7ba1 +F test/existsexpr.test cefe49ffc2295281908e0e1dd6d289381d2c3bcbbabcf36cd799cedb0708c7e9 F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11 F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 4ada8eb822c45ef27a36851a258004d43c1e95e7c82585a1217e732084e4482c @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 872c41feddafcc21a02f1229ce017ceea9f8e309a4dd5b6e323477d67f975947 13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc -R bc9dd605b1b6086398bb04180450d2c6 +P 6f98b16d210a9f5b6ca4b4599e3dab3263eddbae7c70ddbcabf988f4a1014e8b +R 1a0b4833b41c9eafcebd2713b9567447 U drh -Z 9c89d6634e2f24fe30079554a53be2d7 +Z d76421db80a68ce3b2346aa4278aa4db # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7864b0e031..24edc66d6f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f98b16d210a9f5b6ca4b4599e3dab3263eddbae7c70ddbcabf988f4a1014e8b +c1d5295724f9cf7f49e0786d28016eff2d268a2b670f934d24c76787626089db diff --git a/src/select.c b/src/select.c index 750de5e8ff..b15300237a 100644 --- a/src/select.c +++ b/src/select.c @@ -7418,11 +7418,17 @@ static int fromClauseTermCanBeCoroutine( ** ** SELECT name FROM sailors AS S, reserves AS R ** WHERE S.sid = R.sid AND R.day = '2022-10-25'; +** +** **Approximately**. Really, we have to ensure that the FROM-clause term +** that was formerly inside the EXISTS is only executed once. This is handled +** by setting the SrcItem.fg.fromExists flag, which then causes code in +** the where.c file to exit the corresponding loop after the first successful +** match (if any). */ static SQLITE_NOINLINE void existsToJoin( - Parse *pParse, - Select *p, - Expr *pWhere + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement being optimized */ + Expr *pWhere /* part of the WHERE clause currently being examined */ ){ if( pWhere && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) @@ -7437,9 +7443,9 @@ static SQLITE_NOINLINE void existsToJoin( } else if( pWhere->op==TK_EXISTS ){ Select *pSub = pWhere->x.pSelect; + Expr *pSubWhere = pSub->pWhere; if( pSub->pSrc->nSrc==1 && (pSub->selFlags & SF_Aggregate)==0 - && pSub->pWhere && !pSub->pSrc->a[0].fg.isSubquery ){ memset(pWhere, 0, sizeof(*pWhere)); @@ -7451,9 +7457,10 @@ static SQLITE_NOINLINE void existsToJoin( pSub->pSrc->a[0].fg.fromExists = 1; pSub->pSrc->a[0].fg.jointype |= JT_CROSS; p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); - p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere); - - pSub->pWhere = 0; + if( pSubWhere ){ + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere); + pSub->pWhere = 0; + } pSub->pSrc = 0; sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub); #if TREETRACE_ENABLED @@ -7463,6 +7470,7 @@ static SQLITE_NOINLINE void existsToJoin( sqlite3TreeViewSelect(0, p, 0); } #endif + existsToJoin(pParse, p, pSubWhere); } } } diff --git a/test/existsexpr.test b/test/existsexpr.test index 51b9234b7f..c28955b672 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -193,7 +193,7 @@ do_subquery_test 3.7 1 { 4 4 4 } -do_subquery_test 3.8 1 { +do_subquery_test 3.8 0 { SELECT * FROM y1 WHERE EXISTS ( SELECT a+1 FROM y2 ) } { 1 1 1 From c701d173668b07e743e7af8132842b7e6d8c1922 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 6 Jul 2025 01:19:09 +0000 Subject: [PATCH 42/88] Improvements to the EXPLAIN QUERY PLAN output for EXISTS-to-JOIN. FossilOrigin-Name: 6b1ecbaa2ee405be040901dceac45d027d35c313622748ba4dbbd404e297a7fa --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 14 ++++---------- test/eqp.test | 2 +- test/existsexpr.test | 4 ++-- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 700cfd8a47..4b0c4022b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sEXISTS-to-JOIN\soptimization\sso\sthat\sit\sworks\son\sEXISTS\ssubqueries\nthat\sdo\snot\shave\sa\sWHERE\sclause,\sand\sso\sthat\sit\sworks\son\snested\sEXISTS\nsubqueries. -D 2025-07-05T23:33:21.216 +C Improvements\sto\sthe\sEXPLAIN\sQUERY\sPLAN\soutput\sfor\sEXISTS-to-JOIN. +D 2025-07-06T01:19:09.350 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -869,7 +869,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c f8139d355555e305aa5cf40ddf0f94ca606341d5196c6c597a79e6b1f7a173ee F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da -F src/wherecode.c 2917e70e12f7b238285240e564329374f20e4270fe90c36e0d19b6770754a7c4 +F src/wherecode.c ff520ce2a1ac8248e7adc1cff7ea2141fb07260ece28d2c6130e87fdfc0d2afa F src/whereexpr.c d007dc41364de5902181739632380afd671e14f0c5cc9978e64a2c6df8f28c6c F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1131,7 +1131,7 @@ F test/enc.test b5503a87b31cea8a5084c6e447383f9ca08933bd2f29d97b6b6201081b2343eb F test/enc2.test 872afe58db772e7dfa1ad8e0759f8cc820e9efc8172d460fae83023101c2e435 F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test 800fb69fae9086b76dc767931a9973355187d673f69cd2ccfd3c455528af7859 +F test/eqp.test 746db9fe11629a0d00328e1721cc2a2e4726d574b677ab14de35fd914f54cc82 F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/errofst1.test 6da78363739ba8991f498396ab331b5d64e7ab5c4172c12b5884683ef523ac53 @@ -1140,7 +1140,7 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/existsexpr.test cefe49ffc2295281908e0e1dd6d289381d2c3bcbbabcf36cd799cedb0708c7e9 +F test/existsexpr.test 40ddd9500109579dd949cd15bbb4e3a88f79f905d1f31905b9493651f60aacf6 F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11 F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e F test/expr.test 4ada8eb822c45ef27a36851a258004d43c1e95e7c82585a1217e732084e4482c @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6f98b16d210a9f5b6ca4b4599e3dab3263eddbae7c70ddbcabf988f4a1014e8b -R 1a0b4833b41c9eafcebd2713b9567447 +P c1d5295724f9cf7f49e0786d28016eff2d268a2b670f934d24c76787626089db +R e327f2cba9403b63bcd0d2189ed9005a U drh -Z d76421db80a68ce3b2346aa4278aa4db +Z 99af5d89797b6a2541e58b654e88bc24 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24edc66d6f..870e5bc361 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1d5295724f9cf7f49e0786d28016eff2d268a2b670f934d24c76787626089db +6b1ecbaa2ee405be040901dceac45d027d35c313622748ba4dbbd404e297a7fa diff --git a/src/wherecode.c b/src/wherecode.c index 9c611001bb..5111880c05 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -126,7 +126,6 @@ void sqlite3WhereAddExplainText( #endif { VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); - SrcItem *pItem = &pTabList->a[pLevel->iFrom]; sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ @@ -135,7 +134,6 @@ void sqlite3WhereAddExplainText( #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) char *zMsg; /* Text to add to EQP output */ #endif - const char *zFormat; StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ @@ -150,14 +148,10 @@ void sqlite3WhereAddExplainText( sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); str.printfFlags = SQLITE_PRINTF_INTERNAL; - if( pItem->fg.fromExists ){ - zFormat = "SINGLETON %S"; - }else if( isSearch ){ - zFormat = "SEARCH %S"; - }else{ - zFormat = "SCAN %S"; - } - sqlite3_str_appendf(&str, zFormat, pItem); + sqlite3_str_appendf(&str, "%s %S%s", + isSearch ? "SEARCH" : "SCAN", + pItem, + pItem->fg.fromExists ? " EXISTS" : ""); if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; Index *pIdx; diff --git a/test/eqp.test b/test/eqp.test index b7e7acd8a0..147b5ceafe 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -338,7 +338,7 @@ det 3.3.3 { } { QUERY PLAN |--SCAN t1 - `--SINGLETON t2 + `--SCAN t2 EXISTS } #------------------------------------------------------------------------- diff --git a/test/existsexpr.test b/test/existsexpr.test index c28955b672..2bf2e8223f 100644 --- a/test/existsexpr.test +++ b/test/existsexpr.test @@ -94,13 +94,13 @@ do_execsql_test 2.4.0 { do_eqp_test 2.4.1 { SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); -} {SCAN t1*SINGLETON t2} +} {SCAN t1*t2 EXISTS} do_execsql_test 2.4.2 { ANALYZE; } do_eqp_test 2.4.3 { SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); -} {SCAN t1*SINGLETON t2} +} {SCAN t1*t2 EXISTS} do_execsql_test 2.4.4 { SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a); } {100} From 4d453cc2eda12164bb14ab9e773101919f85aac7 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:01:44 +0000 Subject: [PATCH 43/88] Experimentally add sqlite3.oo1.DB/Stmt.wrapHandle(), which allow DB/Stmt instances to wrap a (sqlite3*)/(sqlite3_stmt*) optionally with or without taking ownership of it. The intent is to enable mix-and-match use of the C API, the oo1 API, and any other hypothetical API which exposes those pointers. oo1.Stmt.parameterCount is now a property access interceptor like Stmt.columnCount is, but that doesn't change how it's used. FossilOrigin-Name: 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 321 ++++++++++++++++++++------- ext/wasm/tester1.c-pp.js | 90 +++++++- manifest | 17 +- manifest.uuid | 2 +- 4 files changed, 346 insertions(+), 84 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 06f9160021..91d8bc544d 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -37,6 +37,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ it. */ const __ptrMap = new WeakMap(); + /** + A Set of oo1.DB objects which are proxies for (A) (sqlite3*) or + another oo1.DB object or (B) oo1.Stmt objects which are proxies + for (sqlite3_stmt*) pointers. Such objects do not own their + underlying handle and that handle must be guaranteed (by the + client) to outlive the proxy. These proxies are primarily + intended as a way to briefly wrap an (sqlite3[_stmt]*) object as + an oo1.DB/Stmt without taking over ownership. + */ + const __doesNotOwnHandle = new Set(); /** Map of DB instances to objects, each object being a map of Stmt wasm pointers to Stmt objects. @@ -234,73 +244,89 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; } const opt = ctor.normalizeArgs(...args); - let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags; - if(('string'!==typeof fn && 'number'!==typeof fn) - || 'string'!==typeof flagsStr - || (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){ - sqlite3.config.error("Invalid DB ctor args",opt,arguments); - toss3("Invalid arguments for DB constructor."); - } - let fnJs = ('number'===typeof fn) ? wasm.cstrToJs(fn) : fn; - const vfsCheck = ctor._name2vfs[fnJs]; - if(vfsCheck){ - vfsName = vfsCheck.vfs; - fn = fnJs = vfsCheck.filename(fnJs); - } - let pDb, oflags = 0; - if( flagsStr.indexOf('c')>=0 ){ - oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE; - } - if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE; - if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY; - oflags |= capi.SQLITE_OPEN_EXRESCODE; - const stack = wasm.pstack.pointer; - try { - const pPtr = wasm.pstack.allocPtr() /* output (sqlite3**) arg */; - let rc = capi.sqlite3_open_v2(fn, pPtr, oflags, vfsName || 0); - pDb = wasm.peekPtr(pPtr); - checkSqlite3Rc(pDb, rc); - capi.sqlite3_extended_result_codes(pDb, 1); - if(flagsStr.indexOf('t')>=0){ - capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, - __dbTraceToConsole, pDb); + //sqlite3.config.debug("DB ctor",opt); + let pDb; + if( (pDb = opt['sqlite3*']) ){ + /* This property ^^^^^ is very specifically NOT DOCUMENTED and + NOT part of the public API. This is a back door for functions + like DB.wrapDbHandle(). */ + //sqlite3.config.debug("creating proxy db from",opt); + if( !opt['sqlite3*:takeOwnership'] ){ + /* This is object does not own its handle. */ + __doesNotOwnHandle.add(this); } - }catch( e ){ - if( pDb ) capi.sqlite3_close_v2(pDb); - throw e; - }finally{ - wasm.pstack.restore(stack); + this.filename = capi.sqlite3_db_filename(pDb,'main'); + }else{ + let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags; + if(('string'!==typeof fn && 'number'!==typeof fn) + || 'string'!==typeof flagsStr + || (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){ + sqlite3.config.error("Invalid DB ctor args",opt,arguments); + toss3("Invalid arguments for DB constructor."); + } + let fnJs = ('number'===typeof fn) ? wasm.cstrToJs(fn) : fn; + const vfsCheck = ctor._name2vfs[fnJs]; + if(vfsCheck){ + vfsName = vfsCheck.vfs; + fn = fnJs = vfsCheck.filename(fnJs); + } + let oflags = 0; + if( flagsStr.indexOf('c')>=0 ){ + oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE; + } + if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE; + if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY; + oflags |= capi.SQLITE_OPEN_EXRESCODE; + const stack = wasm.pstack.pointer; + try { + const pPtr = wasm.pstack.allocPtr() /* output (sqlite3**) arg */; + let rc = capi.sqlite3_open_v2(fn, pPtr, oflags, vfsName || 0); + pDb = wasm.peekPtr(pPtr); + checkSqlite3Rc(pDb, rc); + capi.sqlite3_extended_result_codes(pDb, 1); + if(flagsStr.indexOf('t')>=0){ + capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT, + __dbTraceToConsole, pDb); + } + }catch( e ){ + if( pDb ) capi.sqlite3_close_v2(pDb); + throw e; + }finally{ + wasm.pstack.restore(stack); + } + this.filename = fnJs; } - this.filename = fnJs; __ptrMap.set(this, pDb); __stmtMap.set(this, Object.create(null)); - try{ + if( !opt['sqlite3*'] ){ + try{ //#if enable-see - dbCtorApplySEEKey(this,opt); + dbCtorApplySEEKey(this,opt); //#endif - // Check for per-VFS post-open SQL/callback... - const pVfs = capi.sqlite3_js_db_vfs(pDb) - || toss3("Internal error: cannot get VFS for new db handle."); - const postInitSql = __vfsPostOpenCallback[pVfs]; - if(postInitSql){ - /** - Reminder: if this db is encrypted and the client did _not_ pass - in the key, any init code will fail, causing the ctor to throw. - We don't actually know whether the db is encrypted, so we cannot - sensibly apply any heuristics which skip the init code only for - encrypted databases for which no key has yet been supplied. - */ - if(postInitSql instanceof Function){ - postInitSql(this, sqlite3); - }else{ - checkSqlite3Rc( - pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) - ); + // Check for per-VFS post-open SQL/callback... + const pVfs = capi.sqlite3_js_db_vfs(pDb) + || toss3("Internal error: cannot get VFS for new db handle."); + const postInitSql = __vfsPostOpenCallback[pVfs]; + if(postInitSql){ + /** + Reminder: if this db is encrypted and the client did _not_ pass + in the key, any init code will fail, causing the ctor to throw. + We don't actually know whether the db is encrypted, so we cannot + sensibly apply any heuristics which skip the init code only for + encrypted databases for which no key has yet been supplied. + */ + if(postInitSql instanceof Function){ + postInitSql(this, sqlite3); + }else{ + checkSqlite3Rc( + pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0) + ); + } } + }catch(e){ + this.close(); + throw e; } - }catch(e){ - this.close(); - throw e; } }; @@ -486,26 +512,30 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - `db`: the DB object which created the statement. - `columnCount`: the number of result columns in the query, or 0 - for queries which cannot return results. This property is a proxy - for sqlite3_column_count() and its use in loops should be avoided - because of the call overhead associated with that. The - `columnCount` is not cached when the Stmt is created because a - schema change made via a separate db connection between this - statement's preparation and when it is stepped may invalidate it. + for queries which cannot return results. This property is a + read-only proxy for sqlite3_column_count() and its use in loops + should be avoided because of the call overhead associated with + that. The `columnCount` is not cached when the Stmt is created + because a schema change made between this statement's preparation + and when it is stepped may invalidate it. - - `parameterCount`: the number of bindable parameters in the query. + - `parameterCount`: the number of bindable parameters in the + query. Like `columnCount`, this property is ready-only and is a + proxy for a C API call. As a general rule, most methods of this class will throw if called on an instance which has been finalized. For brevity's sake, the method docs do not all repeat this warning. */ - const Stmt = function(){ + const Stmt = function(/*oo1db, stmtPtr, BindTypes [,takeOwnership=true] */){ if(BindTypes!==arguments[2]){ toss3(capi.SQLITE_MISUSE, "Do not call the Stmt constructor directly. Use DB.prepare()."); } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - this.parameterCount = capi.sqlite3_bind_parameter_count(this.pointer); + if( arguments.length>3 && false===arguments[3] ){ + __doesNotOwnHandle.add(this); + } }; /** Throws if the given DB has been closed, else it is returned. */ @@ -723,12 +753,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ a db. */ close: function(){ - if(this.pointer){ + const pDb = this.pointer; + if(pDb){ if(this.onclose && (this.onclose.before instanceof Function)){ try{this.onclose.before(this)} catch(e){/*ignore*/} } - const pDb = this.pointer; Object.keys(__stmtMap.get(this)).forEach((k,s)=>{ if(s && s.pointer){ try{s.finalize()} @@ -737,7 +767,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }); __ptrMap.delete(this); __stmtMap.delete(this); - capi.sqlite3_close_v2(pDb); + if( !__doesNotOwnHandle.delete(this) ){ + capi.sqlite3_close_v2(pDb); + } if(this.onclose && (this.onclose.after instanceof Function)){ try{this.onclose.after(this)} catch(e){/*ignore*/} @@ -1450,9 +1482,87 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ checkRc: function(resultCode){ return checkSqlite3Rc(this, resultCode); - } + }, }/*DB.prototype*/; + /** + Returns a new oo1.DB instance which wraps the given db. + + The first argument must be either a non-NULL (sqlite3*) WASM + pointer or a non-close()d instance of oo1.DB. + + The second argument only applies if the first argument is a + (sqlite3*). If it is, the returned object will pass that pointer + to sqlite3_close() when its close() method is called, otherwise + it will not. + + If the first argument is a oo1.DB object, the second argument is + disregarded and the returned object will be created as a + sqlite3.oo1.DB object (as opposed to the concrete derived DB + subclass from the first argument), so will not include any + derived-type behaviors, + e.g. JsStorageDb.prototype.clearStorage(). + + Throws if db cannot be resolved to one of the legal options. + + The caller MUST GUARANTEE that the passed-in handle will outlive + the returned object, i.e. that it will not be closed. If it is closed, + this object will hold a stale pointer and results are undefined. + + Aside from its lifetime, the proxy is to be treated as any other + DB instance, including the requirement of calling close() on + it. close() will free up internal resources owned by the proxy, + and disassociate the proxy from that handle, but will not + actually close the proxied db handle. + + The following quirks and requirements apply when proxying another + DB instance, as opposed to a (sqlite3*): + + - DO NOT call close() on the being-proxied instance while a proxy + is active. + + - ALWAYS eventually call close() on the returned object BEFORE + the being-proxied handle is closed. + + - For historical reasons, the filename property of the returned + object is captured at the time of this call, as opposed to being + dynamically proxied. e.g., if the filename property of the + being-proxied object is changed, this object will not reflect + that change. There is no good reason to ever modify that + property, so this distinction is not truly significant but it's + noted here because it's a client-visible discrepancy between the + proxy and its partner. (Sidebar: the filename property _should_ + be a property access interceptor for sqlite3_db_filename(), + but making it so now may break existing code.) + */ + DB.wrapHandle = function(db, takeOwnership=false){ + let ptr, ctor = DB; + const oo1db = (db instanceof DB) ? db : undefined; + if( wasm.isPtr(db) ){ + ptr = db; + }else if( oo1db ){ + takeOwnership = false; + ptr = db.pointer; + //ctor = db.constructor; + // ^^^ that doesn't work, resulting in an Object-type value + } + //sqlite3.config.debug("wrapHandle()",'db',db,'ctor',ctor, + //'arguments',arguments,'db.constructor',db.constructor); + if( !ptr ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "Argument must be a WASM sqlite3 "+ + "pointer or an sqlite3.oo1.DB instance"); + } + const dc = new ctor({ + "sqlite3*": ptr, + "sqlite3*:takeOwnership": !!takeOwnership + }); + if( oo1db ){ + dc.filename = oo1db.filename; + }//else dc.filename was captured by the ctor for legacy consistency + //sqlite3.config.debug("wrapHandle() dc",dc); + return dc; + }/*DB.wrapHandle()*/; /** Throws if the given Stmt has been finalized, else stmt is returned. */ @@ -1641,12 +1751,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ This method always throws if called when it is illegal to do so. Namely, when triggered via a per-row callback handler of a DB.exec() call. + + If Stmt does not own its underlying (sqlite3_stmt*) (see + Stmt.wrapHandle()) then this function will not pass it to + sqlite3_finalize(). */ finalize: function(){ - if(this.pointer){ + const ptr = this.pointer; + if(ptr){ affirmNotLockedByExec(this,'finalize()'); - const rc = capi.sqlite3_finalize(this.pointer); - delete __stmtMap.get(this.db)[this.pointer]; + const rc = (__doesNotOwnHandle.delete(this) + ? 0 + : capi.sqlite3_finalize(ptr)); + delete __stmtMap.get(this.db)[ptr]; __ptrMap.delete(this); __execLock.delete(this); __stmtMayGet.delete(this); @@ -2134,6 +2251,60 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ set: ()=>toss3("The columnCount property is read-only.") }); + Object.defineProperty(Stmt.prototype, 'parameterCount', { + enumerable: false, + get: function(){return capi.sqlite3_bind_parameter_count(this.pointer)}, + set: ()=>toss3("The parameterCount property is read-only.") + }); + + /** + The Stmt counterpart of oo1.DB.wrapHandle(), this creates a Stmt + instance which wraps a WASM (sqlite3_stmt*) in the oo1 API with + or without taking over ownership of that pointer. + + The first argument must be an oo1.DB instance[^1]. + + The second argument must be a valid WASM (sqlite3_stmt*), as + produced by sqlite3_prepare_v2() and sqlite3_prepare_v3(). + + The third argument specifies whether the returned Stmt object + takes over ownership of the underlying (sqlite3_stmt*). If true, + the returned object's finalize() method will finalize that + handle, else it will not. If it is false, ownership of stmtPtr is + unchanged and stmtPtr MUST outlive the returned object or results + are undefined. + + This function throws if the arguments are invalid. On success it + returns a new Stmt object which wraps the given statement + pointer. + + Like all Stmt objects, the finalize() method must eventually be + called on the returned object to free up internal resources, + regardless of whether this function's third argument is true or + not. + + [^1]: The first argument cannot be a (sqlite3*) because the + resulting Stmt object requires a parent DB object. It is not yet + determined whether it would be of general benefit to refactor the + DB/Stmt pair internals to communicate in terms of the underlying + (sqlite3*) rather than a DB object. If so, we could laxen the + first argument's requirement and allow an (sqlite3*). + */ + Stmt.wrapHandle = function(oo1db, stmtPtr, takeOwnership=false){ + let ctor = Stmt; + if( !(oo1db instanceof DB) || !oo1db.pointer ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "First argument must be an opened "+ + "sqlite3.oo1.DB instance"); + } + if( !stmtPtr || !wasm.isPtr(stmtPtr) ){ + throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, + "Second argument must be a WASM "+ + "sqlite3_stmt pointer"); + } + return new Stmt(oo1db, stmtPtr, BindTypes, !!takeOwnership); + } + /** The OO API's public namespace. */ sqlite3.oo1 = { DB, diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 5b94c7c05e..446437eef8 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -41,7 +41,7 @@ ES6 worker module build: - ./c-pp -f tester1.c-pp.js -o tester1-esm.js -Dtarget=es6-module + ./c-pp -f tester1.c-pp.js -o tester1-esm.mjs -Dtarget=es6-module */ //#if target=es6-module import {default as sqlite3InitModule} from './jswasm/sqlite3.mjs'; @@ -1209,6 +1209,94 @@ globalThis.sqlite3InitModule = sqlite3InitModule; } } }) + + //////////////////////////////////////////////////////////////////// + .t({ + name: "oo1.DB/Stmt.wrapDbHandle()", + test: function(sqlite3){ + /* Maintenance reminder: this function is early in the list to + demonstrate that the wrappers for this.db created by this + function do not interfere with downstream tests, e.g. by + closing this.db.pointer. */ + sqlite3.config.debug("Proxying",this.db); + let dw = sqlite3.oo1.DB.wrapHandle(this.db); + sqlite3.config.debug('dw',dw); + T.assert( dw, '!!dw' ) + .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) + .assert( dw.pointer, 'dw.pointer' ) + .assert( dw.pointer === this.db.pointer, 'dw.pointer===db.pointer' ) + .assert( dw.filename === this.db.filename, 'dw.filename===db.filename' ); + + T.assert( dw === dw.exec("select 1") ); + let q; + try { + q = dw.prepare("select 1"); + T.assert( q.step() ) + .assert( !q.step() ); + }finally{ + if( q ) q.finalize(); + } + dw.close(); + T.assert( !dw.pointer ) + .assert( this.db === this.db.exec("select 1") ); + dw = undefined; + + let pDb = 0, pStmt = 0; + const stack = wasm.pstack.pointer; + try { + const ppOut = wasm.pstack.allocPtr(); + T.assert( 0===wasm.peekPtr(ppOut) ); + let rc = capi.sqlite3_open_v2( ":memory:", ppOut, + capi.SQLITE_OPEN_CREATE + | capi.SQLITE_OPEN_READWRITE, + 0); + T.assert( 0===rc, 'open_v2()' ); + pDb = wasm.peekPtr(ppOut); + wasm.pokePtr(ppOut, 0); + T.assert( pDb>0, 'pDb>0' ); + const pTmp = pDb; + dw = sqlite3.oo1.DB.wrapHandle(pDb, true); + pDb = 0; + //sqlite3.config.debug("dw",dw); + T.assert( pTmp===dw.pointer, 'pDb===dw.pointer' ); + T.assert( dw.filename === "", "dw.filename == "+dw.filename ); + let q = dw.prepare("select 1"); + try { + T.assert( q.step(), "step()" ); + T.assert( !q.step(), "!step()" ); + }finally{ + q.finalize(); + q = undefined; + } + T.assert( dw===dw.exec("select 1") ); + dw.affirmOpen(); + rc = capi.sqlite3_prepare_v2( dw, "select 1", -1, ppOut, 0 ); + T.assert( 0===rc, 'prepare_v2() rc='+rc ); + pStmt = wasm.peekPtr(ppOut); + try { + q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, false); + T.assert( q.step(), "step()" ) + .assert( !q.step(), "!step()" ); + q.finalize(); + q = undefined; + q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, true); + pStmt = 0; + q.reset(); + T.assert( q.step(), "step()" ) + .assert( !q.step(), "!step()" ); + }finally{ + if( pStmt ) capi.sqlite3_finalize(pStmt) + if( q ) q.finalize(); + } + + }finally{ + wasm.pstack.restore(stack); + if( pDb ){ capi.sqlite3_close_v2(pDb); } + else if( dw ){ dw.close(); } + } + } + })/*oo1.DB/Stmt.wrapHandle()*/ + //////////////////////////////////////////////////////////////////// .t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){ let rc = capi.sqlite3_db_config(this.db, capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, 0, 0); diff --git a/manifest b/manifest index 423c865285..b818c61644 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s'reconfigure'\starget\sto\sMakefile.in\sto\sre-run\sthe\sconfigure\sscript\swith\sthe\ssame\sflags\sit\swas\sgenerated\swith. -D 2025-07-04T18:32:18.912 +C Experimentally\sadd\ssqlite3.oo1.DB/Stmt.wrapHandle(),\swhich\sallow\sDB/Stmt\sinstances\sto\swrap\sa\s(sqlite3*)/(sqlite3_stmt*)\soptionally\swith\sor\swithout\staking\sownership\sof\sit.\sThe\sintent\sis\sto\senable\smix-and-match\suse\sof\sthe\sC\sAPI,\sthe\soo1\sAPI,\sand\sany\sother\shypothetical\sAPI\swhich\sexposes\sthose\spointers.\soo1.Stmt.parameterCount\sis\snow\sa\sproperty\saccess\sinterceptor\slike\sStmt.columnCount\sis,\sbut\sthat\sdoesn't\schange\show\sit's\sused. +D 2025-07-06T15:01:44.333 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js c68d6da0088c2527156fca9163a721abe08e7bd077b15404fd8d292f4612adc1 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 44d122b6d22ba9caa644193357a03bf5d2678a7815f1e2bbbdb086b14db11b7e F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 766a2ba51a2619d41a49be7c6a1ad014c1d23fc97b67496e4f103038203eb17d +F ext/wasm/tester1.c-pp.js e7176b2bc1228cf9a87833be7e53e20cb82dec2f104525f5cdd6cb1a53998ad6 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 -R 2e84b390408477c8e70efdd22e84c169 +P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +R 23984087c5c98e4f1ed7d33ca211546f +T *branch * oo1-unowned-handles +T *sym-oo1-unowned-handles * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z a6be9728f4a0aec0de70108286e76b7e +Z 3bad3f183e619bbd50d1bebd9118b331 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 08e4c43bce..f6dbdc594c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 From 787f4c3f09d00e79c04822a99fd9a03f7878e959 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:13:06 +0000 Subject: [PATCH 44/88] JS doc additions. FossilOrigin-Name: 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 35 ++++++++++++++++------------ manifest | 15 +++++------- manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 91d8bc544d..13ca9a4bdf 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -533,7 +533,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - if( arguments.length>3 && false===arguments[3] ){ + if( arguments.length>3 && !!arguments[3] ){ __doesNotOwnHandle.add(this); } }; @@ -728,10 +728,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }, /** Finalizes all open statements and closes this database - connection. This is a no-op if the db has already been - closed. After calling close(), `this.pointer` will resolve to - `undefined`, so that can be used to check whether the db - instance is still opened. + connection (with one exception noted below). This is a no-op if + the db has already been closed. After calling close(), + `this.pointer` will resolve to `undefined`, and that can be + used to check whether the db instance is still opened. If this.onclose.before is a function then it is called before any close-related cleanup. @@ -751,6 +751,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ all, will never trigger close(), so onclose handlers are not a reliable way to implement close-time cleanup or maintenance of a db. + + If this instance was created using DB.wrapHandle() and does not + own this.pointer then it does not close the db handle but it + does perform all other work, such as calling onclose callbacks + and disassociating this object from this.pointer. */ close: function(){ const pDb = this.pointer; @@ -1491,10 +1496,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ The first argument must be either a non-NULL (sqlite3*) WASM pointer or a non-close()d instance of oo1.DB. - The second argument only applies if the first argument is a - (sqlite3*). If it is, the returned object will pass that pointer - to sqlite3_close() when its close() method is called, otherwise - it will not. + The second argument, defaulting to false, only applies if the + first argument is a (sqlite3*). If it is, the returned object + will pass that pointer to sqlite3_close() when its close() method + is called, otherwise it will not. If the first argument is a oo1.DB object, the second argument is disregarded and the returned object will be created as a @@ -2267,12 +2272,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ The second argument must be a valid WASM (sqlite3_stmt*), as produced by sqlite3_prepare_v2() and sqlite3_prepare_v3(). - The third argument specifies whether the returned Stmt object - takes over ownership of the underlying (sqlite3_stmt*). If true, - the returned object's finalize() method will finalize that - handle, else it will not. If it is false, ownership of stmtPtr is - unchanged and stmtPtr MUST outlive the returned object or results - are undefined. + The third argument, defaulting to false, specifies whether the + returned Stmt object takes over ownership of the underlying + (sqlite3_stmt*). If true, the returned object's finalize() method + will finalize that handle, else it will not. If it is false, + ownership of stmtPtr is unchanged and stmtPtr MUST outlive the + returned object or results are undefined. This function throws if the arguments are invalid. On success it returns a new Stmt object which wraps the given statement diff --git a/manifest b/manifest index b818c61644..5299e9d5a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimentally\sadd\ssqlite3.oo1.DB/Stmt.wrapHandle(),\swhich\sallow\sDB/Stmt\sinstances\sto\swrap\sa\s(sqlite3*)/(sqlite3_stmt*)\soptionally\swith\sor\swithout\staking\sownership\sof\sit.\sThe\sintent\sis\sto\senable\smix-and-match\suse\sof\sthe\sC\sAPI,\sthe\soo1\sAPI,\sand\sany\sother\shypothetical\sAPI\swhich\sexposes\sthose\spointers.\soo1.Stmt.parameterCount\sis\snow\sa\sproperty\saccess\sinterceptor\slike\sStmt.columnCount\sis,\sbut\sthat\sdoesn't\schange\show\sit's\sused. -D 2025-07-06T15:01:44.333 +C JS\sdoc\sadditions. +D 2025-07-06T15:13:06.902 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 44d122b6d22ba9caa644193357a03bf5d2678a7815f1e2bbbdb086b14db11b7e +F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc3b30cefa93e6dd9f2b827e31acacbfc2acd522d5ca4d46e977dacc4261398f F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 -R 23984087c5c98e4f1ed7d33ca211546f -T *branch * oo1-unowned-handles -T *sym-oo1-unowned-handles * -T -sym-trunk * Cancelled\sby\sbranch. +P 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 +R cef3ddc9e77c9bf23d0de246f8a430aa U stephan -Z 3bad3f183e619bbd50d1bebd9118b331 +Z 86c577d4430c4b03afa5e02f4812dc59 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f6dbdc594c..a50c65454f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 +7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 From 240319decde8af8fc4d0896d7138c7ca282627ea Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 6 Jul 2025 15:36:28 +0000 Subject: [PATCH 45/88] Remove some dead JS code and some extraneous debug output from test code. FossilOrigin-Name: 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 10 +++------- ext/wasm/tester1.c-pp.js | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 13ca9a4bdf..cc4c9bb287 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -429,7 +429,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - `vfs`: the VFS fname //#if enable-see - SEE-capable builds optionally support ONE of the following additional options: @@ -455,7 +454,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ is supplied and the database is encrypted, execution of the post-initialization SQL will fail, causing the constructor to throw. - //#endif enable-see The `filename` and `vfs` arguments may be either JS strings or @@ -483,8 +481,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** Internal-use enum for mapping JS types to DB-bindable types. These do not (and need not) line up with the SQLITE_type - values. All values in this enum must be truthy and distinct - but they need not be numbers. + values. All values in this enum must be truthy and (mostly) + distinct but they need not be numbers. */ const BindTypes = { null: 1, @@ -493,7 +491,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ boolean: 4, blob: 5 }; - BindTypes['undefined'] == BindTypes.null; if(wasm.bigIntEnabled){ BindTypes.bigint = BindTypes.number; } @@ -1589,8 +1586,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ case BindTypes.string: return t; case BindTypes.bigint: - if(wasm.bigIntEnabled) return t; - /* else fall through */ + return wasm.bigIntEnabled ? t : undefined; default: return util.isBindableTypedArray(v) ? BindTypes.blob : undefined; } diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 446437eef8..824b6081da 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1218,9 +1218,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; demonstrate that the wrappers for this.db created by this function do not interfere with downstream tests, e.g. by closing this.db.pointer. */ - sqlite3.config.debug("Proxying",this.db); + //sqlite3.config.debug("Proxying",this.db); let dw = sqlite3.oo1.DB.wrapHandle(this.db); - sqlite3.config.debug('dw',dw); + //sqlite3.config.debug('dw',dw); T.assert( dw, '!!dw' ) .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) .assert( dw.pointer, 'dw.pointer' ) diff --git a/manifest b/manifest index 5299e9d5a5..7a3bb87723 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C JS\sdoc\sadditions. -D 2025-07-06T15:13:06.902 +C Remove\ssome\sdead\sJS\scode\sand\ssome\sextraneous\sdebug\soutput\sfrom\stest\scode. +D 2025-07-06T15:36:28.567 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc3b30cefa93e6dd9f2b827e31acacbfc2acd522d5ca4d46e977dacc4261398f +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 33203352e067d3dbb569c5ec3c247b356f61a8d320bf8551fdf18ff25c0ff862 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js e7176b2bc1228cf9a87833be7e53e20cb82dec2f104525f5cdd6cb1a53998ad6 +F ext/wasm/tester1.c-pp.js b99d18fe8803215664a3b53af451d11e2573682a2c8973bcd28ce574c497393b F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1227543b87c3320d6b80e0f61b88ea53b68779966a0295c4d6a1db6369c48207 -R cef3ddc9e77c9bf23d0de246f8a430aa +P 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 +R 7f815f9b4c7a2aabd4a38289c5be858a U stephan -Z 86c577d4430c4b03afa5e02f4812dc59 +Z d14be01d18ce30e04a958bfca48cc223 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a50c65454f..eee638be6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 +6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 From 084046068949dfaeaae71ce4fe9cdbe5ccb24db4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 7 Jul 2025 02:18:27 +0000 Subject: [PATCH 46/88] Fix parser error introduced by [325e547a2195571e]. See [forum:/forumpost/095dbfc06e5b1f7e|forum post 095dbfc06e5]. FossilOrigin-Name: 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tokenize.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 423c865285..c3bcb089c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s'reconfigure'\starget\sto\sMakefile.in\sto\sre-run\sthe\sconfigure\sscript\swith\sthe\ssame\sflags\sit\swas\sgenerated\swith. -D 2025-07-04T18:32:18.912 +C Fix\sparser\serror\sintroduced\sby\s[325e547a2195571e].\s\sSee\n[forum:/forumpost/095dbfc06e5b1f7e|forum\spost\s095dbfc06e5]. +D 2025-07-07T02:18:27.401 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -844,7 +844,7 @@ F src/test_vfs.c b4135c1308516adf0dfd494e6d6c33114e03732be899eace0502919b674586b F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 3e37ac2b6cbb9b0abe33827b0153c27595269afd7152b48019808974481aca2c +F src/tokenize.c 8400646d2830afc2f2dc465a75e3a92e4bedeea623f19dbd79c0c12d0dd6dda2 F src/treeview.c d85ce76e6d1498d781957c07cb234da6d77ce0ed2d196480d516f54dabc62279 F src/trigger.c 3ffb8ed6b64dbcc0ccae6e82435d01be3bf547e13b814e2d46f7df9bef84748e F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501 -R 2e84b390408477c8e70efdd22e84c169 -U stephan -Z a6be9728f4a0aec0de70108286e76b7e +P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +R 9751f5fd5db45dc9854f3e80aaabd1b6 +U drh +Z 4f27d9f9c6c0d2b5f41153ee565cb8ec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 08e4c43bce..387609d24f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 +4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 diff --git a/src/tokenize.c b/src/tokenize.c index e4d9f53718..6f7bab35bc 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -199,7 +199,7 @@ static int getToken(const unsigned char **pz){ int t; /* Token type to return */ do { z += sqlite3GetToken(z, &t); - }while( t==TK_SPACE ); + }while( t==TK_SPACE || t==TK_COMMENT ); if( t==TK_ID || t==TK_STRING || t==TK_JOIN_KW From 4aacd1ef8eff53662b827e920d2c7d5d46833b9d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 7 Jul 2025 10:54:00 +0000 Subject: [PATCH 47/88] Back out the fix at [ba7d5bad32ad6aac] because it does not always work and because it causes a performance regression. Add new test cases for row-value lookups of indexes that contain redundant columns, three of which are currently failing. This branch is seeking an improved solution to the redundant index column problem for row-value lookups. FossilOrigin-Name: ad8ddcefab5cc526b1cd77731e00939c672e61ca83350d28961b67635d20da03 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/build.c | 1 - src/sqliteInt.h | 1 - src/where.c | 2 +- test/rowvalue.test | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c3bcb089c2..b603fd257b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sparser\serror\sintroduced\sby\s[325e547a2195571e].\s\sSee\n[forum:/forumpost/095dbfc06e5b1f7e|forum\spost\s095dbfc06e5]. -D 2025-07-07T02:18:27.401 +C Back\sout\sthe\sfix\sat\s[ba7d5bad32ad6aac]\sbecause\sit\sdoes\snot\salways\swork\sand\sbecause\nit\scauses\sa\sperformance\sregression.\s\sAdd\snew\stest\scases\sfor\srow-value\slookups\sof\nindexes\sthat\scontain\sredundant\scolumns,\sthree\sof\swhich\sare\scurrently\sfailing.\s\sThis\nbranch\sis\sseeking\san\simproved\ssolution\sto\sthe\sredundant\sindex\scolumn\sproblem\sfor\nrow-value\slookups. +D 2025-07-07T10:54:00.314 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -729,7 +729,7 @@ F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea F src/btree.c 783f9999f9ca56846619ba902f5970e181d897c23cc923c915fef225af6dda8a F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 -F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f +F src/build.c 67159d31bfc565e5f23a7be8159325bae599bddd19fc584ac2511b947cf341d3 F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 @@ -790,7 +790,7 @@ F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h 005542f8760edf9b62f014abccb876cf64533b64475a40a89402054d62535288 +F src/sqliteInt.h 72bf74887e551d8adf0140bf20fbc321fda7f3cef2c6dc0c5aeefa584cd713a1 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -867,7 +867,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c f58d41d0923eeb21cab8e4fc87a0b36c0724ff4f279ce95ab2731b4696b8e75a +F src/where.c da2ad25987070bc28722f115d5bd6cfb0c12331f351d7334ed51dab66841184d F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 F src/whereexpr.c d007dc41364de5902181739632380afd671e14f0c5cc9978e64a2c6df8f28c6c @@ -1576,7 +1576,7 @@ F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190c F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test d27191b5ce794c05bf61081e8b2c546a1844c1641321dcaf7fb785234256cc8e -F test/rowvalue.test 9c873b2f6e7ce72b24ef133f93515c07a6a7dac4846a344ebc2af7b8bfdf5147 +F test/rowvalue.test dfc4c7004779d24d037644ce9d8e252a83042b1fb51b913ea5f833ccab241940 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 103e9a224ca0548dd0d67e439f39c5dd16de4200221a333927372408c025324c F test/rowvalue4.test bac9326d1e886656650f67c0ec484eb5f452244a8209c6af508e9a862ace08ed @@ -2208,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 -R 9751f5fd5db45dc9854f3e80aaabd1b6 +P 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 +R 18dc3afff00dcbf730d14200fa0306d6 +T *branch * redundant-idx-columns +T *sym-redundant-idx-columns * +T -sym-trunk * U drh -Z 4f27d9f9c6c0d2b5f41153ee565cb8ec +Z 32126d38005c3356359df43f9f9d9144 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 387609d24f..0bb10a5058 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 +ad8ddcefab5cc526b1cd77731e00939c672e61ca83350d28961b67635d20da03 diff --git a/src/build.c b/src/build.c index 5bd3aac3ca..27d7b499df 100644 --- a/src/build.c +++ b/src/build.c @@ -4219,7 +4219,6 @@ void sqlite3CreateIndex( assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; - pIndex->bIdxRowid = 1; }else{ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 36a21d92ef..a05cf75ad1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2808,7 +2808,6 @@ struct Index { unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ - unsigned bIdxRowid:1; /* One or more of the index keys is the ROWID */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ diff --git a/src/where.c b/src/where.c index ddf3f74996..6a195dd2dd 100644 --- a/src/where.c +++ b/src/where.c @@ -3479,7 +3479,7 @@ static int whereLoopAddBtreeIndex( if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEqnColumn && (pNew->u.btree.nEqnKeyCol || - (pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY && !pProbe->bIdxRowid)) + pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) ){ if( pNew->u.btree.nEq>3 ){ sqlite3ProgressCheck(pParse); diff --git a/test/rowvalue.test b/test/rowvalue.test index e2688e9030..a4c021deb7 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -804,5 +804,39 @@ do_execsql_test 34.1 { WHERE (Id, Item) IN (SELECT Id, Item FROM items); SELECT Id, Item, test FROM items ORDER BY id; } {1 2 ok 2 2 ok 3 3 ok 4 5 ok} +db null NULL +do_execsql_test 34.2 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); + CREATE INDEX idx ON t1(b,a); + INSERT INTO t1(a,b) VALUES (1, 22); + SELECT * FROM t1 INDEXED BY idx WHERE (b,a) IN (SELECT b,a FROM t1); +} {1 22 NULL NULL} +do_execsql_test 34.3 { + DROP TABLE t1; + CREATE TABLE t1(a, b, c, d); + CREATE INDEX idx ON t1(b,a,a); + INSERT INTO t1(a,b) VALUES (1, 22); + SELECT * FROM t1 INDEXED BY idx WHERE (b,a) IN (SELECT b,a FROM t1); +} {1 22 NULL NULL} +do_execsql_test 34.4 { + DROP TABLE t1; + CREATE TABLE t1(id INTEGER PRIMARY KEY, a INT); + CREATE INDEX t1a ON t1(a,id); -- index includes PRIMARY KEY + CREATE TABLE t2(id INTEGER PRIMARY KEY); + WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<100) + INSERT INTO t1(id,a) SELECT n, 777 FROM c; + INSERT INTO t2 SELECT id FROM t1; + SELECT * + FROM t1 JOIN t2 USING(id) + WHERE t1.a=777 AND t2.id>999 + ORDER BY t1.id; +} {} +do_execsql_test 34.5 { + EXPLAIN QUERY PLAN + SELECT * + FROM t1 JOIN t2 USING(id) + WHERE t1.a=777 AND t2.id>999 + ORDER BY t1.id; +} {/SEARCH t1 USING COVERING INDEX t1a .a=. AND id>../} finish_test From 8504d37b99002d8bc0466c401ed441274f5557f7 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 7 Jul 2025 11:37:55 +0000 Subject: [PATCH 48/88] Avoid invoking the preupdate hook from within sqlite3_blob_write() if the cursor is already invalid. FossilOrigin-Name: 9f335b9a4e9e761a0c6afd6dc69665a24506141bde88530bf59fcbdf957ae881 --- manifest | 16 ++++---- manifest.uuid | 2 +- src/vdbeblob.c | 33 +++++++++++----- test/incrblob4.test | 91 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c3bcb089c2..696aaba121 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sparser\serror\sintroduced\sby\s[325e547a2195571e].\s\sSee\n[forum:/forumpost/095dbfc06e5b1f7e|forum\spost\s095dbfc06e5]. -D 2025-07-07T02:18:27.401 +C Avoid\sinvoking\sthe\spreupdate\shook\sfrom\swithin\ssqlite3_blob_write()\sif\sthe\scursor\sis\salready\sinvalid. +D 2025-07-07T11:37:55.009 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -857,7 +857,7 @@ F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7 -F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd +F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692 F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21 F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 @@ -1315,7 +1315,7 @@ F test/in7.test d9efdee00b074a60c6343993b2eda78bc369ab080dad864513c73f8aca89d566 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f -F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba +F test/incrblob4.test 10f4537febe1774c02f8d490d393322b4a50898d4027868b67055e9c3adc22db F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9 F test/incrblobfault.test de274b1e329169c2c3438f9528994807ea8201ebf38ae9f157d34bf3ec0cc549 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01 -R 9751f5fd5db45dc9854f3e80aaabd1b6 -U drh -Z 4f27d9f9c6c0d2b5f41153ee565cb8ec +P 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 +R 8dd2c3d3469e31d78df8ad758ebdebcb +U dan +Z 1af57e86c85e1876b1c7c9bf1cb0169c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 387609d24f..843f258736 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 +9f335b9a4e9e761a0c6afd6dc69665a24506141bde88530bf59fcbdf957ae881 diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 42edcf7de8..a15fec6c48 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -385,7 +385,7 @@ static int blobReadWrite( int iOffset, int (*xCall)(BtCursor*, u32, u32, void*) ){ - int rc; + int rc = SQLITE_OK; Incrblob *p = (Incrblob *)pBlob; Vdbe *v; sqlite3 *db; @@ -425,17 +425,32 @@ static int blobReadWrite( ** using the incremental-blob API, this works. For the sessions module ** anyhow. */ - sqlite3_int64 iKey; - iKey = sqlite3BtreeIntegerKey(p->pCsr); - assert( v->apCsr[0]!=0 ); - assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); - sqlite3VdbePreUpdateHook( - v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol - ); + if( sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ){ + /* If the cursor is not currently valid, try to reseek it. This + ** always either fails or finds the correct row - the cursor will + ** have been marked permanently CURSOR_INVALID if the open row has + ** been deleted. */ + int bDiff = 0; + rc = sqlite3BtreeCursorRestore(p->pCsr, &bDiff); + assert( bDiff==0 || sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ); + } + if( sqlite3BtreeCursorIsValidNN(p->pCsr) ){ + sqlite3_int64 iKey; + iKey = sqlite3BtreeIntegerKey(p->pCsr); + assert( v->apCsr[0]!=0 ); + assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); + sqlite3VdbePreUpdateHook( + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol + ); + } } + if( rc==SQLITE_OK ){ + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); + } +#else + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); #endif - rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); sqlite3BtreeLeaveCursor(p->pCsr); if( rc==SQLITE_ABORT ){ sqlite3VdbeFinalize(v); diff --git a/test/incrblob4.test b/test/incrblob4.test index dbff8eb7d5..31040e91b4 100644 --- a/test/incrblob4.test +++ b/test/incrblob4.test @@ -106,4 +106,95 @@ do_test 4.4 { } {SQLITE_LOCKED} close $blob +#------------------------------------------------------------------------- + +reset_db +do_execsql_test 5.1 { + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + INSERT INTO t2 VALUES(1000, 'abcdefghijklmnopqrstuvwxyz'); + INSERT INTO t2 VALUES(2000, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + INSERT INTO t2 VALUES(3000, 'abcdefghijklmnopqrstuvwxyz'); +} + +do_test 5.2.1 { + execsql BEGIN + set blob [db incrblob t2 b 2000] + seek $blob 0 + puts -nonewline $blob "hello " + flush $blob + execsql ROLLBACK +} {} + +do_test 5.2.2 { + puts -nonewline $blob "world" + list [catch { flush $blob } msg] $msg +} "1 {error flushing \"$blob\": I/O error}" +catch { close $blob } + +set preupdate_count 0 +proc preupdate {args} { incr ::preupdate_count ; return {} } +db preupdate hook preupdate + +set preupdate_count 0 +do_test 5.3.1 { + execsql BEGIN + set blob [db incrblob t2 b 1000] + seek $blob 0 + puts -nonewline $blob "hello " + flush $blob + execsql ROLLBACK +} {} + +do_test 5.3.2 { + puts -nonewline $blob "world" + list [catch { flush $blob } msg] $msg +} "1 {error flushing \"$blob\": I/O error}" +catch { close $blob } + +do_test 5.3.3 { + set ::preupdate_count +} {1} + +set preupdate_count 0 +do_test 5.4.1 { + execsql BEGIN + set blob [db incrblob t2 b 1000] + seek $blob 0 + puts -nonewline $blob "hello " + flush $blob + execsql { DELETE FROM t2 WHERE a=3000; } +} {} + +do_test 5.4.2 { + puts -nonewline $blob "world" + list [catch { flush $blob } msg] $msg +} "0 {}" +catch { close $blob } +catchsql { ROLLBACK } + +do_test 5.3.3 { + set ::preupdate_count +} {3} + +set preupdate_count 0 +do_test 5.4.3 { + execsql BEGIN + set blob [db incrblob t2 b 2000] + seek $blob 0 + puts -nonewline $blob "hello " + flush $blob + execsql { UPDATE t2 SET b='abcdefghijklmnopqrstuvwxyz' WHERE a=2000 } +} {} + +do_test 5.4.4 { + puts -nonewline $blob "world" + list [catch { flush $blob } msg] $msg +} "1 {error flushing \"$blob\": I/O error}" +catch { close $blob } +catchsql { ROLLBACK } + +do_test 5.3.3 { + set ::preupdate_count +} {2} + finish_test From 24d290e7b0373b0b0749a0ac32d16bc42d462e60 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 7 Jul 2025 12:11:26 +0000 Subject: [PATCH 49/88] Work around the Emscripten 4.10 regression described in [https://github.com/emscripten-core/emscripten/issues/24656 | Emscripten ticket #24656]. Problem reported off-list by BrickViking. FossilOrigin-Name: c385475b250f3364507a95c5832137098a9bb7c7fc12ab3bb116e1fad7bb7645 --- ext/wasm/fiddle.make | 3 +-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index 8110384a6e..5b1eb5e778 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -40,9 +40,8 @@ fiddle.emcc-flags = \ -sWASM_BIGINT=$(emcc.WASM_BIGINT) \ -sEXPORT_NAME=$(sqlite3.js.init-func) \ -Wno-limited-postlink-optimizations \ - $(emcc.exportedRuntimeMethods) \ + $(emcc.exportedRuntimeMethods),FS \ -sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \ - -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \ $(SQLITE_OPT.full-featured) \ $(SQLITE_OPT.common) \ $(SHELL_OPT) \ diff --git a/manifest b/manifest index 696aaba121..5559239615 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinvoking\sthe\spreupdate\shook\sfrom\swithin\ssqlite3_blob_write()\sif\sthe\scursor\sis\salready\sinvalid. -D 2025-07-07T11:37:55.009 +C Work\saround\sthe\sEmscripten\s4.10\sregression\sdescribed\sin\s[https://github.com/emscripten-core/emscripten/issues/24656\s|\sEmscripten\sticket\s#24656].\sProblem\sreported\soff-list\sby\sBrickViking. +D 2025-07-07T12:11:26.315 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -674,7 +674,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 08720227e98fa5b44761cf6e219269cee3e9dd0421d8d91459535da776950314 F ext/wasm/dist.make 92ef4ffe33022a50f92d602acabad10bd8dd91759f3eb7df27fc6d7d37072b96 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make c6d7a3d6cc03bb5f21acb295c1233820d0dbf5c6a89b28dc2e093edcc001c45a +F ext/wasm/fiddle.make 2df87f12bcbae2c966c2cef34ce71bb1584c440c69e14ca6d32f443d8d550dc5 F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js 2a2f27b4be2674f501fff61c4a09e44dcf2295731a26b5c28e439f3a573bd269 F ext/wasm/fiddle/index.html 7fcfb221165183bef0e05d5af9ceb79b527e799b1708ab05de0ec0eaebd5b7bf @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 -R 8dd2c3d3469e31d78df8ad758ebdebcb -U dan -Z 1af57e86c85e1876b1c7c9bf1cb0169c +P 9f335b9a4e9e761a0c6afd6dc69665a24506141bde88530bf59fcbdf957ae881 +R 027d046a8c80c08284dcaad6a9d57a24 +U stephan +Z c407d0bb15707ac8be6028e01680c96c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 843f258736..eeb7056dd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f335b9a4e9e761a0c6afd6dc69665a24506141bde88530bf59fcbdf957ae881 +c385475b250f3364507a95c5832137098a9bb7c7fc12ab3bb116e1fad7bb7645 From 4fe1ac8fe1c3831588ae2ad1f8ea0841b11523ab Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 7 Jul 2025 15:40:53 +0000 Subject: [PATCH 50/88] Simplifications to the row-value IN operator logic. Do not let the query planner accept a WhereLoop for a row-value IN operator that uses the same index column more than once. FossilOrigin-Name: d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12 --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/where.c | 16 +++++++++++++++- src/wherecode.c | 25 ++++++++----------------- test/rowvalue.test | 3 +++ 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index b603fd257b..82932a507d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\sthe\sfix\sat\s[ba7d5bad32ad6aac]\sbecause\sit\sdoes\snot\salways\swork\sand\sbecause\nit\scauses\sa\sperformance\sregression.\s\sAdd\snew\stest\scases\sfor\srow-value\slookups\sof\nindexes\sthat\scontain\sredundant\scolumns,\sthree\sof\swhich\sare\scurrently\sfailing.\s\sThis\nbranch\sis\sseeking\san\simproved\ssolution\sto\sthe\sredundant\sindex\scolumn\sproblem\sfor\nrow-value\slookups. -D 2025-07-07T10:54:00.314 +C Simplifications\sto\sthe\srow-value\sIN\soperator\slogic.\s\sDo\snot\slet\sthe\squery\nplanner\saccept\sa\sWhereLoop\sfor\sa\srow-value\sIN\soperator\sthat\suses\sthe\ssame\nindex\scolumn\smore\sthan\sonce. +D 2025-07-07T15:40:53.150 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -867,9 +867,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c da2ad25987070bc28722f115d5bd6cfb0c12331f351d7334ed51dab66841184d +F src/where.c 21b768d47fe28aafc7607a97228c261d7ccdca5cd2bff2221418566ca608e2c5 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da -F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45 +F src/wherecode.c ce9e2311186c14ef0f3a56bdc243f17f8bd43de70bd79841fe13ee8db0cd9ffa F src/whereexpr.c d007dc41364de5902181739632380afd671e14f0c5cc9978e64a2c6df8f28c6c F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1576,7 +1576,7 @@ F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190c F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test d27191b5ce794c05bf61081e8b2c546a1844c1641321dcaf7fb785234256cc8e -F test/rowvalue.test dfc4c7004779d24d037644ce9d8e252a83042b1fb51b913ea5f833ccab241940 +F test/rowvalue.test 8a3f0fea3a3cbbfc7cb9885b76185a774cd8d891e0c133e289567c755d39eb9f F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 103e9a224ca0548dd0d67e439f39c5dd16de4200221a333927372408c025324c F test/rowvalue4.test bac9326d1e886656650f67c0ec484eb5f452244a8209c6af508e9a862ace08ed @@ -2208,11 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39 -R 18dc3afff00dcbf730d14200fa0306d6 -T *branch * redundant-idx-columns -T *sym-redundant-idx-columns * -T -sym-trunk * +P ad8ddcefab5cc526b1cd77731e00939c672e61ca83350d28961b67635d20da03 +R 5a92e17b8b464622bfef81f8d59225e0 U drh -Z 32126d38005c3356359df43f9f9d9144 +Z d89bb9ed1d7ca89fa0bfcdcb21412c8b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0bb10a5058..bc807743f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad8ddcefab5cc526b1cd77731e00939c672e61ca83350d28961b67635d20da03 +d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12 diff --git a/src/where.c b/src/where.c index 6a195dd2dd..5d80dd3d6c 100644 --- a/src/where.c +++ b/src/where.c @@ -3239,6 +3239,7 @@ static int whereLoopAddBtreeIndex( if( ExprUseXSelect(pExpr) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; + int bRedundant = 0; nIn = 46; assert( 46==sqlite3LogEst(25) ); /* The expression may actually be of the form (x, y) IN (SELECT...). @@ -3247,7 +3248,20 @@ static int whereLoopAddBtreeIndex( ** for each such term. The following loop checks that pTerm is the ** first such term in use, and sets nIn back to 0 if it is not. */ for(i=0; inLTerm-1; i++){ - if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){ + nIn = 0; + if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){ + /* Detect when two or more columns of an index match the same + ** column of a vector IN operater, and avoid adding the column + ** to the WhereLoop more than once. See tag-20250707-01 + ** in test/rowvalue.test */ + bRedundant = 1; + } + } + } + if( bRedundant ){ + pNew->nLTerm--; + continue; } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ diff --git a/src/wherecode.c b/src/wherecode.c index cc672aa839..eb508d9388 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -695,7 +695,7 @@ static SQLITE_NOINLINE void codeINTerm( return; } } - for(i=iEq;inLTerm; i++){ + for(i=iEq; inLTerm; i++){ assert( pLoop->aLTerm[i]!=0 ); if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; } @@ -704,22 +704,13 @@ static SQLITE_NOINLINE void codeINTerm( if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ - Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); - pExpr->iTable = iTab; - } - sqlite3ExprDelete(db, pX); - }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + sqlite3 *db = pParse->db; + Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); } - pX = pExpr; + sqlite3ExprDelete(db, pXMod); } if( eType==IN_INDEX_INDEX_DESC ){ @@ -749,7 +740,7 @@ static SQLITE_NOINLINE void codeINTerm( if( pIn ){ int iMap = 0; /* Index in aiMap[] */ pIn += i; - for(i=iEq;inLTerm; i++){ + for(i=iEq; inLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ int iOut = iTarget + i - iEq; if( eType==IN_INDEX_ROWID ){ diff --git a/test/rowvalue.test b/test/rowvalue.test index a4c021deb7..387780c453 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -788,6 +788,9 @@ do_execsql_test 33.3 { # INTEGER PRIMARY KEY, and the columns that UNIQUE constraint are # used in a rowvalue-IN operator constraint. # +# 2025-07-07 Discovered that the original fix was incomplete and +# new tests added. See tag-20250707-01 in the code. +# reset_db do_execsql_test 34.1 { CREATE TABLE items ( From 8c8443a38a69eafee4ef930cbfc2c07da4b78628 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 7 Jul 2025 19:03:50 +0000 Subject: [PATCH 51/88] Small performance optimization in the resolver. FossilOrigin-Name: 840646df0696706bd4dd7a04dfc8b16ad80c24cbcbc57a22c9e65a93cc17af2b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 974b081ab2..7ead8c5181 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\s\senhancements\sand\sfixes\sinto\sthe\sempty-table-optimizations\sbranch. -D 2025-07-07T18:35:51.568 +C Small\sperformance\soptimization\sin\sthe\sresolver. +D 2025-07-07T19:03:50.925 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -783,7 +783,7 @@ F src/pragma.c 30b535d0a66348df844ee36f890617b4cf45e9a22dcbc47ec3ca92909c50aaf1 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 5b14cad58bc21341fbaea76d7e781187559627a461745ece00c2655ba7c083ec +F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c b1d4e1f21a32b4f33d3bf02c4167ac8da5aafb97210a0b13a9119d68183db37d F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6b1ecbaa2ee405be040901dceac45d027d35c313622748ba4dbbd404e297a7fa 28db0d152d90fb5e62d03ea5caceabe8901be98522aef3dc2b54564fbc35355d -R 1ad2faf618cb852b453d45306c55c408 +P f15cdf07573c05276a13885d74bae21a93544766344f19ef939b7a69edd1073b +R 2636d63ee0b11ec41a4803b9ba60214d U drh -Z 725feec2e2e8168094856eb7acaf31d4 +Z f0a94ad32bbc71db6c95d4953159e88b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f4fafa7e7b..0533abe09d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f15cdf07573c05276a13885d74bae21a93544766344f19ef939b7a69edd1073b +840646df0696706bd4dd7a04dfc8b16ad80c24cbcbc57a22c9e65a93cc17af2b diff --git a/src/resolve.c b/src/resolve.c index bbd1021e0b..57ccd0c07a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1359,9 +1359,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: - assert( ExprUseXSelect(pExpr) ); - pParse->bHasExists = 1; - /* no break */ deliberate_fall_through case TK_SELECT: #endif case TK_IN: { @@ -1375,6 +1372,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); assert( pExpr->x.pSelect ); + if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1; if( pNC->ncFlags & NC_SelfRef ){ notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); }else{ From 7fc6e6a2726e650d3b82c6d3683bdbdc10e02467 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 7 Jul 2025 20:47:23 +0000 Subject: [PATCH 52/88] Only run preupdate-hook tests in incrblob4.test if the preupdate-hook is enabled in the build. FossilOrigin-Name: 56314b6b53c86ae131f780e20b62bdeabccba6d62dda41becc1c4b2e87cee07b --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/incrblob4.test | 6 +++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 48b10eebb7..7f408bbb67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rework\sthe\sfix\sto\sthe\sproblem\sdescribed\sby\n[forum:/forumpost/b9647a113b465950|forum\spost\sb9647a113b]\sso\sthat\sit\nprovides\sa\smore\scomplete\sfix\sthat\scovers\scases\sthat\swere\snot\sresolved\sby\nthe\soriginal\sfix,\sand\sso\sthat\sit\sdoes\snot\scause\sperformance\sregressions. -D 2025-07-07T16:19:44.166 +C Only\srun\spreupdate-hook\stests\sin\sincrblob4.test\sif\sthe\spreupdate-hook\sis\senabled\sin\sthe\sbuild. +D 2025-07-07T20:47:23.343 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1315,7 +1315,7 @@ F test/in7.test d9efdee00b074a60c6343993b2eda78bc369ab080dad864513c73f8aca89d566 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f -F test/incrblob4.test 10f4537febe1774c02f8d490d393322b4a50898d4027868b67055e9c3adc22db +F test/incrblob4.test 832045dda1148121a329bfb42abcca576b808e23a85cd3bedae9b7e1c89b3f1f F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9 F test/incrblobfault.test de274b1e329169c2c3438f9528994807ea8201ebf38ae9f157d34bf3ec0cc549 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a @@ -2208,9 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c385475b250f3364507a95c5832137098a9bb7c7fc12ab3bb116e1fad7bb7645 d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12 -R 82e9c3e3f384036ea2f7751db27154bc -T +closed d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12 -U drh -Z 1a6c8c788ec8f2b16f1cc6f88559d1db +P 28db0d152d90fb5e62d03ea5caceabe8901be98522aef3dc2b54564fbc35355d +R 1e194882c201aa8b6f5e945d6a9a2830 +U dan +Z 378fff7db2aa3a965f8f7be7342e2ca6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b06de79081..c2c2547e28 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28db0d152d90fb5e62d03ea5caceabe8901be98522aef3dc2b54564fbc35355d +56314b6b53c86ae131f780e20b62bdeabccba6d62dda41becc1c4b2e87cee07b diff --git a/test/incrblob4.test b/test/incrblob4.test index 31040e91b4..d6ffe6b654 100644 --- a/test/incrblob4.test +++ b/test/incrblob4.test @@ -108,6 +108,8 @@ close $blob #------------------------------------------------------------------------- +ifcapable preupdate { + reset_db do_execsql_test 5.1 { CREATE TABLE t2(a INTEGER PRIMARY KEY, b); @@ -193,8 +195,10 @@ do_test 5.4.4 { catch { close $blob } catchsql { ROLLBACK } -do_test 5.3.3 { +do_test 5.4.5 { set ::preupdate_count } {2} +} + finish_test From 925b79039cbed20ca8947b961530c64070b22829 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 8 Jul 2025 12:37:25 +0000 Subject: [PATCH 53/88] Fix test case results in FTS5 that were changed error message improvements in [48044a6b57c0a16c] but which were omitted from that check-in. FossilOrigin-Name: e1f8e0240b14f1338e947634e840af785e5042a09cd365975e922a13a562f4cd --- ext/fts5/test/fts5corrupt3.test | 5 ++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 66acf07ee3..eab4c3c913 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -6644,7 +6644,7 @@ do_test 48.0 { do_catchsql_test 48.1 { INSERT INTO t1(t1) VALUES('integrity-check'); -} {1 {database disk image is malformed}} +} {1 {fts5: corruption on page 1, segment 1, table "t1"}} #-------------------------------------------------------------------------- reset_db @@ -10106,7 +10106,7 @@ do_test 68.0 { do_catchsql_test 68.1 { PRAGMA reverse_unordered_selects=ON; INSERT INTO t1(t1) SELECT x FROM t2; -} {1 {database disk image is malformed}} +} {1 {fts5: corruption on page 1, segment 1, table "t1"}} #------------------------------------------------------------------------- reset_db @@ -16126,4 +16126,3 @@ do_catchsql_test 83.1 { sqlite3_fts5_may_be_corrupt 0 finish_test - diff --git a/manifest b/manifest index 7f408bbb67..8849616fcc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\srun\spreupdate-hook\stests\sin\sincrblob4.test\sif\sthe\spreupdate-hook\sis\senabled\sin\sthe\sbuild. -D 2025-07-07T20:47:23.343 +C Fix\stest\scase\sresults\sin\sFTS5\sthat\swere\schanged\serror\smessage\simprovements\nin\s[48044a6b57c0a16c]\sbut\swhich\swere\somitted\sfrom\sthat\scheck-in. +D 2025-07-08T12:37:25.996 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -162,7 +162,7 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b F ext/fts5/test/fts5contentless5.test 38cd0392c730dc7090c550321ce3c24ba4c392bc97308b51a4180e9959dca7b5 F ext/fts5/test/fts5corrupt.test 237fce1c3261bb3a5bec333b0f0dbf5b105ec32627ef14cccbda3cfe13833193 F ext/fts5/test/fts5corrupt2.test 4a03a158c2cb617c9f76d26b35c1ef2534124bc0bbddcea38dfd5b170ebea27b -F ext/fts5/test/fts5corrupt3.test 03a6118a8fe5a7c217c28c92b6b25ba04643640a4ac0a1d2b8d10de8191dc5f4 +F ext/fts5/test/fts5corrupt3.test 43d6a836892d79ab738ab89b3b6f4ae46c07ee966193e4b357bbb14e7f81d5da F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a0ff2f26e0c2e222abe F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 28db0d152d90fb5e62d03ea5caceabe8901be98522aef3dc2b54564fbc35355d -R 1e194882c201aa8b6f5e945d6a9a2830 -U dan -Z 378fff7db2aa3a965f8f7be7342e2ca6 +P 56314b6b53c86ae131f780e20b62bdeabccba6d62dda41becc1c4b2e87cee07b +R dc894f7a0ca88716616acdb5c2fedf44 +U drh +Z a929e93c97a2220333e660f05941e298 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c2c2547e28..e92173e7f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56314b6b53c86ae131f780e20b62bdeabccba6d62dda41becc1c4b2e87cee07b +e1f8e0240b14f1338e947634e840af785e5042a09cd365975e922a13a562f4cd From 9615cf93c886f13c6c9148ca52fb7b8f7d1fa7de Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Jul 2025 14:54:20 +0000 Subject: [PATCH 54/88] If SQLITE_DEBUG is defined, fts5 does extra checks as part of integrity-check. Ensure that errors from these extra checks are only reported if the other, normal, tests all pass. This fixes a test case in fts5corrupt3.test that was failing if SQLITE_DEBUG was defined. FossilOrigin-Name: 98a53fb276fa1fa733da2dd3255c35ce9f6af9b9feef6e76fb577b6d142167a2 --- ext/fts5/fts5_index.c | 26 +++++++++++++++++++------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 5a50637486..7526330644 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -8286,14 +8286,19 @@ static int fts5TestUtf8(const char *z, int n){ /* ** This function is also purely an internal test. It does not contribute to ** FTS functionality, or even the integrity-check, in any way. +** +** This function sets output variable (*pbFail) to true if the test fails. Or +** leaves it unchanged if the test succeeds. */ static void fts5TestTerm( Fts5Index *p, Fts5Buffer *pPrev, /* Previous term */ const char *z, int n, /* Possibly new term to test */ u64 expected, - u64 *pCksum + u64 *pCksum, + int *pbFail ){ + int bRet = 0; int rc = p->rc; if( pPrev->n==0 ){ fts5BufferSet(&rc, pPrev, n, (const u8*)z); @@ -8348,7 +8353,7 @@ static void fts5TestTerm( fts5BufferSet(&rc, pPrev, n, (const u8*)z); if( rc==SQLITE_OK && cksum3!=expected ){ - rc = FTS5_CORRUPT; + *pbFail = 1; } *pCksum = cksum3; } @@ -8357,7 +8362,7 @@ static void fts5TestTerm( #else # define fts5TestDlidxReverse(x,y,z) -# define fts5TestTerm(u,v,w,x,y,z) +# define fts5TestTerm(t,u,v,w,x,y,z) #endif /* @@ -8615,6 +8620,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ /* Used by extra internal tests only run if NDEBUG is not defined */ u64 cksum3 = 0; /* Checksum based on contents of indexes */ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ + int bTestFail = 0; #endif const int flags = FTS5INDEX_QUERY_NOOUTPUT; @@ -8657,7 +8663,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ char *z = (char*)fts5MultiIterTerm(pIter, &n); /* If this is a new term, query for it. Update cksum3 with the results. */ - fts5TestTerm(p, &term, z, n, cksum2, &cksum3); + fts5TestTerm(p, &term, z, n, cksum2, &cksum3, &bTestFail); if( p->rc ) break; if( eDetail==FTS5_DETAIL_NONE ){ @@ -8675,7 +8681,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ } } } - fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3); + fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3, &bTestFail); fts5MultiIterFree(pIter); if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ){ @@ -8684,11 +8690,17 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ "fts5: checksum mismatch for table \"%s\"", p->pConfig->zName ); } - - fts5StructureRelease(pStruct); #ifdef SQLITE_DEBUG + /* In SQLITE_DEBUG builds, expensive extra checks were run as part of + ** the integrity-check above. If no other errors were detected, but one + ** of these tests failed, set the result to SQLITE_CORRUPT_VTAB here. */ + if( p->rc==SQLITE_OK && bTestFail ){ + p->rc = FTS5_CORRUPT; + } fts5BufferFree(&term); #endif + + fts5StructureRelease(pStruct); fts5BufferFree(&poslist); return fts5IndexReturn(p); } diff --git a/manifest b/manifest index 8849616fcc..047bd78443 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\scase\sresults\sin\sFTS5\sthat\swere\schanged\serror\smessage\simprovements\nin\s[48044a6b57c0a16c]\sbut\swhich\swere\somitted\sfrom\sthat\scheck-in. -D 2025-07-08T12:37:25.996 +C If\sSQLITE_DEBUG\sis\sdefined,\sfts5\sdoes\sextra\schecks\sas\spart\sof\sintegrity-check.\sEnsure\sthat\serrors\sfrom\sthese\sextra\schecks\sare\sonly\sreported\sif\sthe\sother,\snormal,\stests\sall\spass.\sThis\sfixes\sa\stest\scase\sin\sfts5corrupt3.test\sthat\swas\sfailing\sif\sSQLITE_DEBUG\swas\sdefined. +D 2025-07-08T14:54:20.049 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c ed562b75c87efaa80c40e55f6c1102904728e35baa293c371f96b1c8e151399d +F ext/fts5/fts5_index.c aa1da5db8383da13a620312b60cdb997ec265cd2fa4e9a2e6cea8f864c42c279 F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 56314b6b53c86ae131f780e20b62bdeabccba6d62dda41becc1c4b2e87cee07b -R dc894f7a0ca88716616acdb5c2fedf44 -U drh -Z a929e93c97a2220333e660f05941e298 +P e1f8e0240b14f1338e947634e840af785e5042a09cd365975e922a13a562f4cd +R 2fa6dffea449b33b5ab95a81c97744b0 +U dan +Z a3e485555db3d8ba12554cbb5df06f32 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e92173e7f5..e54c57f7b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1f8e0240b14f1338e947634e840af785e5042a09cd365975e922a13a562f4cd +98a53fb276fa1fa733da2dd3255c35ce9f6af9b9feef6e76fb577b6d142167a2 From 449b34571e9022333eb0cd0ce403a4636719194d Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 8 Jul 2025 17:28:09 +0000 Subject: [PATCH 55/88] Enable the EXISTS-to-JOIN optimization if the outer query has no FROM clause. FossilOrigin-Name: 1b9b124f9a35ebd1ac4ea70ef1ee08a4c82c11da690d4164f6b785a6fd9730d9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 9 ++++++--- src/select.c | 1 - 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7ead8c5181..ff1e169701 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\sthe\sresolver. -D 2025-07-07T19:03:50.925 +C Enable\sthe\sEXISTS-to-JOIN\soptimization\sif\sthe\souter\squery\shas\sno\nFROM\sclause. +D 2025-07-08T17:28:09.030 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -729,7 +729,7 @@ F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea F src/btree.c cb5b8ceb9baa02a63a2f83dec09c4153e1cfbdf9c2adef5c62c26d2160eeb067 F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 -F src/build.c bef89ea23db1221556a3a405b7c46cac14c03fc0a8e82954ca2359a7dc98ec69 +F src/build.c cc4f287348790bbb7219f7e8dee13b1c345c3377fcdd98eca866e7457ecd07e7 F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c b1d4e1f21a32b4f33d3bf02c4167ac8da5aafb97210a0b13a9119d68183db37d +F src/select.c 244f2fba5f73c7ea937333bd54280e83e218a0b652fc4540cbd72d33b0f7b4d8 F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f15cdf07573c05276a13885d74bae21a93544766344f19ef939b7a69edd1073b -R 2636d63ee0b11ec41a4803b9ba60214d +P 840646df0696706bd4dd7a04dfc8b16ad80c24cbcbc57a22c9e65a93cc17af2b +R e35575e41e9bd119ef19709aeaa4c684 U drh -Z f0a94ad32bbc71db6c95d4953159e88b +Z 4da98ddcb106ab62869cc3825500f67f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0533abe09d..384e800b52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -840646df0696706bd4dd7a04dfc8b16ad80c24cbcbc57a22c9e65a93cc17af2b +1b9b124f9a35ebd1ac4ea70ef1ee08a4c82c11da690d4164f6b785a6fd9730d9 diff --git a/src/build.c b/src/build.c index cd838557fd..5495cef18f 100644 --- a/src/build.c +++ b/src/build.c @@ -5138,6 +5138,9 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ */ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ assert( p1 ); + assert( p2 || pParse->nErr ); + assert( p2==0 || p2->nSrc>=1 ); + testcase( p1->nSrc==0 ); if( p2 ){ int nOld = p1->nSrc; SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, nOld); @@ -5146,10 +5149,10 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ }else{ p1 = pNew; memcpy(&p1->a[nOld], p2->a, p2->nSrc*sizeof(SrcItem)); - assert( nOld==1 || (p2->nSrc==1 && (p2->a[0].fg.jointype&JT_LTORJ)==0) ); - assert( p1->nSrc>=2 ); + assert( nOld==1 || (p2->a[0].fg.jointype & JT_LTORJ)==0 ); + assert( p1->nSrc>=1 ); + p1->a[0].fg.jointype |= (JT_LTORJ & p2->a[0].fg.jointype); sqlite3DbFree(pParse->db, p2); - p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); } } return p1; diff --git a/src/select.c b/src/select.c index b15300237a..2dd8fc7725 100644 --- a/src/select.c +++ b/src/select.c @@ -7432,7 +7432,6 @@ static SQLITE_NOINLINE void existsToJoin( ){ if( pWhere && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) - && p->pSrc->nSrc>0 && p->pSrc->nSrcdb->mallocFailed==0 ){ From acd1d93497260ee7341634f635d057213226c945 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Jul 2025 18:44:56 +0000 Subject: [PATCH 56/88] Fix another problem with running fts5 integrity-check in SQLITE_DEBUG builds, this one causing an assert() failure. FossilOrigin-Name: 5cb8e342e1d33a0fd04fd022900eeada46a2ee23f15c6abca1b37633e77429d6 --- ext/fts5/fts5_index.c | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 7526330644..3be556f8ac 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -8298,12 +8298,15 @@ static void fts5TestTerm( u64 *pCksum, int *pbFail ){ - int bRet = 0; int rc = p->rc; if( pPrev->n==0 ){ fts5BufferSet(&rc, pPrev, n, (const u8*)z); }else - if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){ + if( *pbFail==0 + && rc==SQLITE_OK + && (pPrev->n!=n || memcmp(pPrev->p, z, n)) + && p->pHash->nEntry==0 + ){ u64 cksum3 = *pCksum; const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */ int nTerm = pPrev->n-1; /* Size of zTerm in bytes */ diff --git a/manifest b/manifest index 047bd78443..0fbdfaba9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sSQLITE_DEBUG\sis\sdefined,\sfts5\sdoes\sextra\schecks\sas\spart\sof\sintegrity-check.\sEnsure\sthat\serrors\sfrom\sthese\sextra\schecks\sare\sonly\sreported\sif\sthe\sother,\snormal,\stests\sall\spass.\sThis\sfixes\sa\stest\scase\sin\sfts5corrupt3.test\sthat\swas\sfailing\sif\sSQLITE_DEBUG\swas\sdefined. -D 2025-07-08T14:54:20.049 +C Fix\sanother\sproblem\swith\srunning\sfts5\sintegrity-check\sin\sSQLITE_DEBUG\sbuilds,\sthis\sone\scausing\san\sassert()\sfailure. +D 2025-07-08T18:44:56.030 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c aa1da5db8383da13a620312b60cdb997ec265cd2fa4e9a2e6cea8f864c42c279 +F ext/fts5/fts5_index.c 679f87e02b932a833b3be3f8cd0be801764734e45eec0af2f40221e9d642dca5 F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e1f8e0240b14f1338e947634e840af785e5042a09cd365975e922a13a562f4cd -R 2fa6dffea449b33b5ab95a81c97744b0 +P 98a53fb276fa1fa733da2dd3255c35ce9f6af9b9feef6e76fb577b6d142167a2 +R 5447b82878e3e38acec112f41ff81989 U dan -Z a3e485555db3d8ba12554cbb5df06f32 +Z 3692a3140974e87e4bf2396c2ef42958 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e54c57f7b3..a5f6837098 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98a53fb276fa1fa733da2dd3255c35ce9f6af9b9feef6e76fb577b6d142167a2 +5cb8e342e1d33a0fd04fd022900eeada46a2ee23f15c6abca1b37633e77429d6 From 9b91aac83b3db7a108ed203ee43b40e2e735ac0e Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Jul 2025 19:02:26 +0000 Subject: [PATCH 57/88] Fix a problem with the fix in [5cb8e342e1]. FossilOrigin-Name: 043ff54fb746c54bc6cfa6aa8c8a32c876c09d36163125916ad01024b98d447b --- ext/fts5/fts5_index.c | 2 +- ext/fts5/test/fts5integrity.test | 6 ++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3be556f8ac..7036e57f5f 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -8305,7 +8305,7 @@ static void fts5TestTerm( if( *pbFail==0 && rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) - && p->pHash->nEntry==0 + && (p->pHash==0 || p->pHash->nEntry==0) ){ u64 cksum3 = *pCksum; const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */ diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index 5c40021803..4bf120c446 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -37,6 +37,12 @@ do_execsql_test 2.1 { INSERT INTO yy(yy) VALUES('integrity-check'); } +db close +sqlite3 db test.db +do_execsql_test 2.1 { + INSERT INTO yy(yy) VALUES('integrity-check'); +} + #-------------------------------------------------------------------- # do_execsql_test 3.0 { diff --git a/manifest b/manifest index 0fbdfaba9e..53a33eba01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\swith\srunning\sfts5\sintegrity-check\sin\sSQLITE_DEBUG\sbuilds,\sthis\sone\scausing\san\sassert()\sfailure. -D 2025-07-08T18:44:56.030 +C Fix\sa\sproblem\swith\sthe\sfix\sin\s[5cb8e342e1]. +D 2025-07-08T19:02:26.486 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c 679f87e02b932a833b3be3f8cd0be801764734e45eec0af2f40221e9d642dca5 +F ext/fts5/fts5_index.c 8321944bcabdb3f3cac1c44867758ff9a9baaee5532debed2721d4d64d3c615d F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -197,7 +197,7 @@ F ext/fts5/test/fts5first.test bfd685b96905bf541d99d8644e0a7219d1d833455a08ab64e F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affcf7e979df59547b F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e F ext/fts5/test/fts5hash.test fd3e0367fbf0b0944d6936fdb22696350f57b9871069c6766251578a103e8a14 -F ext/fts5/test/fts5integrity.test 646796671205dae46af5bb12a49b5696483cfe8e12d71d21454940b13ace95ab +F ext/fts5/test/fts5integrity.test c423ce16fd1ccadcac7fc22f794226b2bb00f5a187c0ab1d9f8502521b1bae05 F ext/fts5/test/fts5integrity2.test 4c3636615c0201232c44a8105d5cb14fd5499fd0ee3014d7ffd7e83aac76ece8 F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 98a53fb276fa1fa733da2dd3255c35ce9f6af9b9feef6e76fb577b6d142167a2 -R 5447b82878e3e38acec112f41ff81989 +P 5cb8e342e1d33a0fd04fd022900eeada46a2ee23f15c6abca1b37633e77429d6 +R 2f815a7ddd919cbdb9dea42abcf9e107 U dan -Z 3692a3140974e87e4bf2396c2ef42958 +Z 1f7246259d459232db167600e0b56367 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a5f6837098..10ef81e7bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5cb8e342e1d33a0fd04fd022900eeada46a2ee23f15c6abca1b37633e77429d6 +043ff54fb746c54bc6cfa6aa8c8a32c876c09d36163125916ad01024b98d447b From aa12f0027b7630a5f6d2129ea967bf971e9e12f1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 8 Jul 2025 20:28:35 +0000 Subject: [PATCH 58/88] Adjustments to test/incrblob4.test so that it works on both Linux and Mac in spite of error message differences between those platforms. Minor change to termIsEquivalent() to provide 100% MC/DC. FossilOrigin-Name: 720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/whereexpr.c | 2 +- test/incrblob4.test | 9 ++++++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index acdcb2527c..ef930db58f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\soptimizations\sto\sdetect\searly\swhen\squeries\sreturn\sno\srows\sdue\sto\ntables\sbeing\sempty.\s\sThis\sincludes\sthe\sEXISTS-to-JOIN\soptimization\sthat\ntries\sto\stransform\sEXISTS\sconstraints\sinto\sadditional\sterms\sof\sthe\sFROM\nclause. -D 2025-07-08T19:53:36.480 +C Adjustments\sto\stest/incrblob4.test\sso\sthat\sit\sworks\son\sboth\sLinux\sand\sMac\nin\sspite\sof\serror\smessage\sdifferences\sbetween\sthose\splatforms.\s\sMinor\schange\nto\stermIsEquivalent()\sto\sprovide\s100%\sMC/DC. +D 2025-07-08T20:28:35.779 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -870,7 +870,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 6a9266dd1a559d48d8c7ca670a3e80143c7913153f7d1ceb0a4eca1087318951 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 2a2d2993fd98c46f525f71b3bfd330fde73d8613aa0ff3e20402dd1fc63470af -F src/whereexpr.c d007dc41364de5902181739632380afd671e14f0c5cc9978e64a2c6df8f28c6c +F src/whereexpr.c 0a7fe115adad30def38aeab6ac1d35fb67782cee92a43df7448136240accd4dd F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -1318,7 +1318,7 @@ F test/in7.test d9efdee00b074a60c6343993b2eda78bc369ab080dad864513c73f8aca89d566 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f -F test/incrblob4.test 832045dda1148121a329bfb42abcca576b808e23a85cd3bedae9b7e1c89b3f1f +F test/incrblob4.test a8d6b5ff04055fcec747a50b78485ebf4fcd80074e0b3cedbe952bde346da54a F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9 F test/incrblobfault.test de274b1e329169c2c3438f9528994807ea8201ebf38ae9f157d34bf3ec0cc549 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a @@ -2211,9 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 043ff54fb746c54bc6cfa6aa8c8a32c876c09d36163125916ad01024b98d447b 1b9b124f9a35ebd1ac4ea70ef1ee08a4c82c11da690d4164f6b785a6fd9730d9 -R f2382be8a4dd59640ba7d3e608aa0208 -T +closed 1b9b124f9a35ebd1ac4ea70ef1ee08a4c82c11da690d4164f6b785a6fd9730d9 +P e33da6d5dc964db817d1bc63c9083aecd93d49ee14d5198600b47eaf7c5b9331 +R 78682a3b3c6b0a6c29f5de1434b5f502 U drh -Z 2faf96645b8f6e620da8ad84b2b3ac57 +Z 9e6d5e7b5a33e381b6fe52bba2b5d309 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 156cff42a4..46b6f92afb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e33da6d5dc964db817d1bc63c9083aecd93d49ee14d5198600b47eaf7c5b9331 +720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067 diff --git a/src/whereexpr.c b/src/whereexpr.c index e4be8d9d67..e9fa4a1432 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -948,7 +948,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ assert( pSrc!=0 ); if( pExpr->op==TK_IS - && pSrc->nSrc + && pSrc->nSrc>=2 && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* (4) */ diff --git a/test/incrblob4.test b/test/incrblob4.test index d6ffe6b654..c9bcee8a3b 100644 --- a/test/incrblob4.test +++ b/test/incrblob4.test @@ -129,7 +129,8 @@ do_test 5.2.1 { do_test 5.2.2 { puts -nonewline $blob "world" - list [catch { flush $blob } msg] $msg + set rc [catch { flush $blob } msg] + list $rc [regsub {input/output} $msg {I/O}] } "1 {error flushing \"$blob\": I/O error}" catch { close $blob } @@ -149,7 +150,8 @@ do_test 5.3.1 { do_test 5.3.2 { puts -nonewline $blob "world" - list [catch { flush $blob } msg] $msg + set rc [catch { flush $blob } msg] + list $rc [regsub {input/output} $msg {I/O}] } "1 {error flushing \"$blob\": I/O error}" catch { close $blob } @@ -190,7 +192,8 @@ do_test 5.4.3 { do_test 5.4.4 { puts -nonewline $blob "world" - list [catch { flush $blob } msg] $msg + set rc [catch { flush $blob } msg] + list $rc [regsub {input/output} $msg {I/O}] } "1 {error flushing \"$blob\": I/O error}" catch { close $blob } catchsql { ROLLBACK } From 8663a78ec9f6c85db6224007a49c264359e908ce Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 8 Jul 2025 22:11:39 +0000 Subject: [PATCH 59/88] Fix a possible user-after free following OOM in the EXISTS-to-JOIN optimization. FossilOrigin-Name: 498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ef930db58f..58cfe31140 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjustments\sto\stest/incrblob4.test\sso\sthat\sit\sworks\son\sboth\sLinux\sand\sMac\nin\sspite\sof\serror\smessage\sdifferences\sbetween\sthose\splatforms.\s\sMinor\schange\nto\stermIsEquivalent()\sto\sprovide\s100%\sMC/DC. -D 2025-07-08T20:28:35.779 +C Fix\sa\spossible\suser-after\sfree\sfollowing\sOOM\sin\sthe\sEXISTS-to-JOIN\noptimization. +D 2025-07-08T22:11:39.260 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 244f2fba5f73c7ea937333bd54280e83e218a0b652fc4540cbd72d33b0f7b4d8 +F src/select.c 33a46f68191ac6cb00409417593adb03be68c8078d36ebe079a3a0914b220d93 F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e33da6d5dc964db817d1bc63c9083aecd93d49ee14d5198600b47eaf7c5b9331 -R 78682a3b3c6b0a6c29f5de1434b5f502 +P 720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067 +R 06654310fbfa0a3e107f5e62dfa928dd U drh -Z 9e6d5e7b5a33e381b6fe52bba2b5d309 +Z d3919178e62d3c6ffc666ec27b2d4fc8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 46b6f92afb..bedccbe899 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067 +498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa diff --git a/src/select.c b/src/select.c index 2dd8fc7725..99b05c76a3 100644 --- a/src/select.c +++ b/src/select.c @@ -7430,10 +7430,11 @@ static SQLITE_NOINLINE void existsToJoin( Select *p, /* The SELECT statement being optimized */ Expr *pWhere /* part of the WHERE clause currently being examined */ ){ - if( pWhere + if( pParse->nErr==0 + && pWhere!=0 && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) + && ALWAYS(p->pSrc!=0) && p->pSrc->nSrcdb->mallocFailed==0 ){ if( pWhere->op==TK_AND ){ Expr *pRight = pWhere->pRight; From 6276637075213c3735108d4a9d5a03eeda1e72e5 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Jul 2025 13:13:01 +0000 Subject: [PATCH 60/88] wasm: add a few tests demonstrating that oo1.Stmt.paramaterCount's new impl does not change visible behaviors. Add the c-pp-filtered files to 'make clean'. FossilOrigin-Name: 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce --- ext/wasm/GNUmakefile | 2 +- ext/wasm/tester1.c-pp.js | 4 ++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index bf1a49111c..4296b6305e 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -429,7 +429,7 @@ define SQLITE.CALL.C-PP.FILTER $(2): $(1) $$(MAKEFILE_LIST) $$(bin.c-pp) @mkdir -p $$(dir $$@) $$(bin.c-pp) -f $(1) -o $$@ $(3) $(SQLITE.CALL.C-PP.FILTER.global) -#CLEAN_FILES += $(2) +CLEAN_FILES += $(2) endef # /end SQLITE.CALL.C-PP.FILTER ######################################################################## diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 824b6081da..aafe4d7f3f 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1356,6 +1356,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; /columnCount property is read-only/) .assert(1===st.columnCount) .assert(0===st.parameterCount) + .assert(0===capi.sqlite3_bind_parameter_count(st)) .mustThrow(()=>st.bind(1,null)) .assert(true===st.step()) .assert(3 === st.get(0)) @@ -1578,6 +1579,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule; let st = db.prepare("update t set b=:b where a='blob'"); try { T.assert(0===st.columnCount) + .assert(1===st.parameterCount) + .assert(1===capi.sqlite3_bind_parameter_count(st)) .assert( false===st.isReadOnly() ); const ndx = st.getParamIndex(':b'); T.assert(1===ndx); @@ -3417,6 +3420,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; db.exec("create table t(a)"); const stmt = db.prepare("insert into t(a) values($a)"); T.assert( 1===capi.sqlite3_bind_parameter_count(stmt) ) + .assert( 1===stmt.parameterCount ) .assert( 1===capi.sqlite3_bind_parameter_index(stmt, "$a") ) .assert( 0===capi.sqlite3_bind_parameter_index(stmt, ":a") ) .assert( 1===stmt.getParamIndex("$a") ) diff --git a/manifest b/manifest index 7a3bb87723..da6bf18ef5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sdead\sJS\scode\sand\ssome\sextraneous\sdebug\soutput\sfrom\stest\scode. -D 2025-07-06T15:36:28.567 +C wasm:\sadd\sa\sfew\stests\sdemonstrating\sthat\soo1.Stmt.paramaterCount's\snew\simpl\sdoes\snot\schange\svisible\sbehaviors.\sAdd\sthe\sc-pp-filtered\sfiles\sto\s'make\sclean'. +D 2025-07-09T13:13:01.736 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -621,7 +621,7 @@ F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af1 F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile a05bb1766f97c88cb42fbfe9e349c799c691f8ae0dc959e9d9469f0bcee89350 +F ext/wasm/GNUmakefile 4d329d89ffb701847abadff9a7e8ec59aaa26a6a2b8ddc2677514154248a2871 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js b99d18fe8803215664a3b53af451d11e2573682a2c8973bcd28ce574c497393b +F ext/wasm/tester1.c-pp.js 1c4fdb32e10c92e2595939b1b6f6588cd3a30a2691ba2dc4a42893db99e0648b F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7933505f0c1d25c6ee81ead8edc5ea649a84ec0582321bcf5ed4a17232750f90 -R 7f815f9b4c7a2aabd4a38289c5be858a +P 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 +R 275bf35e86e01e823d3a78eac9fe64ed U stephan -Z d14be01d18ce30e04a958bfca48cc223 +Z 5ade71be55c22a5952ee210feb5c3747 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eee638be6b..dbc806e8f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 +3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce From 2ba5a93e8f6f42e617fad7b840d0720bb1dfbe26 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Jul 2025 13:43:53 +0000 Subject: [PATCH 61/88] wasm: DB.wrapHandle() no longer accepts a DB object as its first argument, as there's no apparent use case for proxying one DB object with another. Doc improvements for the new code. FossilOrigin-Name: 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 117 ++++++++++++--------------- ext/wasm/tester1.c-pp.js | 7 +- manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 63 insertions(+), 77 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index cc4c9bb287..27176c0264 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -38,13 +38,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ */ const __ptrMap = new WeakMap(); /** - A Set of oo1.DB objects which are proxies for (A) (sqlite3*) or - another oo1.DB object or (B) oo1.Stmt objects which are proxies - for (sqlite3_stmt*) pointers. Such objects do not own their - underlying handle and that handle must be guaranteed (by the - client) to outlive the proxy. These proxies are primarily - intended as a way to briefly wrap an (sqlite3[_stmt]*) object as - an oo1.DB/Stmt without taking over ownership. + A Set of oo1.DB or oo1.Stmt objects which are proxies for + (sqlite3*) resp. (sqlite3_stmt*) pointers. Such objects + optionally do not own their underlying handle and that handle + must be guaranteed (by the client) to outlive the proxy. These + proxies are primarily intended as a way to briefly wrap an + (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking over + ownership. + + See DB.wrapHandle() and Stmt.wrapHandle(). */ const __doesNotOwnHandle = new Set(); /** @@ -1488,22 +1490,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*DB.prototype*/; /** - Returns a new oo1.DB instance which wraps the given db. + Returns a new oo1.DB instance which wraps the given (sqlite3*) + WASM pointer, optionally with or without taking over ownership of + that pointer. The first argument must be either a non-NULL (sqlite3*) WASM - pointer or a non-close()d instance of oo1.DB. + pointer. - The second argument, defaulting to false, only applies if the - first argument is a (sqlite3*). If it is, the returned object - will pass that pointer to sqlite3_close() when its close() method - is called, otherwise it will not. - - If the first argument is a oo1.DB object, the second argument is - disregarded and the returned object will be created as a - sqlite3.oo1.DB object (as opposed to the concrete derived DB - subclass from the first argument), so will not include any - derived-type behaviors, - e.g. JsStorageDb.prototype.clearStorage(). + The second argument, defaulting to false, specifies ownership of + the first argument. If it is truthy, the returned object will + pass that pointer to sqlite3_close() when its close() method is + called, otherwise it will not. Throws if db cannot be resolved to one of the legal options. @@ -1515,56 +1512,38 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ DB instance, including the requirement of calling close() on it. close() will free up internal resources owned by the proxy, and disassociate the proxy from that handle, but will not - actually close the proxied db handle. + actually close the proxied db handle unless this function is + passed a thruthy second argument. The following quirks and requirements apply when proxying another DB instance, as opposed to a (sqlite3*): - - DO NOT call close() on the being-proxied instance while a proxy - is active. + - DO NOT call sqlite3_close() (or similar) on the being-proxied + instance while a proxy is active. - - ALWAYS eventually call close() on the returned object BEFORE - the being-proxied handle is closed. + - ALWAYS eventually call close() on the returned object. If the + proxy does not own the underlying handle then its MUST be + closed BEFORE the being-proxied handle is closed. - - For historical reasons, the filename property of the returned - object is captured at the time of this call, as opposed to being - dynamically proxied. e.g., if the filename property of the - being-proxied object is changed, this object will not reflect - that change. There is no good reason to ever modify that - property, so this distinction is not truly significant but it's - noted here because it's a client-visible discrepancy between the - proxy and its partner. (Sidebar: the filename property _should_ - be a property access interceptor for sqlite3_db_filename(), - but making it so now may break existing code.) + Design notes: + + - wrapHandle() "could" accept a DB object instance as its first + argument and proxy thatDb.pointer but there is currently no use + case where doing so would be useful, so it does not allow + that. That restriction may be lifted in a future version. */ - DB.wrapHandle = function(db, takeOwnership=false){ - let ptr, ctor = DB; - const oo1db = (db instanceof DB) ? db : undefined; - if( wasm.isPtr(db) ){ - ptr = db; - }else if( oo1db ){ - takeOwnership = false; - ptr = db.pointer; - //ctor = db.constructor; - // ^^^ that doesn't work, resulting in an Object-type value + DB.wrapHandle = function(pDb, takeOwnership=false){ + if( !pDb || !wasm.isPtr(pDb) ){ + throw new sqlite3.SQLite3Error(capi.SQLITE_MISUSE, + "Argument must be a WASM sqlite3 pointer"); } - //sqlite3.config.debug("wrapHandle()",'db',db,'ctor',ctor, - //'arguments',arguments,'db.constructor',db.constructor); - if( !ptr ){ - throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, - "Argument must be a WASM sqlite3 "+ - "pointer or an sqlite3.oo1.DB instance"); - } - const dc = new ctor({ - "sqlite3*": ptr, + return new DB({ + /* This ctor call style is very specifically internal-use-only. + It is not documented and may change at any time. */ + "sqlite3*": pDb, "sqlite3*:takeOwnership": !!takeOwnership }); - if( oo1db ){ - dc.filename = oo1db.filename; - }//else dc.filename was captured by the ctor for legacy consistency - //sqlite3.config.debug("wrapHandle() dc",dc); - return dc; - }/*DB.wrapHandle()*/; + }; /** Throws if the given Stmt has been finalized, else stmt is returned. */ @@ -2260,8 +2239,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** The Stmt counterpart of oo1.DB.wrapHandle(), this creates a Stmt - instance which wraps a WASM (sqlite3_stmt*) in the oo1 API with - or without taking over ownership of that pointer. + instance which wraps a WASM (sqlite3_stmt*) in the oo1 API, + optionally with or without taking over ownership of that pointer. The first argument must be an oo1.DB instance[^1]. @@ -2272,7 +2251,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ returned Stmt object takes over ownership of the underlying (sqlite3_stmt*). If true, the returned object's finalize() method will finalize that handle, else it will not. If it is false, - ownership of stmtPtr is unchanged and stmtPtr MUST outlive the + ownership of pStmt is unchanged and pStmt MUST outlive the returned object or results are undefined. This function throws if the arguments are invalid. On success it @@ -2289,21 +2268,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ determined whether it would be of general benefit to refactor the DB/Stmt pair internals to communicate in terms of the underlying (sqlite3*) rather than a DB object. If so, we could laxen the - first argument's requirement and allow an (sqlite3*). + first argument's requirement and allow an (sqlite3*). Because + DB.wrapHandle() enables multiple DB objects to proxy the same + (sqlite3*), we cannot unambiguously translate the first arugment + from (sqlite3*) to DB instances for us with this function's first + argument. */ - Stmt.wrapHandle = function(oo1db, stmtPtr, takeOwnership=false){ + Stmt.wrapHandle = function(oo1db, pStmt, takeOwnership=false){ let ctor = Stmt; if( !(oo1db instanceof DB) || !oo1db.pointer ){ throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, "First argument must be an opened "+ "sqlite3.oo1.DB instance"); } - if( !stmtPtr || !wasm.isPtr(stmtPtr) ){ + if( !pStmt || !wasm.isPtr(pStmt) ){ throw new sqlite3.SQLite3Error(sqlite3.SQLITE_MISUSE, "Second argument must be a WASM "+ "sqlite3_stmt pointer"); } - return new Stmt(oo1db, stmtPtr, BindTypes, !!takeOwnership); + return new Stmt(oo1db, pStmt, BindTypes, !!takeOwnership); } /** The OO API's public namespace. */ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index aafe4d7f3f..f2fdeebed6 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -221,7 +221,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; else if(filter instanceof Function) pass = filter(err); else if('string' === typeof filter) pass = (err.message === filter); if(!pass){ - throw new Error(msg || ("Filter rejected this exception: "+err.message)); + throw new Error(msg || ("Filter rejected this exception: <<"+err.message+">>")); } return this; }, @@ -1219,7 +1219,10 @@ globalThis.sqlite3InitModule = sqlite3InitModule; function do not interfere with downstream tests, e.g. by closing this.db.pointer. */ //sqlite3.config.debug("Proxying",this.db); - let dw = sqlite3.oo1.DB.wrapHandle(this.db); + const misuseMsg = "SQLITE_MISUSE: Argument must be a WASM sqlite3 pointer"; + T.mustThrowMatching(()=>sqlite3.oo1.DB.wrapHandle(this.db), misuseMsg) + .mustThrowMatching(()=>sqlite3.oo1.DB.wrapHandle(0), misuseMsg); + let dw = sqlite3.oo1.DB.wrapHandle(this.db.pointer); //sqlite3.config.debug('dw',dw); T.assert( dw, '!!dw' ) .assert( dw instanceof sqlite3.oo1.DB, 'dw is-a oo1.DB' ) diff --git a/manifest b/manifest index da6bf18ef5..abeec3b372 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sadd\sa\sfew\stests\sdemonstrating\sthat\soo1.Stmt.paramaterCount's\snew\simpl\sdoes\snot\schange\svisible\sbehaviors.\sAdd\sthe\sc-pp-filtered\sfiles\sto\s'make\sclean'. -D 2025-07-09T13:13:01.736 +C wasm:\sDB.wrapHandle()\sno\slonger\saccepts\sa\sDB\sobject\sas\sits\sfirst\sargument,\sas\sthere's\sno\sapparent\suse\scase\sfor\sproxying\sone\sDB\sobject\swith\sanother.\sDoc\simprovements\sfor\sthe\snew\scode. +D 2025-07-09T13:43:53.471 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 33203352e067d3dbb569c5ec3c247b356f61a8d320bf8551fdf18ff25c0ff862 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 972e0aa2f6f3ad9d9530edfc5c18a56e55ab5bec728ce6ca9b89ce1df463f740 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 1c4fdb32e10c92e2595939b1b6f6588cd3a30a2691ba2dc4a42893db99e0648b +F ext/wasm/tester1.c-pp.js 830749ee21bde538f52e150878c0078a3f6d294ba183900efd8488a9e6debf4f F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6e73770a7f3845055e0130012d844c32c4a1bfdb87e8379c161e1a266a808143 -R 275bf35e86e01e823d3a78eac9fe64ed +P 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce +R 7d3270f820abddff176885a6dceb6626 U stephan -Z 5ade71be55c22a5952ee210feb5c3747 +Z 4ed976109c5d88084cce8c9c03b32258 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dbc806e8f1..b2ae9d924e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce +0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 From 33c2e37f981af6766a6309f24a54b91fa3fa9080 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 9 Jul 2025 20:11:49 +0000 Subject: [PATCH 62/88] Fix the empty-table optimization on INTERSECT so that it does not try to use an uninitialized register for LIMIT processing. FossilOrigin-Name: 6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 25 ++++++++++++++++++++----- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 58cfe31140..a8c30532d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spossible\suser-after\sfree\sfollowing\sOOM\sin\sthe\sEXISTS-to-JOIN\noptimization. -D 2025-07-08T22:11:39.260 +C Fix\sthe\sempty-table\soptimization\son\sINTERSECT\sso\sthat\sit\sdoes\snot\stry\sto\nuse\san\suninitialized\sregister\sfor\sLIMIT\sprocessing. +D 2025-07-09T20:11:49.196 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 33a46f68191ac6cb00409417593adb03be68c8078d36ebe079a3a0914b220d93 +F src/select.c fc003cad96a105765261f7b6c5f4596e505894262bb5593cb29e10b682800d12 F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067 -R 06654310fbfa0a3e107f5e62dfa928dd +P 498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa +R ebdf1d802e5dd88fbc80d28dd0639cd8 U drh -Z d3919178e62d3c6ffc666ec27b2d4fc8 +Z 51edd06328595496523194f72341809d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bedccbe899..b9c5f04af2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa +6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f diff --git a/src/select.c b/src/select.c index 99b05c76a3..1b12663138 100644 --- a/src/select.c +++ b/src/select.c @@ -3130,7 +3130,7 @@ static int multiSelect( int tab1, tab2; int iCont, iBreak, iStart; Expr *pLimit; - int addr; + int addr, iLimit, iOffset; SelectDest intersectdest; int r1; int emptyBypass; @@ -3157,6 +3157,11 @@ static int multiSelect( if( rc ){ goto multi_select_end; } + + /* Initialize LIMIT counters before checking to see if the LHS + ** is empty, in case the jump is taken */ + iBreak = sqlite3VdbeMakeLabel(pParse); + computeLimitRegisters(pParse, p, iBreak); emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v); /* Code the current SELECT into temporary table "tab2" @@ -3164,9 +3169,17 @@ static int multiSelect( addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); assert( p->addrOpenEphm[1] == -1 ); p->addrOpenEphm[1] = addr; - p->pPrior = 0; + + /* Disable prior SELECTs and the LIMIT counters during the computation + ** of the RHS select */ pLimit = p->pLimit; + iLimit = p->iLimit; + iOffset = p->iOffset; + p->pPrior = 0; p->pLimit = 0; + p->iLimit = 0; + p->iOffset = 0; + intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", sqlite3SelectOpName(p->op))); @@ -3179,19 +3192,21 @@ static int multiSelect( p->nSelectRow = pPrior->nSelectRow; } sqlite3ExprDelete(db, p->pLimit); + + /* Reinstate the LIMIT counters prior to running the final intersect */ p->pLimit = pLimit; + p->iLimit = iLimit; + p->iOffset = iOffset; /* Generate code to take the intersection of the two temporary ** tables. */ if( rc ) break; assert( p->pEList ); - iBreak = sqlite3VdbeMakeLabel(pParse); - iCont = sqlite3VdbeMakeLabel(pParse); - computeLimitRegisters(pParse, p, iBreak); sqlite3VdbeAddOp1(v, OP_Rewind, tab1); r1 = sqlite3GetTempReg(pParse); iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); + iCont = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, r1); From 6fd9469a3281ae67929bfc518d0e80674ec15378 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 10 Jul 2025 09:25:57 +0000 Subject: [PATCH 63/88] Minor JS doc tweaks. FossilOrigin-Name: 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 11 +++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 27176c0264..1473e4e45e 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -1502,7 +1502,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ pass that pointer to sqlite3_close() when its close() method is called, otherwise it will not. - Throws if db cannot be resolved to one of the legal options. + Throws if pDb is not a non-0 WASM pointer. The caller MUST GUARANTEE that the passed-in handle will outlive the returned object, i.e. that it will not be closed. If it is closed, @@ -1510,16 +1510,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Aside from its lifetime, the proxy is to be treated as any other DB instance, including the requirement of calling close() on - it. close() will free up internal resources owned by the proxy, - and disassociate the proxy from that handle, but will not + it. close() will free up internal resources owned by the proxy + and disassociate the proxy from that handle but will not actually close the proxied db handle unless this function is passed a thruthy second argument. - The following quirks and requirements apply when proxying another - DB instance, as opposed to a (sqlite3*): + To stress: - DO NOT call sqlite3_close() (or similar) on the being-proxied - instance while a proxy is active. + pointer while a proxy is active. - ALWAYS eventually call close() on the returned object. If the proxy does not own the underlying handle then its MUST be diff --git a/manifest b/manifest index abeec3b372..20cc623889 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sDB.wrapHandle()\sno\slonger\saccepts\sa\sDB\sobject\sas\sits\sfirst\sargument,\sas\sthere's\sno\sapparent\suse\scase\sfor\sproxying\sone\sDB\sobject\swith\sanother.\sDoc\simprovements\sfor\sthe\snew\scode. -D 2025-07-09T13:43:53.471 +C Minor\sJS\sdoc\stweaks. +D 2025-07-10T09:25:57.652 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 972e0aa2f6f3ad9d9530edfc5c18a56e55ab5bec728ce6ca9b89ce1df463f740 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js bc472af6c3aada06ad94b332bf23cef2407932e5bb4c0c34c12a6ced343c2e51 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3fe61545967f82190011edb90b1be6a448b590555c7ba5f8e96494aeea8f88ce -R 7d3270f820abddff176885a6dceb6626 +P 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 +R 9671bcb7870e122ad1976f1fae21a064 U stephan -Z 4ed976109c5d88084cce8c9c03b32258 +Z adaaff03d3b0b893bc2eaac10b306778 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b2ae9d924e..963b157be5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 +34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f From 07b483c48eb82e46d98addfaa511722662e546b5 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 10 Jul 2025 09:27:57 +0000 Subject: [PATCH 64/88] Minor internal doc correction in vdbeInt.h. FossilOrigin-Name: c3a2ef639c22255a298cbccb7fd871ec9b24929f82bf95d6982b12daf5c963d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeInt.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a8c30532d4..0bd3540310 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sempty-table\soptimization\son\sINTERSECT\sso\sthat\sit\sdoes\snot\stry\sto\nuse\san\suninitialized\sregister\sfor\sLIMIT\sprocessing. -D 2025-07-09T20:11:49.196 +C Minor\sinternal\sdoc\scorrection\sin\svdbeInt.h. +D 2025-07-10T09:27:57.540 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -854,7 +854,7 @@ F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 F src/vdbe.c e505b8b879a330e8dafbe3ed9582eae2fc671b44a64748d1b58c07e4e0f527da F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 -F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e +F src/vdbeInt.h 626465ff6d673f73a2476dc230b7cd07bdaf4acea9d4ecceaa12a5174bb2c8d7 F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa -R ebdf1d802e5dd88fbc80d28dd0639cd8 -U drh -Z 51edd06328595496523194f72341809d +P 6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f +R 8d36b737321e561e20f07d5b87981833 +U stephan +Z b3f208b4a565eb9c2de3da1def14d617 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9c5f04af2..bdf7cbe6f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f +c3a2ef639c22255a298cbccb7fd871ec9b24929f82bf95d6982b12daf5c963d6 diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 0faa327472..07160f5901 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -288,7 +288,7 @@ struct sqlite3_value { ** MEM_Int, MEM_Real, and MEM_IntReal. ** ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus -** MEM.u.i extra 0x00 bytes at the end. +** Mem.u.nZero extra 0x00 bytes at the end. ** ** * MEM_Int Integer stored in Mem.u.i. ** From 45bff0ea643d39d1b57d0297837df45a48eb8b8d Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 10 Jul 2025 17:19:08 +0000 Subject: [PATCH 65/88] Add the estkey column to the jobs table of testrunner.db. The plan is to use this to collect measurements that will help generate improved ETAs for a test run. FossilOrigin-Name: 9eccf5267c6423c9dd4da1d61b62bbb6fbba44fb8089da79f89c84e8b77ff0f0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/testrunner.tcl | 21 +++++++++++++++++++-- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0bd3540310..7153ccb169 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sinternal\sdoc\scorrection\sin\svdbeInt.h. -D 2025-07-10T09:27:57.540 +C Add\sthe\sestkey\scolumn\sto\sthe\sjobs\stable\sof\stestrunner.db.\s\sThe\splan\sis\sto\nuse\sthis\sto\scollect\smeasurements\sthat\swill\shelp\sgenerate\simproved\sETAs\sfor\na\stest\srun. +D 2025-07-10T17:19:08.350 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1736,7 +1736,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a -F test/testrunner.tcl 614c4a28f7f730acd7bec53e17d76602fb480e0d538b6ec548169e03a093f92d x +F test/testrunner.tcl 5f74064aa32ba192808d2c2a85c036c1db7efe570b433c390443241144075528 x F test/testrunner_data.tcl 02dd645b647d907c959fbf232b7ff7d869c2ae430d5117443fc1e16a0d32243a F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f -R 8d36b737321e561e20f07d5b87981833 -U stephan -Z b3f208b4a565eb9c2de3da1def14d617 +P c3a2ef639c22255a298cbccb7fd871ec9b24929f82bf95d6982b12daf5c963d6 +R 8a638f7e150dac9b9d9c1a93839f5665 +U drh +Z 0cbe7c5c0788898f8ac3fc8efc37b5f2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bdf7cbe6f3..4649b590a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3a2ef639c22255a298cbccb7fd871ec9b24929f82bf95d6982b12daf5c963d6 +9eccf5267c6423c9dd4da1d61b62bbb6fbba44fb8089da79f89c84e8b77ff0f0 diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 0c6982f426..7d1b3141ac 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -341,6 +341,7 @@ set TRG(schema) { endtime INTEGER, -- End time span INTEGER, -- Total run-time in milliseconds estwork INTEGER, -- Estimated amount of work + estkey TEXT, -- Key used to compute estwork state TEXT CHECK( state IN ('','ready','running','done','failed','omit','halt') ), ntest INT, -- Number of test cases run nerr INT, -- Number of errors reported @@ -985,12 +986,27 @@ proc add_job {args} { set state "" if {$A(-depid)==""} { set state ready } set type $A(-displaytype) + set displayname $A(-displayname) + switch $type { + tcl { + set ek [file tail [lindex $displayname end]] + } + bld { + set ek [lindex $displayname end] + } + fuzz { + set ek [lrange $displayname 1 2] + } + make { + set ek [lindex $displayname end] + } + } set ew $estwork($type) trdb eval { INSERT INTO jobs( - displaytype, displayname, build, dirname, cmd, depid, priority, estwork, - state + displaytype, displayname, build, dirname, cmd, depid, priority, + estwork, estkey, state ) VALUES ( $type, $A(-displayname), @@ -1000,6 +1016,7 @@ proc add_job {args} { $A(-depid), $A(-priority), $ew, + $ek, $state ) } From 625d0b70febecb0864a81b2a047a961a59e8c17e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 10 Jul 2025 20:45:00 +0000 Subject: [PATCH 66/88] Improve the accuracy of the ETC on both devtest and releasetest. FossilOrigin-Name: a3f96cafdc0e1f2eeccc6509f1f9c26d2c48668953550f299cf2805a0a063014 --- manifest | 13 +- manifest.uuid | 2 +- test/testrunner.tcl | 91 ++++++- test/testrunner_estwork.tcl | 488 ++++++++++++++++++++++++++++++++++++ 4 files changed, 574 insertions(+), 20 deletions(-) create mode 100644 test/testrunner_estwork.tcl diff --git a/manifest b/manifest index 7153ccb169..11f8082b65 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sestkey\scolumn\sto\sthe\sjobs\stable\sof\stestrunner.db.\s\sThe\splan\sis\sto\nuse\sthis\sto\scollect\smeasurements\sthat\swill\shelp\sgenerate\simproved\sETAs\sfor\na\stest\srun. -D 2025-07-10T17:19:08.350 +C Improve\sthe\saccuracy\sof\sthe\sETC\son\sboth\sdevtest\sand\sreleasetest. +D 2025-07-10T20:45:00.900 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1736,8 +1736,9 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 463ae33b8bf75ac77451df19bd65e7c415c2e9891227c7c9e657d0a2d8e1074a -F test/testrunner.tcl 5f74064aa32ba192808d2c2a85c036c1db7efe570b433c390443241144075528 x +F test/testrunner.tcl b42f7736968cafc9e69bb5d0b87fc81b375fb4c3f44e19b472cccd91d41a416a x F test/testrunner_data.tcl 02dd645b647d907c959fbf232b7ff7d869c2ae430d5117443fc1e16a0d32243a +F test/testrunner_estwork.tcl 7927a84327259a32854926f68a75292e33a61e7e052fdbfcb01f18696c99c724 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -2211,8 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c3a2ef639c22255a298cbccb7fd871ec9b24929f82bf95d6982b12daf5c963d6 -R 8a638f7e150dac9b9d9c1a93839f5665 +P 9eccf5267c6423c9dd4da1d61b62bbb6fbba44fb8089da79f89c84e8b77ff0f0 +R 72101457f4e8f2d4243e574d79fb694e U drh -Z 0cbe7c5c0788898f8ac3fc8efc37b5f2 +Z fd661df697accbf37239cc80ab12a734 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4649b590a6..2fd45c96e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9eccf5267c6423c9dd4da1d61b62bbb6fbba44fb8089da79f89c84e8b77ff0f0 +a3f96cafdc0e1f2eeccc6509f1f9c26d2c48668953550f299cf2805a0a063014 diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 7d1b3141ac..52bc0f34b7 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -7,6 +7,18 @@ set testdir [file normalize [file dirname $argv0]] set saved $argv set argv [list] source [file join $testdir testrunner_data.tcl] + +# Estimated amount of work required by displaytype, relative to 'tcl' +# +set estwork(tcl) 1 +set estwork(fuzz) 22 +set estwork(bld) 66 +set estwork(make) 102 + +set estworkfile [file join $testdir testrunner_estwork.tcl] +if {[file readable $estworkfile]} { + source $estworkfile +} source [file join $testdir permutations.test] set argv $saved cd $dir @@ -92,6 +104,7 @@ Usage: $a0 script ?-msvc? CONFIG $a0 status ?-d SECS? ?--cls? $a0 halt + $a0 estwork where SWITCHES are: --buildonly Build test exes but do not run tests @@ -360,13 +373,6 @@ set TRG(schema) { } #------------------------------------------------------------------------- -# Estimated amount of work required by displaytype, relative to 'tcl' -# -set estwork(tcl) 1 -set estwork(fuzz) 11 -set estwork(bld) 56 -set estwork(make) 97 - #-------------------------------------------------------------------------- # Check if this script is being invoked to run a single file. If so, # run it. @@ -453,6 +459,59 @@ if {[llength $argv]==1 } #-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Check if this is the "estwork" command: +# +# Generate (on standard output) a set of estwork() values based on the lastest +# test case, that can be used to replace the test/testrunner_estwork.tcl file. +# +if {[llength $argv]==1 + && [string compare -nocase estwork [lindex $argv 0]]==0 +} { + sqlite3 mydb $TRG(dbname) + set njob [mydb one {SELECT count(*) FROM jobs WHERE state='done'}] + if {$njob<1000} { + puts "Too few completed jobs to do a work estimate." + puts "Have $njob but not need at least 1000." + mydb close + exit 1 + } + set badjobs [mydb one {SELECT count(*) FROM jobs WHERE state<>'done'}] + if {$badjobs} { + puts "Database contains $badjobs incomplete jobs." + mydb close + exit 1 + } + set half [mydb one {SELECT count(*)/2 FROM jobs WHERE displaytype='tcl'}] + set scale [mydb one {SELECT span FROM jobs WHERE displaytype='tcl' + ORDER BY span LIMIT 1 OFFSET $half}] + mydb eval { + SELECT estkey, CAST(avg(span)/$scale AS INT) AS cost + FROM jobs + GROUP BY estkey + HAVING cost>=2 + } { + set estwork($estkey) $cost + } + set avgtcl [mydb one {SELECT avg(span) FROM jobs WHERE displaytype='tcl'}] + set estwork(tcl) 1 + foreach type {bld fuzz make} { + set avg [mydb one {SELECT avg(span) FROM jobs WHERE displaytype=$type}] + if {$avg!=""} { + set estwork($type) [expr {int($avg/$avgtcl)}] + } + } + mydb close + puts "# Estimated relative cost of various jobs, based on the \"estkey\" field." + puts "# Computed by the \"test/testrunner.tcl estwork\" command." + puts "#" + foreach key [lsort [array names estwork]] { + puts "set [list estwork($key)] $estwork($key)" + } + exit +} +#-------------------------------------------------------------------------- + #-------------------------------------------------------------------------- # Check if this is the "help" command: # @@ -563,8 +622,8 @@ proc show_status {db cls} { set srcdir [file dirname [file dirname $TRG(info_script)]] set line "Running: $S(running) (max: $nJob)" - if {$S(running)>0 && $fin>10} { - set tmleft [expr {($tm/$fin)*($totalw-$fin)}] + if {$S(running)>0 && [set pct [expr {int(($fin*100.0)/$totalw)}]]>=4} { + set tmleft [expr {($tm/double($fin))*($totalw-$fin)}] if {$tmleft<0.02*$tm} { set tmleft [expr {$tm*0.02}] } @@ -572,6 +631,7 @@ proc show_status {db cls} { if {[string length $line]+[string length $etc]<80} { append line $etc } + # append line " $pct%" } puts [format %-79.79s $line] if {$S(running)>0} { @@ -1001,7 +1061,11 @@ proc add_job {args} { set ek [lindex $displayname end] } } - set ew $estwork($type) + if {[info exists estwork($ek)]} { + set ew $estwork($ek) + } else { + set ew $estwork($type) + } trdb eval { INSERT INTO jobs( @@ -1603,12 +1667,13 @@ proc progress_report {} { } } set report "[elapsetime $tmms] [join $text { }]" - if {$wdone>0} { - set tmleft [expr {($tmms/$wdone)*($wtotal-$wdone)}] - set etc " ETC [elapsetime $tmleft]" + if {$wdone>0 && [set pct [expr {int(($wdone*100.0)/$wtotal)}]]>=4} { + set tmleft [expr {($tmms/double($wdone))*($wtotal-$wdone)}] + set etc " ETC [elapsetime $tmleft]" if {[string length $report]+[string length $etc]<80} { append report $etc } + # append report " $pct%" } puts -nonewline [format %-79.79s $report]\r flush stdout diff --git a/test/testrunner_estwork.tcl b/test/testrunner_estwork.tcl new file mode 100644 index 0000000000..c139394a56 --- /dev/null +++ b/test/testrunner_estwork.tcl @@ -0,0 +1,488 @@ +# Estimated relative cost of various jobs, based on the "estkey" field. +# Computed by the "test/testrunner.tcl estwork" command. +# +set estwork((fuzzcheck)) 1291 +set estwork((fuzzcheck-asan)) 2427 +set estwork((fuzzcheck-ubsan)) 2749 +set estwork((sessionfuzz)) 1276 +set estwork((sqlite3)) 1281 +set estwork((testfixture)) 1546 +set estwork(aggerror.test) 5 +set estwork(alter.test) 20 +set estwork(alter3.test) 2 +set estwork(alterauth.test) 5 +set estwork(altercol.test) 5 +set estwork(alterdropcol.test) 17 +set estwork(alterlegacy.test) 2 +set estwork(altertab.test) 34 +set estwork(altertab2.test) 2 +set estwork(altertab3.test) 12 +set estwork(amatch1.test) 40 +set estwork(atof1.test) 146 +set estwork(atomic2.test) 2 +set estwork(auth.test) 2 +set estwork(autoindex1.test) 5 +set estwork(autoindex3.test) 5 +set estwork(autovacuum.test) 15 +set estwork(avfs.test) 16 +set estwork(avtrans.test) 285 +set estwork(backup2.test) 15 +set estwork(bestindex4.test) 12 +set estwork(bigrow.test) 5 +set estwork(bitvec.test) 94 +set estwork(bld) 99 +set estwork(blob.test) 2 +set estwork(boundary1.test) 8 +set estwork(boundary2.test) 16 +set estwork(boundary3.test) 14 +set estwork(btree01.test) 20 +set estwork(busy.test) 2 +set estwork(busy2.test) 288 +set estwork(capi3.test) 5 +set estwork(capi3b.test) 6 +set estwork(capi3c.test) 5 +set estwork(capi3d.test) 8 +set estwork(capi3e.test) 20 +set estwork(changes.test) 11 +set estwork(chunksize.test) 5 +set estwork(closure01.test) 63 +set estwork(collate5.test) 2 +set estwork(conflict.test) 8 +set estwork(conflict2.test) 4 +set estwork(conflict3.test) 8 +set estwork(corrupt2.test) 2 +set estwork(corrupt4.test) 91 +set estwork(corrupt7.test) 5 +set estwork(corrupt8.test) 3 +set estwork(corruptB.test) 4 +set estwork(corruptF.test) 6 +set estwork(count.test) 18 +set estwork(crash8.test) 14 +set estwork(createtab.test) 3 +set estwork(csv01.test) 7 +set estwork(cursorhint.test) 4 +set estwork(date.test) 17 +set estwork(date4.test) 64 +set estwork(date5.test) 3 +set estwork(dbdata.test) 77 +set estwork(dbfuzz001.test) 2 +set estwork(dbstatus.test) 4 +set estwork(decimal.test) 2 +set estwork(delete.test) 4 +set estwork(diskfull.test) 34 +set estwork(e_blobbytes.test) 11 +set estwork(e_createtable.test) 14 +set estwork(e_delete.test) 3 +set estwork(e_droptrigger.test) 6 +set estwork(e_dropview.test) 2 +set estwork(e_expr.test) 251 +set estwork(e_select.test) 5 +set estwork(e_select2.test) 5 +set estwork(e_vacuum.test) 6 +set estwork(e_walauto.test) 51 +set estwork(e_walckpt.test) 6 +set estwork(enc.test) 2 +set estwork(enc3.test) 11 +set estwork(enc4.test) 3 +set estwork(eval.test) 2 +set estwork(exists.test) 4 +set estwork(existsexpr.test) 44 +set estwork(expert1.test) 14 +set estwork(expr.test) 5 +set estwork(filectrl.test) 5 +set estwork(filefmt.test) 6 +set estwork(fkey2.test) 9 +set estwork(fpconv1.test) 40 +set estwork(fts3aa.test) 18 +set estwork(fts3ad.test) 10 +set estwork(fts3ag.test) 6 +set estwork(fts3aj.test) 8 +set estwork(fts3am.test) 5 +set estwork(fts3auto.test) 29 +set estwork(fts3b.test) 41 +set estwork(fts3c.test) 22 +set estwork(fts3conf.test) 3 +set estwork(fts3corrupt4.test) 7 +set estwork(fts3corrupt5.test) 8 +set estwork(fts3corrupt6.test) 13 +set estwork(fts3d.test) 2 +set estwork(fts3defer2.test) 2 +set estwork(fts3expr.test) 10 +set estwork(fts3expr2.test) 8 +set estwork(fts3expr3.test) 145 +set estwork(fts3f.test) 9 +set estwork(fts3first.test) 3 +set estwork(fts3matchinfo.test) 4 +set estwork(fts3misc.test) 54 +set estwork(fts3prefix.test) 4 +set estwork(fts3prefix2.test) 8 +set estwork(fts3query.test) 23 +set estwork(fts3varint.test) 2 +set estwork(fts4aa.test) 34 +set estwork(fts4content.test) 5 +set estwork(fts4incr.test) 19 +set estwork(fts4noti.test) 3 +set estwork(fts4opt.test) 129 +set estwork(fts4unicode.test) 45 +set estwork(fts5aa.test) 442 +set estwork(fts5ab.test) 54 +set estwork(fts5ad.test) 33 +set estwork(fts5ae.test) 3 +set estwork(fts5af.test) 13 +set estwork(fts5ag.test) 13 +set estwork(fts5ah.test) 265 +set estwork(fts5al.test) 2 +set estwork(fts5auto.test) 92 +set estwork(fts5connect.test) 5 +set estwork(fts5content.test) 9 +set estwork(fts5contentless.test) 23 +set estwork(fts5contentless2.test) 189 +set estwork(fts5contentless4.test) 234 +set estwork(fts5contentless5.test) 9 +set estwork(fts5delete.test) 62 +set estwork(fts5doclist.test) 11 +set estwork(fts5expr.test) 10 +set estwork(fts5full.test) 42 +set estwork(fts5hash.test) 17 +set estwork(fts5integrity.test) 84 +set estwork(fts5interrupt.test) 16 +set estwork(fts5locale.test) 5 +set estwork(fts5matchinfo.test) 11 +set estwork(fts5merge.test) 29 +set estwork(fts5merge2.test) 9 +set estwork(fts5misc.test) 8 +set estwork(fts5multiclient.test) 2 +set estwork(fts5optimize.test) 13 +set estwork(fts5optimize2.test) 737 +set estwork(fts5optimize3.test) 280 +set estwork(fts5origintext.test) 144 +set estwork(fts5origintext3.test) 8 +set estwork(fts5origintext4.test) 30 +set estwork(fts5origintext5.test) 462 +set estwork(fts5origintext6.test) 55 +set estwork(fts5porter.test) 57 +set estwork(fts5query.test) 8 +set estwork(fts5restart.test) 10 +set estwork(fts5rowid.test) 35 +set estwork(fts5secure.test) 61 +set estwork(fts5secure3.test) 796 +set estwork(fts5secure4.test) 141 +set estwork(fts5secure5.test) 29 +set estwork(fts5secure6.test) 33 +set estwork(fts5secure7.test) 680 +set estwork(fts5simple.test) 7 +set estwork(fts5simple2.test) 2 +set estwork(fts5synonym.test) 13 +set estwork(fts5synonym2.test) 384 +set estwork(fts5tok2.test) 92 +set estwork(fts5tokenizer.test) 2 +set estwork(fts5tokenizer3.test) 8 +set estwork(fts5trigram.test) 2 +set estwork(fts5unicode2.test) 28 +set estwork(fts5unicode3.test) 72 +set estwork(fts5unindexed.test) 7 +set estwork(fts5update.test) 161 +set estwork(fts5update2.test) 11 +set estwork(fts5vocab.test) 11 +set estwork(fts5vocab2.test) 15 +set estwork(func.test) 36 +set estwork(fuzz) 68 +set estwork(fuzz-oss1.test) 11 +set {estwork(fuzzcheck --slice)} 499 +set {estwork(fuzzcheck fuzzdata1.db)} 301 +set {estwork(fuzzcheck fuzzdata2.db)} 275 +set {estwork(fuzzcheck fuzzdata3.db)} 72 +set {estwork(fuzzcheck fuzzdata4.db)} 30 +set {estwork(fuzzcheck fuzzdata5.db)} 299 +set {estwork(fuzzcheck fuzzdata6.db)} 91 +set {estwork(fuzzcheck fuzzdata7.db)} 201 +set {estwork(fuzzcheck fuzzdata8.db)} 331 +set {estwork(fuzzcheck-asan --slice)} 2037 +set {estwork(fuzzcheck-asan fuzzdata1.db)} 3112 +set {estwork(fuzzcheck-asan fuzzdata2.db)} 8753 +set {estwork(fuzzcheck-asan fuzzdata3.db)} 459 +set {estwork(fuzzcheck-asan fuzzdata4.db)} 123 +set {estwork(fuzzcheck-asan fuzzdata5.db)} 1178 +set {estwork(fuzzcheck-asan fuzzdata6.db)} 1356 +set {estwork(fuzzcheck-asan fuzzdata7.db)} 938 +set {estwork(fuzzcheck-asan fuzzdata8.db)} 1451 +set {estwork(fuzzcheck-ubsan --slice)} 1729 +set {estwork(fuzzcheck-ubsan fuzzdata1.db)} 1180 +set {estwork(fuzzcheck-ubsan fuzzdata2.db)} 876 +set {estwork(fuzzcheck-ubsan fuzzdata3.db)} 306 +set {estwork(fuzzcheck-ubsan fuzzdata4.db)} 95 +set {estwork(fuzzcheck-ubsan fuzzdata5.db)} 1356 +set {estwork(fuzzcheck-ubsan fuzzdata6.db)} 333 +set {estwork(fuzzcheck-ubsan fuzzdata7.db)} 883 +set {estwork(fuzzcheck-ubsan fuzzdata8.db)} 1124 +set estwork(fuzzer1.test) 6 +set estwork(gencol1.test) 3 +set estwork(hook.test) 2 +set estwork(in4.test) 4 +set estwork(in7.test) 6 +set estwork(incrblob2.test) 2 +set estwork(incrblob3.test) 5 +set estwork(incrvacuum.test) 10 +set estwork(incrvacuum2.test) 17 +set estwork(incrvacuum3.test) 17 +set estwork(index.test) 3 +set estwork(index2.test) 8 +set estwork(index4.test) 33 +set estwork(index5.test) 99 +set estwork(index6.test) 2 +set estwork(indexexpr1.test) 2 +set estwork(insert3.test) 5 +set estwork(insert4.test) 2 +set estwork(intarray.test) 8 +set estwork(intck1.test) 34 +set estwork(intck2.test) 37 +set estwork(interrupt.test) 28 +set estwork(io.test) 3 +set estwork(join.test) 3 +set estwork(join3.test) 6 +set estwork(join5.test) 20 +set estwork(join7.test) 2 +set estwork(join8.test) 3 +set estwork(join9.test) 2 +set estwork(joinA.test) 11 +set estwork(joinB.test) 7 +set estwork(joinC.test) 6 +set estwork(joinD.test) 168 +set estwork(json103.test) 6 +set estwork(json106.test) 690 +set estwork(keyword1.test) 3 +set estwork(like2.test) 2 +set estwork(like3.test) 2 +set estwork(limit.test) 3 +set estwork(literal.test) 6 +set estwork(lock.test) 39 +set estwork(lock4.test) 2 +set estwork(lock5.test) 4 +set estwork(make) 102 +set estwork(manydb.test) 12 +set estwork(mem5.test) 2 +set estwork(memdb.test) 9 +set estwork(memdb1.test) 2 +set estwork(memjournal2.test) 164 +set estwork(memsubsys1.test) 8 +set estwork(misc1.test) 6 +set estwork(misc2.test) 6 +set estwork(misc5.test) 11 +set estwork(misc8.test) 5 +set estwork(mmap1.test) 8 +set estwork(mmap2.test) 10 +set estwork(mmapwarm.test) 2 +set estwork(multiplex.test) 30 +set estwork(multiplex2.test) 7 +set estwork(nan.test) 2 +set estwork(notify3.test) 5 +set estwork(orderby1.test) 11 +set estwork(orderby2.test) 2 +set estwork(orderby5.test) 11 +set estwork(orderby6.test) 6 +set estwork(orderby8.test) 20 +set estwork(orderbyA.test) 2 +set estwork(oserror.test) 7 +set estwork(ovfl.test) 11 +set estwork(pager1.test) 81 +set estwork(pager2.test) 129 +set estwork(pagesize.test) 3 +set estwork(percentile.test) 86 +set estwork(pragma.test) 4 +set estwork(pragma4.test) 18 +set estwork(printf.test) 21 +set estwork(printf2.test) 5 +set estwork(quota.test) 14 +set estwork(randexpr1.test) 35 +set estwork(rbu10.test) 16 +set estwork(rbu13.test) 5 +set estwork(rbuexlock.test) 5 +set estwork(rbumisc.test) 2 +set estwork(rbutemplimit.test) 2 +set estwork(readonly.test) 95 +set estwork(recover.test) 3 +set estwork(recover1.test) 7 +set estwork(recovercorrupt3.test) 5 +set estwork(recoverold.test) 7 +set estwork(recoverpgsz.test) 6 +set estwork(recoverrowid.test) 3 +set estwork(returning1.test) 6 +set estwork(rollback2.test) 2 +set estwork(round1.test) 261 +set estwork(rowhash.test) 85 +set estwork(rowid.test) 3 +set estwork(rowvalue.test) 2 +set estwork(rowvalue2.test) 38 +set estwork(rowvalue4.test) 2 +set estwork(rowvalueA.test) 2 +set estwork(rowvaluevtab.test) 2 +set estwork(rtree1.test) 4 +set estwork(rtree2.test) 758 +set estwork(rtree6.test) 6 +set estwork(rtree8.test) 15 +set estwork(rtree9.test) 15 +set estwork(rtreeA.test) 7 +set estwork(rtreeB.test) 7 +set estwork(rtreeE.test) 47 +set estwork(rtreeH.test) 24 +set estwork(rtreecheck.test) 2 +set estwork(rtreedoc.test) 8 +set estwork(rtreedoc3.test) 76 +set estwork(savepoint.test) 10 +set estwork(savepoint2.test) 57 +set estwork(schema2.test) 15 +set estwork(schema3.test) 2 +set estwork(schema5.test) 5 +set estwork(select1.test) 2 +set estwork(select2.test) 17 +set estwork(select3.test) 2 +set estwork(selectA.test) 2 +set estwork(selectB.test) 2 +set estwork(selectG.test) 30 +set estwork(session1.test) 5 +set estwork(session2.test) 33 +set estwork(session5.test) 63 +set estwork(session9.test) 3 +set estwork(sessionG.test) 60 +set estwork(sessionH.test) 18 +set estwork(sessionalter.test) 3 +set estwork(sessionat.test) 2 +set estwork(sessionblob.test) 3 +set {estwork(sessionfuzz sessionfuzz-data1.db)} 5 +set estwork(sessioninvert.test) 2 +set estwork(sessionnoop.test) 2 +set estwork(sessionnoop2.test) 8 +set estwork(sessionrebase.test) 8 +set estwork(shared.test) 7 +set estwork(sharedA.test) 48 +set estwork(shell1.test) 36 +set estwork(shell2.test) 11 +set estwork(shell3.test) 3 +set estwork(shell4.test) 2 +set estwork(shell5.test) 16 +set estwork(shell6.test) 3 +set estwork(shell8.test) 104 +set estwork(shell9.test) 3 +set estwork(shellA.test) 2 +set estwork(shmlock.test) 27 +set estwork(sidedelete.test) 10 +set estwork(skipscan1.test) 7 +set estwork(skipscan2.test) 5 +set estwork(sort.test) 38 +set estwork(sort2.test) 540 +set estwork(sort5.test) 16 +set estwork(spellfix.test) 5 +set estwork(spellfix2.test) 5 +set estwork(spellfix4.test) 11 +set estwork(starschema1.test) 2 +set estwork(strict1.test) 5 +set estwork(swarmvtab.test) 110 +set estwork(swarmvtab3.test) 14 +set estwork(syscall.test) 4 +set estwork(table.test) 62 +set estwork(tableapi.test) 8 +set estwork(tcl) 1 +set estwork(tclsqlite.test) 29 +set estwork(temptable2.test) 274 +set estwork(thread3.test) 21 +set estwork(timediff1.test) 5 +set estwork(tkt-2d1a5c67d.test) 6 +set estwork(tkt-38cb5df375.test) 2 +set estwork(tkt-4dd95f6943.test) 2 +set estwork(tkt-5e10420e8d.test) 5 +set estwork(tkt-6bfb98dfc0.test) 5 +set estwork(tkt-80e031a00f.test) 25 +set estwork(tkt-9d68c883.test) 3 +set estwork(tkt-9f2eb3abac.test) 5 +set estwork(tkt-b1d3a2e531.test) 5 +set estwork(tkt-b72787b1.test) 5 +set estwork(tkt-b75a9ca6b0.test) 8 +set estwork(tkt-d11f09d36e.test) 9 +set estwork(tkt-fc62af4523.test) 10 +set estwork(tkt1435.test) 7 +set estwork(tkt1644.test) 5 +set estwork(tkt1667.test) 20 +set estwork(tkt1873.test) 2 +set estwork(tkt2192.test) 3 +set estwork(tkt2285.test) 19 +set estwork(tkt2332.test) 2 +set estwork(tkt2409.test) 24 +set estwork(tkt3334.test) 5 +set estwork(tkt3357.test) 10 +set estwork(tkt3630.test) 2 +set estwork(tkt3832.test) 8 +set estwork(tkt3838.test) 5 +set estwork(tkt3918.test) 3 +set estwork(tkt4018.test) 48 +set estwork(tokenize.test) 9 +set estwork(tpch01.test) 6 +set estwork(trans.test) 258 +set estwork(trigger2.test) 15 +set estwork(trigger5.test) 2 +set estwork(trigger8.test) 30 +set estwork(triggerA.test) 36 +set estwork(triggerB.test) 4 +set estwork(triggerC.test) 67 +set estwork(triggerD.test) 3 +set estwork(types.test) 2 +set estwork(types2.test) 2 +set estwork(unionall2.test) 9 +set estwork(unionvtab.test) 2 +set estwork(update.test) 7 +set estwork(upsert3.test) 6 +set estwork(upsert5.test) 5 +set estwork(vacuum.test) 2 +set estwork(vacuum5.test) 3 +set estwork(vacuum6.test) 174 +set estwork(vacuummem.test) 132 +set estwork(varint.test) 8 +set estwork(view.test) 2 +set estwork(vtab1.test) 13 +set estwork(vtab6.test) 12 +set estwork(vtabC.test) 33 +set estwork(vtabD.test) 56 +set estwork(vtab_alter.test) 6 +set estwork(wal.test) 38 +set estwork(wal2.test) 7 +set estwork(wal3.test) 196 +set estwork(wal4.test) 70 +set estwork(wal5.test) 22 +set estwork(wal64k.test) 20 +set estwork(wal7.test) 3 +set estwork(wal9.test) 24 +set estwork(walbak.test) 2 +set estwork(walcksum.test) 3 +set estwork(walcrash4.test) 59 +set estwork(waloverwrite.test) 3 +set estwork(walpersist.test) 6 +set estwork(walprotocol2.test) 2 +set estwork(walro2.test) 11 +set estwork(walsetlk.test) 1610 +set estwork(walsetlk3.test) 3 +set estwork(walsetlk_recover.test) 193 +set estwork(walshared.test) 5 +set estwork(walvfs.test) 476 +set estwork(where.test) 24 +set estwork(where3.test) 4 +set estwork(where6.test) 2 +set estwork(where7.test) 20 +set estwork(where8.test) 95 +set estwork(where9.test) 16 +set estwork(whereB.test) 5 +set estwork(whereE.test) 6 +set estwork(whereN.test) 2 +set estwork(window1.test) 5 +set estwork(window2.test) 8 +set estwork(window3.test) 89 +set estwork(window4.test) 3 +set estwork(window5.test) 2 +set estwork(window8.test) 33 +set estwork(windowA.test) 5 +set estwork(windowD.test) 6 +set estwork(with1.test) 114 +set estwork(with2.test) 4 +set estwork(with5.test) 2 +set estwork(withM.test) 4 +set estwork(without_rowid1.test) 2 +set estwork(without_rowid3.test) 9 +set estwork(without_rowid4.test) 6 From c066f2af9cad84df6025127105eb79af8f478ba0 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 10:27:06 +0000 Subject: [PATCH 67/88] Do not export the numerous Emscripten HEAPxy symbols and remove the last remaining JS code which references them. They have long-since been replaced by internal equivalents and a specific feature check on one of them (which is also no longer needed) is triggering an exception from Emscripten. More details are in [https://github.com/emscripten-core/emscripten/issues/24656 | Emscripten ticket #24656], noting that this is not an Emscripten bug but an Emscripten behavior change brought it to light. FossilOrigin-Name: b9462dc1461c830466f4e1de4a4d3bf249e3f81aea363f13462ea915769878d9 --- ext/wasm/GNUmakefile | 4 ++-- ext/wasm/api/sqlite3-api-prologue.js | 17 +---------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index bf1a49111c..0ae814c2da 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -617,9 +617,9 @@ emcc.jsflags += -sDYNAMIC_EXECUTION=0 emcc.jsflags += -sNO_POLYFILL emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.api) emcc.exportedRuntimeMethods := \ - -sEXPORTED_RUNTIME_METHODS=wasmMemory,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAP64,HEAPU64 + -sEXPORTED_RUNTIME_METHODS=wasmMemory # wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY -# Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default +# Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default. emcc.jsflags += $(emcc.exportedRuntimeMethods) emcc.jsflags += -sUSE_CLOSURE_COMPILER=0 emcc.jsflags += -sIMPORTED_MEMORY diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 7e128a3fa9..e3807a314c 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -134,22 +134,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( const config = Object.assign(Object.create(null),{ exports: undefined, memory: undefined, - bigIntEnabled: (()=>{ - if('undefined'!==typeof Module){ - /* Emscripten module will contain HEAPU64 when built with - -sWASM_BIGINT=1, else it will not. - - As of emsdk 3.1.55, when building in strict mode, HEAPxyz - are only available if _explicitly_ included in the exports, - else they are not. We do not (as of 2024-03-04) use -sSTRICT - for the canonical builds. - */ - if( !!Module.HEAPU64 ) return true; - /* Else fall through and hope for the best. Nobody _really_ - builds this without BigInt support, do they? */ - } - return !!globalThis.BigInt64Array; - })(), + bigIntEnabled: !!globalThis.BigInt64Array, debug: console.debug.bind(console), warn: console.warn.bind(console), error: console.error.bind(console), diff --git a/manifest b/manifest index 11f8082b65..b23a5e29be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\saccuracy\sof\sthe\sETC\son\sboth\sdevtest\sand\sreleasetest. -D 2025-07-10T20:45:00.900 +C Do\snot\sexport\sthe\snumerous\sEmscripten\sHEAPxy\ssymbols\sand\sremove\sthe\slast\sremaining\sJS\scode\swhich\sreferences\sthem.\sThey\shave\slong-since\sbeen\sreplaced\sby\sinternal\sequivalents\sand\sa\sspecific\sfeature\scheck\son\sone\sof\sthem\s(which\sis\salso\sno\slonger\sneeded)\sis\striggering\san\sexception\sfrom\sEmscripten.\sMore\sdetails\sare\sin\s[https://github.com/emscripten-core/emscripten/issues/24656\s|\sEmscripten\sticket\s#24656],\snoting\sthat\sthis\sis\snot\san\sEmscripten\sbug\sbut\san\sEmscripten\sbehavior\schange\sbrought\sit\sto\slight. +D 2025-07-11T10:27:06.737 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -621,7 +621,7 @@ F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af1 F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile a05bb1766f97c88cb42fbfe9e349c799c691f8ae0dc959e9d9469f0bcee89350 +F ext/wasm/GNUmakefile fa694fe78fc0acfd4406a36133ce4aff8820e086f4dd5f1473d2fafce590ab64 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -642,7 +642,7 @@ F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ad F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa F ext/wasm/api/sqlite3-api-oo1.c-pp.js c68d6da0088c2527156fca9163a721abe08e7bd077b15404fd8d292f4612adc1 -F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 +F ext/wasm/api/sqlite3-api-prologue.js 4f1c2a9dc9caf631907766e9872c27d11b255ccae779e8af01c7f8b932817214 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966 @@ -2212,8 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9eccf5267c6423c9dd4da1d61b62bbb6fbba44fb8089da79f89c84e8b77ff0f0 -R 72101457f4e8f2d4243e574d79fb694e -U drh -Z fd661df697accbf37239cc80ab12a734 +P a3f96cafdc0e1f2eeccc6509f1f9c26d2c48668953550f299cf2805a0a063014 +R a1e55e82ed031f25d914104fdc2c36ac +U stephan +Z 397ec1f53e01f1452d38366e80f3e612 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2fd45c96e2..64cd0358a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3f96cafdc0e1f2eeccc6509f1f9c26d2c48668953550f299cf2805a0a063014 +b9462dc1461c830466f4e1de4a4d3bf249e3f81aea363f13462ea915769878d9 From 0eca9db776ceb7fa979e1da638256fde912ae2e0 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 11:06:25 +0000 Subject: [PATCH 68/88] speedtest1: in WASM builds, disable the "app" test set by default because that one set is triggering file-not-found errors for the db file for reasons not yet understood. FossilOrigin-Name: 9d68971c58261bce72b49c574cf07ad31add62bee814c58840b927fed7eb87b1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 14 +++++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b23a5e29be..5bb39a23db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sexport\sthe\snumerous\sEmscripten\sHEAPxy\ssymbols\sand\sremove\sthe\slast\sremaining\sJS\scode\swhich\sreferences\sthem.\sThey\shave\slong-since\sbeen\sreplaced\sby\sinternal\sequivalents\sand\sa\sspecific\sfeature\scheck\son\sone\sof\sthem\s(which\sis\salso\sno\slonger\sneeded)\sis\striggering\san\sexception\sfrom\sEmscripten.\sMore\sdetails\sare\sin\s[https://github.com/emscripten-core/emscripten/issues/24656\s|\sEmscripten\sticket\s#24656],\snoting\sthat\sthis\sis\snot\san\sEmscripten\sbug\sbut\san\sEmscripten\sbehavior\schange\sbrought\sit\sto\slight. -D 2025-07-11T10:27:06.737 +C speedtest1:\sin\sWASM\sbuilds,\sdisable\sthe\s"app"\stest\sset\sby\sdefault\sbecause\sthat\sone\sset\sis\striggering\sfile-not-found\serrors\sfor\sthe\sdb\sfile\sfor\sreasons\snot\syet\sunderstood. +D 2025-07-11T11:06:25.274 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1689,7 +1689,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c F test/speedtest.md ee958457ae1b729d9715ae33c0320600000bf1d9ddea1a88dcf79f56729d6fad F test/speedtest.tcl 405411356fbc54af15987b7ffeec330a49138f71584220fb8fe1948b2f7ac907 x -F test/speedtest1.c 64b8804b053a796eab22f8b23fb181000f05d7b3e2aa44f022117ea543bc5a2a +F test/speedtest1.c a9b002a7bfed99ba3166c2a9b8ae45a95b4c2d37f891e1637c022f9e1d15e3f9 F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -2212,8 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a3f96cafdc0e1f2eeccc6509f1f9c26d2c48668953550f299cf2805a0a063014 -R a1e55e82ed031f25d914104fdc2c36ac +P b9462dc1461c830466f4e1de4a4d3bf249e3f81aea363f13462ea915769878d9 +R e406216e09aca8ec86fc937423446783 U stephan -Z 397ec1f53e01f1452d38366e80f3e612 +Z c61801d5a56ae16f81bbbf5139f256d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 64cd0358a6..fa03335778 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9462dc1461c830466f4e1de4a4d3bf249e3f81aea363f13462ea915769878d9 +9d68971c58261bce72b49c574cf07ad31add62bee814c58840b927fed7eb87b1 diff --git a/test/speedtest1.c b/test/speedtest1.c index 10cd30f1c7..968f2cb00b 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -159,6 +159,12 @@ static void fatal_error(const char *zMsg, ...){ va_start(ap, zMsg); vfprintf(stderr, zMsg, ap); va_end(ap); +#ifdef SQLITE_SPEEDTEST1_WASM + /* Emscripten complains when exit() is called and anything is left + in the I/O buffers. */ + fflush(stdout); + fflush(stderr); +#endif exit(1); } @@ -2994,7 +3000,13 @@ int main(int argc, char **argv){ /* "mix1" is a macro testset: */ static char zMix1Tests[] = - "main,orm/25,cte/20,json,fp/3,parsenumber/25,rtree/10,star,app"; + "main,orm/25,cte/20,json,fp/3,parsenumber/25,rtree/10,star" +#if !defined(SQLITE_SPEEDTEST1_WASM) + ",app" + /* This test misbehaves in WASM builds: sqlite3_open_v2() is + failing to find the db file for reasons not yet understood. */ +#endif + ; #ifdef SQLITE_SPEEDTEST1_WASM /* Resetting all state is important for the WASM build, which may From 69b5674b40932e483ba90e8c63d15901eae408e9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 11 Jul 2025 17:02:11 +0000 Subject: [PATCH 69/88] Additional header comment documentation in the ext/misc/vtablog.c test extension. FossilOrigin-Name: 3656acfaa3011321a6e17fb81e5bdedcfffeab6035f133ab89ae9589bf5bef72 --- ext/misc/vtablog.c | 7 +++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c index e8e29a86ee..44acc32e67 100644 --- a/ext/misc/vtablog.c +++ b/ext/misc/vtablog.c @@ -14,6 +14,13 @@ ** on stdout when its key interfaces are called. This is intended for ** interactive analysis and debugging of virtual table interfaces. ** +** To build this extension as a separately loaded shared library or +** DLL, use compiler command-lines similar to the following: +** +** (linux) gcc -fPIC -shared vtablog.c -o vtablog.so +** (mac) clang -fPIC -dynamiclib vtablog.c -o vtablog.dylib +** (windows) cl vtablog.c -link -dll -out:vtablog.dll +** ** Usage example: ** ** .load ./vtablog diff --git a/manifest b/manifest index 5bb39a23db..afcbfeade0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C speedtest1:\sin\sWASM\sbuilds,\sdisable\sthe\s"app"\stest\sset\sby\sdefault\sbecause\sthat\sone\sset\sis\striggering\sfile-not-found\serrors\sfor\sthe\sdb\sfile\sfor\sreasons\snot\syet\sunderstood. -D 2025-07-11T11:06:25.274 +C Additional\sheader\scomment\sdocumentation\sin\sthe\sext/misc/vtablog.c\stest\sextension. +D 2025-07-11T17:02:11.169 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -456,7 +456,7 @@ F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505 F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c 0b23c0a69a2b63dc0ef0af44f9c1fc977300c480a1f7a9814500369d8211f56e F ext/misc/vfstrace.c 0e4b8b17ac0675ea90f6d168d8214687e06ca3efbc0060aad4814994d82b41fb -F ext/misc/vtablog.c 62d54fb0f4ff9df72ffa44f4a226451a964e1d96ac550f2b8906feebdad00b58 +F ext/misc/vtablog.c 9f7e02e9e8de585f3bfb48405db36c2eb4b680a23a67d7a4b738dd20f6ad7aec F ext/misc/vtshim.c e5bce24ab8c532f4fdc600148718fe1802cb6ed57417f1c1032d8961f72b0e8f F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c @@ -2212,8 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b9462dc1461c830466f4e1de4a4d3bf249e3f81aea363f13462ea915769878d9 -R e406216e09aca8ec86fc937423446783 -U stephan -Z c61801d5a56ae16f81bbbf5139f256d9 +P 9d68971c58261bce72b49c574cf07ad31add62bee814c58840b927fed7eb87b1 +R 5643c35e4f11fb6cf54743a0885fc1f7 +U drh +Z b5fe84fd8bb20fd9110a384dcfcde9c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fa03335778..6e23397d0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d68971c58261bce72b49c574cf07ad31add62bee814c58840b927fed7eb87b1 +3656acfaa3011321a6e17fb81e5bdedcfffeab6035f133ab89ae9589bf5bef72 From c493e4516aa4b45f98c29e546bb424974839846a Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 19:34:30 +0000 Subject: [PATCH 70/88] Correct a one-too-many-exclamation-points bug which caused the opposite of intended semantics in oo1.Stmt.pointer ownership. FossilOrigin-Name: 91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 2 +- ext/wasm/tester1.c-pp.js | 9 ++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 1473e4e45e..f92dde48a7 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -532,7 +532,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - if( arguments.length>3 && !!arguments[3] ){ + if( arguments.length>3 && !arguments[3] ){ __doesNotOwnHandle.add(this); } }; diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index f2fdeebed6..dd70024abb 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1273,15 +1273,22 @@ globalThis.sqlite3InitModule = sqlite3InitModule; } T.assert( dw===dw.exec("select 1") ); dw.affirmOpen(); - rc = capi.sqlite3_prepare_v2( dw, "select 1", -1, ppOut, 0 ); + const select1 = "select 1"; + rc = capi.sqlite3_prepare_v2( dw, select1, -1, ppOut, 0 ); T.assert( 0===rc, 'prepare_v2() rc='+rc ); pStmt = wasm.peekPtr(ppOut); + T.assert( pStmt && wasm.isPtr(pStmt), 'pStmt is valid?' ); try { + //log( "capi.sqlite3_sql() =",capi.sqlite3_sql(pStmt)); + T.assert( select1 === capi.sqlite3_sql(pStmt), 'SQL mismatch' ); q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, false); + //log("q@"+pStmt+" does not own handle"); T.assert( q.step(), "step()" ) .assert( !q.step(), "!step()" ); q.finalize(); q = undefined; + T.assert( select1 === capi.sqlite3_sql(pStmt), 'SQL mismatch' + /* This will fail if we've mismanaged pStmt's lifetime */); q = sqlite3.oo1.Stmt.wrapHandle(dw, pStmt, true); pStmt = 0; q.reset(); diff --git a/manifest b/manifest index 20cc623889..cc57a87555 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sJS\sdoc\stweaks. -D 2025-07-10T09:25:57.652 +C Correct\sa\sone-too-many-exclamation-points\sbug\swhich\scaused\sthe\sopposite\sof\sintended\ssemantics\sin\soo1.Stmt.pointer\sownership. +D 2025-07-11T19:34:30.706 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js bc472af6c3aada06ad94b332bf23cef2407932e5bb4c0c34c12a6ced343c2e51 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 19067fa3939d355db7bb5b02ee79dbb5e7ca4a8bd24216e24a2b4320b81ebb8d F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 830749ee21bde538f52e150878c0078a3f6d294ba183900efd8488a9e6debf4f +F ext/wasm/tester1.c-pp.js 0abba4bd54f6b22adaadf836c04d3163399f7a8a490fd60f20daac5f9c42b47d F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0ee19db02a9b9320681d4393d9ba52889d149eac8ee114fc7b7f52a57271c139 -R 9671bcb7870e122ad1976f1fae21a064 +P 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f +R 3857d6c93e170f8a2978e6a4274a481e U stephan -Z adaaff03d3b0b893bc2eaac10b306778 +Z 42d47a808b11dbced254adeb3041a5ca # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 963b157be5..2eca880dc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f +91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 From 1f68085849b247a6a1773603cd56d915a1c5ce92 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 11 Jul 2025 19:44:42 +0000 Subject: [PATCH 71/88] Clearer docs for the unowned db/stmt handle mechanism. FossilOrigin-Name: 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 --- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 15 +++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index f92dde48a7..62c44fa9d0 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -39,12 +39,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const __ptrMap = new WeakMap(); /** A Set of oo1.DB or oo1.Stmt objects which are proxies for - (sqlite3*) resp. (sqlite3_stmt*) pointers. Such objects - optionally do not own their underlying handle and that handle - must be guaranteed (by the client) to outlive the proxy. These - proxies are primarily intended as a way to briefly wrap an - (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking over - ownership. + (sqlite3*) resp. (sqlite3_stmt*) pointers which themselves are + owned elsewhere. Objects in this Set do not own their underlying + handle and that handle must be guaranteed (by the client) to + outlive the proxy. DB.close()/Stmt.finalize() methods will remove + the object from this Set _instead_ of closing/finalizing the + pointer. These proxies are primarily intended as a way to briefly + wrap an (sqlite3[_stmt]*) object as an oo1.DB/Stmt without taking + over ownership, to take advantage of simplifies usage compared to + the C API while not imposing any change of ownership. See DB.wrapHandle() and Stmt.wrapHandle(). */ diff --git a/manifest b/manifest index cc57a87555..cc2bf20443 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sa\sone-too-many-exclamation-points\sbug\swhich\scaused\sthe\sopposite\sof\sintended\ssemantics\sin\soo1.Stmt.pointer\sownership. -D 2025-07-11T19:34:30.706 +C Clearer\sdocs\sfor\sthe\sunowned\sdb/stmt\shandle\smechanism. +D 2025-07-11T19:44:42.921 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -641,7 +641,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js 19067fa3939d355db7bb5b02ee79dbb5e7ca4a8bd24216e24a2b4320b81ebb8d +F ext/wasm/api/sqlite3-api-oo1.c-pp.js f59e59f0d94ba5835c6b7fc9b800a4aa5084e1224721a07e3cd6cc7fef1789c2 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 34d893b4837be8bb679e9809befd98201dd79c8d2054f41429b18793b77e840f -R 3857d6c93e170f8a2978e6a4274a481e +P 91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 +R e5c4d3b625713e6da11932841f2fcce9 U stephan -Z 42d47a808b11dbced254adeb3041a5ca +Z 9fc18e96946cc270569853caeaa690c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2eca880dc5..6fca69ff3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91e709f36d36174534b4cf4ff548a558e66cca5e23a6c8c106bc43375fc3ce72 +53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 From bcfe38b96a0898846caf1251faf2dbf32f942ad5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 12 Jul 2025 18:14:41 +0000 Subject: [PATCH 72/88] Avoid evaluating special vtab operators (e.g. MATCH) that are part of ON clauses attached to left joins from being evaluated too early. Possible fix for [forum:/forumpost/428ef7c468 | forum post 428ef7c468]. FossilOrigin-Name: 18ba07c152294a96d510a7851a0860f982ff1e0725afeebed9a343f550f6925a --- ext/fts5/test/fts5leftjoin.test | 49 +++++++++++++++++++++++++++++++++ manifest | 22 ++++++++------- manifest.uuid | 2 +- src/whereexpr.c | 2 +- test/between.test | 12 ++++++++ 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/ext/fts5/test/fts5leftjoin.test b/ext/fts5/test/fts5leftjoin.test index 4ef6a8961b..69a172bd45 100644 --- a/ext/fts5/test/fts5leftjoin.test +++ b/ext/fts5/test/fts5leftjoin.test @@ -40,4 +40,53 @@ do_execsql_test 1.2 { SELECT * FROM t1 LEFT JOIN vt ON (vt MATCH 'abc') } {1 abc 2 abc} + +do_execsql_test 1.3 { + DELETE FROM t1; + INSERT INTO t1 VALUES(14); +} + +do_execsql_test 1.4 { + SELECT * FROM vt LEFT JOIN t1 ON vt.rowid = 1; +} { + abc 14 + xyz {} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t0 USING fts5(a,b); + INSERT INTO t0(a,b)VALUES(1,0); + CREATE TABLE t1(x); +} + +do_execsql_test 2.1 { + SELECT * FROM t0 LEFT JOIN t1; +} {1 0 {}} + +breakpoint +do_catchsql_test 2.2 { + SELECT * FROM t0 LEFT JOIN t1 ON t0.b MATCH '1'; +} {1 {no query solution}} + +do_execsql_test 2.3 { + SELECT * FROM t0 LEFT JOIN t1 ON +b MATCH '1'; +} {1 0 {}} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE t0 USING fts5(c0, c1); + INSERT INTO t0(c0,c1) VALUES (1,0); +} + +do_catchsql_test 3.1 { + SELECT * FROM t0 + LEFT JOIN ( SELECT 0 AS col_0 ) + ON ((((t0.c1 MATCH '1')AND(CASE WHEN t0.c0 THEN CAST(t0.c1 AS INTEGER) ELSE 1 END)))); +} {1 {no query solution}} + + finish_test diff --git a/manifest b/manifest index e8a27b8956..87abca403e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sintroduce\sthe\ssqlite3.oo1.DB.wrapHandle()\sand\sStmt.wrapHandle()\sAPIs,\swhich\senable\sclients\sto\swrap\s(sqlite3*)\sresp.\s(sqlite3_stmt*)\spointers\sin\stheir\soo1\sAPI\scounterparts,\soptionally\swith\sor\swithout\staking\sover\sownership\sof\sthe\spointer. -D 2025-07-11T19:52:36.729 +C Avoid\sevaluating\sspecial\svtab\soperators\s(e.g.\sMATCH)\sthat\sare\spart\sof\sON\sclauses\sattached\sto\sleft\sjoins\sfrom\sbeing\sevaluated\stoo\searly.\sPossible\sfix\sfor\s[forum:/forumpost/428ef7c468\s|\sforum\spost\s428ef7c468]. +D 2025-07-12T18:14:41.159 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -201,7 +201,7 @@ F ext/fts5/test/fts5integrity.test c423ce16fd1ccadcac7fc22f794226b2bb00f5a187c0a F ext/fts5/test/fts5integrity2.test 4c3636615c0201232c44a8105d5cb14fd5499fd0ee3014d7ffd7e83aac76ece8 F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1 -F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad +F ext/fts5/test/fts5leftjoin.test 1c14b51f4d1344a89e488160882f05a2246dd7e70c5cf077c8fb473e03c66338 F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fce79fa43004dff01c F ext/fts5/test/fts5locale.test 83ba7ee12628b540d3098f39c39c1de0c0440eddff8f7512c8c698d0c4a3ae3c F ext/fts5/test/fts5matchinfo.test bc9e74157773db7f00aec1e85587f1145956ebdf1672c136f0f04323b2752aa0 @@ -870,7 +870,7 @@ F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 6a9266dd1a559d48d8c7ca670a3e80143c7913153f7d1ceb0a4eca1087318951 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da F src/wherecode.c 2a2d2993fd98c46f525f71b3bfd330fde73d8613aa0ff3e20402dd1fc63470af -F src/whereexpr.c 0a7fe115adad30def38aeab6ac1d35fb67782cee92a43df7448136240accd4dd +F src/whereexpr.c 78c28a8da187816d5d82049f2e343fb39f4a8e30b5bf1bda9b96cecde40ca8bd F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d @@ -964,7 +964,7 @@ F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572e F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/bestindexC.test 95b4a527b1a5d07951d731604a6d4cf7e5a806b39cea0e7819d4c9667e11c3fc F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 -F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 +F test/between.test b301ef0d822a26b31235e10a3b7f1130be1565a7ba080e80a3a1ae3ba5a35ff7 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc F test/bigmmap.test 6021e205487347c6d7e5a541aa472a4b8efc4e9f4a3799a823b61a8e6616105d @@ -2212,9 +2212,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3656acfaa3011321a6e17fb81e5bdedcfffeab6035f133ab89ae9589bf5bef72 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 -R 6e106d1cb56322541040e2b7c468c9ad -T +closed 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 Closed\sby\sintegrate-merge. -U stephan -Z f91aebcbb3981855ba9f714a42d1af4f +P e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3 +R eb99b7ab5a76b7191a98fe93227d2428 +T *branch * vtab-leftjoin-fix +T *sym-vtab-leftjoin-fix * +T -sym-trunk * +U dan +Z c80dd1f4987fe05a4ba000eae17152fd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ac45e07d97..786e5c76d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3 +18ba07c152294a96d510a7851a0860f982ff1e0725afeebed9a343f550f6925a diff --git a/src/whereexpr.c b/src/whereexpr.c index e9fa4a1432..0d17b0d752 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1541,7 +1541,7 @@ static void exprAnalyze( idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = prereqExpr; + pNewTerm->prereqRight = prereqExpr | extraRight; pNewTerm->leftCursor = pLeft->iTable; pNewTerm->u.x.leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_AUX; diff --git a/test/between.test b/test/between.test index 16c3913d12..4f09f1afec 100644 --- a/test/between.test +++ b/test/between.test @@ -140,4 +140,16 @@ foreach {tn expr res} { do_execsql_test between-2.1.$tn $sql $res } +#------------------------------------------------------------------------- +reset_db +do_execsql_test between-3.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(4, 4); + CREATE TABLE t2(a, b); +} + +do_execsql_test between-3.1 { + SELECT * FROM t1 LEFT JOIN t2 ON (x BETWEEN 1 AND 3); +} {4 4 {} {}} + finish_test From f8addcf937937d32947a6719675697dcf8824e79 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Jul 2025 09:41:59 +0000 Subject: [PATCH 73/88] Fix harmless compiler warnings in builds that use SQLITE_OMIT_DATETIME_FUNCS. FossilOrigin-Name: e11fbf9fd630a7de2e0b0e4b67dded05b905b2a0ba04aa7e915ca9df2d9ebe21 --- manifest | 19 +++++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/vdbe.h | 2 ++ src/vdbeaux.c | 2 ++ 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e8a27b8956..0ec1a470ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sintroduce\sthe\ssqlite3.oo1.DB.wrapHandle()\sand\sStmt.wrapHandle()\sAPIs,\swhich\senable\sclients\sto\swrap\s(sqlite3*)\sresp.\s(sqlite3_stmt*)\spointers\sin\stheir\soo1\sAPI\scounterparts,\soptionally\swith\sor\swithout\staking\sover\sownership\sof\sthe\spointer. -D 2025-07-11T19:52:36.729 +C Fix\sharmless\scompiler\swarnings\sin\sbuilds\sthat\suse\sSQLITE_OMIT_DATETIME_FUNCS. +D 2025-07-14T09:41:59.400 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -790,7 +790,7 @@ F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bb F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h 9c99d7565a839ad342cdda504c4b7921bb1a24c07227b8f50b7b131245a20693 +F src/sqliteInt.h 984e80f6cfdb1cd65ab465d14d82b6b56af4f7dc308c4bc1da85074a5b4ca755 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -853,10 +853,10 @@ F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 F src/vdbe.c e505b8b879a330e8dafbe3ed9582eae2fc671b44a64748d1b58c07e4e0f527da -F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 +F src/vdbe.h ea1f1b52f0efe422f80d88da3c57e4eadc72856e29a22f1ff08e502ec6ba5f08 F src/vdbeInt.h 626465ff6d673f73a2476dc230b7cd07bdaf4acea9d4ecceaa12a5174bb2c8d7 F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df -F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7 +F src/vdbeaux.c ed06d2892e830b7ad158f81b2b610c918fbb36a0b717b48d299daca80e8264c6 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692 F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21 F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe @@ -2212,9 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3656acfaa3011321a6e17fb81e5bdedcfffeab6035f133ab89ae9589bf5bef72 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 -R 6e106d1cb56322541040e2b7c468c9ad -T +closed 53401b5435e30c4b47b6e203976b714d616246d734b5876a34f53f6388f872f8 Closed\sby\sintegrate-merge. -U stephan -Z f91aebcbb3981855ba9f714a42d1af4f +P e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3 +R 07c15e107127475edb35cdd6de618874 +U drh +Z cde724828852556a37035896eff32ef8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ac45e07d97..31169f768e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3 +e11fbf9fd630a7de2e0b0e4b67dded05b905b2a0ba04aa7e915ca9df2d9ebe21 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7b914d9586..df0e1c3ba4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2166,7 +2166,7 @@ struct FuncDestructor { #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - pArg, 0, xFunc, 0, 0, 0, #zName, } + pArg, 0, xFunc, 0, 0, 0, #zName, {0} } #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } diff --git a/src/vdbe.h b/src/vdbe.h index a7aedfbb0e..9a9cf3dec1 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -314,7 +314,9 @@ int sqlite3VdbeHasSubProgram(Vdbe*); void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); +#ifndef SQLITE_OMIT_DATETIME_FUNCS int sqlite3NotPureFunc(sqlite3_context*); +#endif #ifdef SQLITE_ENABLE_BYTECODE_VTAB int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8a900aeffe..b1406724ed 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5378,6 +5378,7 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ } } +#ifndef SQLITE_OMIT_DATETIME_FUNCS /* ** Cause a function to throw an error if it was call from OP_PureFunc ** rather than OP_Function. @@ -5411,6 +5412,7 @@ int sqlite3NotPureFunc(sqlite3_context *pCtx){ } return 1; } +#endif /* SQLITE_OMIT_DATETIME_FUNCS */ #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) /* From 08f8111bd8145ec6ba364f7fbca1203703851623 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 14 Jul 2025 14:51:43 +0000 Subject: [PATCH 74/88] Add new sessions function sqlite3changeset_apply_v3() and its streaming equivalent. This allows changesets to be filtered on a per-change basis, not just per-table. FossilOrigin-Name: 10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337 --- ext/session/sessionI.test | 88 ++++++++++++++ ext/session/sqlite3session.c | 179 ++++++++++++++++++++++++---- ext/session/sqlite3session.h | 67 +++++++++-- ext/session/test_session.c | 225 ++++++++++++++++++++++------------- manifest | 19 +-- manifest.uuid | 2 +- 6 files changed, 451 insertions(+), 129 deletions(-) create mode 100644 ext/session/sessionI.test diff --git a/ext/session/sessionI.test b/ext/session/sessionI.test new file mode 100644 index 0000000000..2012f24dca --- /dev/null +++ b/ext/session/sessionI.test @@ -0,0 +1,88 @@ +# 2015 July 14 +# +# 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. +# +#*********************************************************************** +# +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionI + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 1.0 { + do_common_sql { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + } +} {} + +set C [changeset_from_sql { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(4, 'four'); + INSERT INTO t1 VALUES(5, 'five'); + INSERT INTO t1 VALUES(6, 'six'); +}] + +do_execsql_test 1.1 { + SELECT * FROM t1 +} { + 1 one 2 two 3 three 4 four 5 five 6 six +} + +proc xFilter {data} { + foreach {op tname flag pk old new} $data {} + if {$op=="INSERT"} { + set ipk [lindex $new 1] + return [expr $ipk % 2] + } + return 1 +} +proc xConflict {args} { +} + +sqlite3changeset_apply_v3 db2 $C xConflict xFilter + +do_execsql_test -db db2 1.2 { + SELECT * FROM t1 +} { + 1 one 3 three 5 five +} + +do_execsql_test -db db2 1.3 { + DELETE FROM t1 +} +sqlite3changeset_apply_v3 db2 $C xConflict + +do_execsql_test -db db2 1.4 { + SELECT * FROM t1 +} { + 1 one 2 two 3 three 4 four 5 five 6 six +} + +proc xFilter2 {data} { + return 0 +} +do_execsql_test -db db2 1.5 { + DELETE FROM t1 +} +sqlite3changeset_apply_v3 db2 $C xConflict xFilter2 +do_execsql_test -db db2 1.6 { + SELECT * FROM t1 +} { } + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 175cacbe86..df40fdc1cf 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -5182,6 +5182,10 @@ static int sessionChangesetApply( void *pCtx, /* Copy of sixth arg to _apply() */ const char *zTab /* Table name */ ), + int(*xFilterIter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p + ), int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ @@ -5322,6 +5326,9 @@ static int sessionChangesetApply( ** next change. A log message has already been issued. */ if( schemaMismatch ) continue; + /* If this is a call to apply_v3(), invoke xFilterIter here. */ + if( xFilterIter && 0==xFilterIter(pCtx, pIter) ) continue; + rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx); } @@ -5389,6 +5396,87 @@ static int sessionChangesetApply( return rc; } +/* +** This function is called by all six sqlite3changeset_apply() variants: +** +** + sqlite3changeset_apply() +** + sqlite3changeset_apply_v2() +** + sqlite3changeset_apply_v3() +** + sqlite3changeset_apply_strm() +** + sqlite3changeset_apply_strm_v2() +** + sqlite3changeset_apply_strm_v3() +** +** Arguments passed to this function are as follows: +** +** db: +** Database handle to apply changeset to main database of. +** +** nChangeset/pChangeset: +** These are both passed zero for the streaming variants. For the normal +** apply() functions, these are passed the size of and the buffer containing +** the changeset, respectively. +** +** xInput/pIn: +** These are both passed zero for the normal variants. For the streaming +** apply() functions, these are passed the input callback and context +** pointer, respectively. +** +** xFilter: +** The filter function as passed to apply() or apply_v2() (to filter by +** table name), if any. This is always NULL for apply_v3() calls. +** +** xFilterIter: +** The filter function as passed to apply_v3(), if any. +** +** xConflict: +** The conflict handler callback (must not be NULL). +** +** pCtx: +** The context pointer passed to the xFilter and xConflict handler callbacks. +** +** ppRebase, pnRebase: +** Zero for apply(). The rebase changeset output pointers, if any, for +** apply_v2() and apply_v3(). +** +** flags: +** Zero for apply(). The flags parameter for apply_v2() and apply_v3(). +*/ +static int sessionChangesetApplyV23( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xFilterIter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p /* Handle describing current change */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +){ + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart( + &pIter, xInput, pIn, nChangeset, pChangeset, bInverse, 1 + ); + if( rc==SQLITE_OK ){ + rc = sessionChangesetApply(db, pIter, + xFilter, xFilterIter, xConflict, pCtx, ppRebase, pnRebase, flags + ); + } + return rc; +} + /* ** Apply the changeset passed via pChangeset/nChangeset to the main ** database attached to handle "db". @@ -5410,17 +5498,39 @@ int sqlite3changeset_apply_v2( void **ppRebase, int *pnRebase, int flags ){ - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); + return sessionChangesetApplyV23(db, + nChangeset, pChangeset, 0, 0, + xFilter, 0, xConflict, pCtx, + ppRebase, pnRebase, flags + ); +} - if( rc==SQLITE_OK ){ - rc = sessionChangesetApply( - db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags - ); - } - - return rc; +/* +** Apply the changeset passed via pChangeset/nChangeset to the main +** database attached to handle "db". +*/ +int sqlite3changeset_apply_v3( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p /* Handle describing current change */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +){ + return sessionChangesetApplyV23(db, + nChangeset, pChangeset, 0, 0, + 0, xFilter, xConflict, pCtx, + ppRebase, pnRebase, flags + ); } /* @@ -5443,8 +5553,10 @@ int sqlite3changeset_apply( ), void *pCtx /* First argument passed to xConflict */ ){ - return sqlite3changeset_apply_v2( - db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0 + return sessionChangesetApplyV23(db, + nChangeset, pChangeset, 0, 0, + xFilter, 0, xConflict, pCtx, + 0, 0, 0 ); } @@ -5453,6 +5565,29 @@ int sqlite3changeset_apply( ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. */ +int sqlite3changeset_apply_v3_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +){ + return sessionChangesetApplyV23(db, + 0, 0, xInput, pIn, + 0, xFilter, xConflict, pCtx, + ppRebase, pnRebase, flags + ); +} int sqlite3changeset_apply_v2_strm( sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ @@ -5470,15 +5605,11 @@ int sqlite3changeset_apply_v2_strm( void **ppRebase, int *pnRebase, int flags ){ - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1); - if( rc==SQLITE_OK ){ - rc = sessionChangesetApply( - db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags - ); - } - return rc; + return sessionChangesetApplyV23(db, + 0, 0, xInput, pIn, + xFilter, 0, xConflict, pCtx, + ppRebase, pnRebase, flags + ); } int sqlite3changeset_apply_strm( sqlite3 *db, /* Apply change to "main" db of this handle */ @@ -5495,8 +5626,10 @@ int sqlite3changeset_apply_strm( ), void *pCtx /* First argument passed to xConflict */ ){ - return sqlite3changeset_apply_v2_strm( - db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0 + return sessionChangesetApplyV23(db, + 0, 0, xInput, pIn, + xFilter, 0, xConflict, pCtx, + 0, 0, 0 ); } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 4dff5ce874..a3b6987b9c 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -1115,13 +1115,22 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** the changeset passed via the second and third arguments. ** ** The fourth argument (xFilter) passed to these functions is the "filter -** callback". If it is not NULL, then for each table affected by at least one -** change in the changeset, the filter callback is invoked with -** the table name as the second argument, and a copy of the context pointer -** passed as the sixth argument as the first. If the "filter callback" -** returns zero, then no attempt is made to apply any changes to the table. -** Otherwise, if the return value is non-zero or the xFilter argument to -** is NULL, all changes related to the table are attempted. +** callback". This may be passed NULL, in which case all changes in the +** changeset are applied to the database. For sqlite3changeset_apply() and +** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once +** for each table affected by at least one change in the changeset. In this +** case the table name is passed as the second argument, and a copy of +** the context pointer passed as the sixth argument to apply() or apply_v2() +** as the first. If the "filter callback" returns zero, then no attempt is +** made to apply any changes to the table. Otherwise, if the return value is +** non-zero, all changes related to the table are attempted. +** +** For sqlite3_changeset_apply_v3(), the xFilter callback is invoked once +** per change. The second argument in this case is an sqlite3_changeset_iter +** that may be queried using the usual APIs for the details of the current +** change. If the "filter callback" returns zero in this case, then no attempt +** is made to apply the current change. If it returns non-zero, the change +** is applied. ** ** For each table that is not excluded by the filter callback, this function ** tests that the target database contains a compatible table. A table is @@ -1142,11 +1151,11 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** one such warning is issued for each table in the changeset. ** ** For each change for which there is a compatible table, an attempt is made -** to modify the table contents according to the UPDATE, INSERT or DELETE -** change. If a change cannot be applied cleanly, the conflict handler -** function passed as the fifth argument to sqlite3changeset_apply() may be -** invoked. A description of exactly when the conflict handler is invoked for -** each type of change is below. +** to modify the table contents according to each UPDATE, INSERT or DELETE +** change that is not excluded by a filter callback. If a change cannot be +** applied cleanly, the conflict handler function passed as the fifth argument +** to sqlite3changeset_apply() may be invoked. A description of exactly when +** the conflict handler is invoked for each type of change is below. ** ** Unlike the xFilter argument, xConflict may not be passed NULL. The results ** of passing anything other than a valid function pointer as the xConflict @@ -1297,6 +1306,23 @@ int sqlite3changeset_apply_v2( void **ppRebase, int *pnRebase, /* OUT: Rebase data */ int flags /* SESSION_CHANGESETAPPLY_* flags */ ); +int sqlite3changeset_apply_v3( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p /* Handle describing change */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, /* OUT: Rebase data */ + int flags /* SESSION_CHANGESETAPPLY_* flags */ +); /* ** CAPI3REF: Flags for sqlite3changeset_apply_v2 @@ -1716,6 +1742,23 @@ int sqlite3changeset_apply_v2_strm( void **ppRebase, int *pnRebase, int flags ); +int sqlite3changeset_apply_v3_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +); int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, diff --git a/ext/session/test_session.c b/ext/session/test_session.c index f28604abc2..6ad5b37749 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -520,6 +520,65 @@ static int test_obj_eq_string(Tcl_Obj *p, const char *z){ return (nObj==n && (n==0 || 0==memcmp(zObj, z, n))); } +static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){ + Tcl_Obj *pVar = 0; + int nCol; /* Number of columns in table */ + int nCol2; /* Number of columns in table */ + int op; /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zTab; /* Name of table change applies to */ + Tcl_Obj *pOld; /* Vector of old.* values */ + Tcl_Obj *pNew; /* Vector of new.* values */ + int bIndirect; + + char *zPK; + unsigned char *abPK; + int i; + + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + pVar = Tcl_NewObj(); + + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( + op==SQLITE_INSERT ? "INSERT" : + op==SQLITE_UPDATE ? "UPDATE" : + "DELETE", -1 + )); + + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); + + zPK = ckalloc(nCol+1); + memset(zPK, 0, nCol+1); + sqlite3changeset_pk(pIter, &abPK, &nCol2); + assert( nCol==nCol2 ); + for(i=0; iinterp; + + pEval = Tcl_DuplicateObj(p->pFilterScript); + Tcl_IncrRefCount(pEval); + Tcl_ListObjAppendElement(0, pEval, testIterData(pIter)); + + if( TCL_OK!=Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL) + || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &res) + ){ + Tcl_BackgroundError(interp); + } + + Tcl_DecrRefCount(pEval); + return res; +} + static int test_conflict_handler( void *pCtx, /* Pointer to TestConflictHandler structure */ int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */ @@ -776,7 +858,7 @@ static int testStreamInput( static int SQLITE_TCLAPI testSqlite3changesetApply( - int bV2, + int iVersion, void * clientData, Tcl_Interp *interp, int objc, @@ -793,11 +875,13 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( int nRebase = 0; int flags = 0; /* Flags for apply_v2() */ + assert( iVersion==1 || iVersion==2 || iVersion==3 ); + memset(&sStr, 0, sizeof(sStr)); sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); /* Check for the -nosavepoint, -invert or -ignorenoop switches */ - if( bV2 ){ + if( iVersion==2 || iVersion==3 ){ while( objc>1 ){ const char *z1 = Tcl_GetString(objv[1]); int n = (int)strlen(z1); @@ -822,7 +906,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( if( objc!=4 && objc!=5 ){ const char *zMsg; - if( bV2 ){ + if( iVersion==2 || iVersion==3 ){ zMsg = "?-nosavepoint? ?-inverse? ?-ignorenoop? " "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?"; }else{ @@ -842,30 +926,49 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( ctx.interp = interp; if( sStr.nStream==0 ){ - if( bV2==0 ){ - rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, - (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx - ); - }else{ - rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset, - (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx, - &pRebase, &nRebase, flags - ); + switch( iVersion ){ + case 1: + rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, + (objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx + ); + break; + case 2: + rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset, + (objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx, + &pRebase, &nRebase, flags + ); + break; + case 3: + rc = sqlite3changeset_apply_v3(db, (int)nChangeset, pChangeset, + (objc==5)?test_filter_v3_handler:0, test_conflict_handler, + (void*)&ctx, &pRebase, &nRebase, flags + ); + break; } }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = (int)nChangeset; - if( bV2==0 ){ - rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, - (objc==5) ? test_filter_handler : 0, - test_conflict_handler, (void *)&ctx - ); - }else{ - rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr, - (objc==5) ? test_filter_handler : 0, - test_conflict_handler, (void *)&ctx, - &pRebase, &nRebase, flags - ); + switch( iVersion ){ + case 1: + rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_handler : 0, + test_conflict_handler, (void *)&ctx + ); + break; + case 2: + rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_handler : 0, + test_conflict_handler, (void *)&ctx, + &pRebase, &nRebase, flags + ); + break; + case 3: + rc = sqlite3changeset_apply_v3_strm(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_v3_handler : 0, + test_conflict_handler, (void *)&ctx, + &pRebase, &nRebase, flags + ); + break; } } @@ -873,7 +976,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( return test_session_error(interp, rc, 0); }else{ Tcl_ResetResult(interp); - if( bV2 && pRebase ){ + if( (iVersion==2 || iVersion==3) && pRebase ){ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase)); } } @@ -890,7 +993,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply( int objc, Tcl_Obj *CONST objv[] ){ - return testSqlite3changesetApply(0, clientData, interp, objc, objv); + return testSqlite3changesetApply(1, clientData, interp, objc, objv); } /* ** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? @@ -901,7 +1004,18 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2( int objc, Tcl_Obj *CONST objv[] ){ - return testSqlite3changesetApply(1, clientData, interp, objc, objv); + return testSqlite3changesetApply(2, clientData, interp, objc, objv); +} +/* +** sqlite3changeset_apply_v3 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? +*/ +static int SQLITE_TCLAPI test_sqlite3changeset_apply_v3( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + return testSqlite3changesetApply(3, clientData, interp, objc, objv); } /* @@ -1034,64 +1148,6 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat( return rc; } -static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){ - Tcl_Obj *pVar = 0; - int nCol; /* Number of columns in table */ - int nCol2; /* Number of columns in table */ - int op; /* SQLITE_INSERT, UPDATE or DELETE */ - const char *zTab; /* Name of table change applies to */ - Tcl_Obj *pOld; /* Vector of old.* values */ - Tcl_Obj *pNew; /* Vector of new.* values */ - int bIndirect; - - char *zPK; - unsigned char *abPK; - int i; - - sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); - pVar = Tcl_NewObj(); - - Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( - op==SQLITE_INSERT ? "INSERT" : - op==SQLITE_UPDATE ? "UPDATE" : - "DELETE", -1 - )); - - Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); - Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); - - zPK = ckalloc(nCol+1); - memset(zPK, 0, nCol+1); - sqlite3changeset_pk(pIter, &abPK, &nCol2); - assert( nCol==nCol2 ); - for(i=0; i Date: Mon, 14 Jul 2025 15:34:11 +0000 Subject: [PATCH 75/88] In rtree.c, ensure that the pReadAux statement is reset whenever the bAuxValid flag is cleared. Possible fix for [forum:/forumpost/3e45ed31d8 | forum post 3e45ed31d8]. FossilOrigin-Name: 1740f9a09850f6647fc1f6384353d89a1ac0b2b15c429b576b6014eada71937e --- ext/rtree/rtree.c | 6 ++++++ ext/rtree/rtreeH.test | 19 +++++++++++++++++++ manifest | 17 ++++++++++------- manifest.uuid | 2 +- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index f7d3bda01a..fb35bc10e6 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1135,6 +1135,12 @@ static void resetCursor(RtreeCursor *pCsr){ pCsr->base.pVtab = (sqlite3_vtab*)pRtree; pCsr->pReadAux = pStmt; + /* The following will only fail if the previous sqlite3_step() call failed, + ** in which case the error has already been caught. This statement never + ** encounters an error within an sqlite3_column_xxx() function, as it + ** calls sqlite3_column_value(), which does not use malloc(). So it is safe + ** to ignore the error code here. */ + sqlite3_reset(pStmt); } /* diff --git a/ext/rtree/rtreeH.test b/ext/rtree/rtreeH.test index e26107f075..79bf9808df 100644 --- a/ext/rtree/rtreeH.test +++ b/ext/rtree/rtreeH.test @@ -99,5 +99,24 @@ do_execsql_test rtreeH-300 { ORDER BY id; } {box-48,48 box-49,48 box-48,49 xbox-49,49} +#------------------------------------------------------------------------- +reset_db +do_execsql_test rtreeH-300 { + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES (NULL); + INSERT INTO t0(c0) VALUES (1); + CREATE VIRTUAL TABLE t1 USING rtree(c0, c1, c2, +c3 BLOB ); + INSERT INTO t1(c2, c3, c0) VALUES (1, 2, 1); +} + +do_execsql_test rtreeH-310 { + SELECT 1 FROM t1 WHERE t1.c3; +} {1} + +do_execsql_test rtreeH-320 { + SELECT * FROM t0 WHERE NOT EXISTS ( + SELECT 1 FROM t1 WHERE t1.c3 OR t0.c0 ISNULL + ); +} {} finish_test diff --git a/manifest b/manifest index 9efc9ff73e..80b1c92f22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\ssessions\sfunction\ssqlite3changeset_apply_v3()\sand\sits\sstreaming\sequivalent.\sThis\sallows\schangesets\sto\sbe\sfiltered\son\sa\sper-change\sbasis,\snot\sjust\sper-table. -D 2025-07-14T14:51:43.802 +C In\srtree.c,\sensure\sthat\sthe\spReadAux\sstatement\sis\sreset\swhenever\sthe\sbAuxValid\sflag\sis\scleared.\sPossible\sfix\sfor\s[forum:/forumpost/3e45ed31d8\s|\sforum\spost\s3e45ed31d8]. +D 2025-07-14T15:34:11.166 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -539,7 +539,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1 F ext/rtree/geopoly.c f0573d5109fdc658a180db0db6eec86ab2a1cf5ce58ec66cbf3356167ea757eb -F ext/rtree/rtree.c a1f04a2013bc8f982307760615d1cee591355ac4723c74c3761c128d5c6954ab +F ext/rtree/rtree.c 86967c5a501f895b9705366b8cd9c37f15a9ebdff770ceb719c7deeeb2c22b72 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -557,7 +557,7 @@ F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9 F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331 F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c -F ext/rtree/rtreeH.test 0885151ee8429242625600ae47142cca935332c70a06737f35af53a7bd7aaf90 +F ext/rtree/rtreeH.test c304651ee87dbb60296366d2c802f3043c3d00506c79a5c85bd20f2c9274498b F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123e19c4ca4 F ext/rtree/rtreeJ.test 93227ccd4d6c328f5ac46a902b8880041509dd2d68f6ce71560f0d8ab5bb507a F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 @@ -2213,8 +2213,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e11fbf9fd630a7de2e0b0e4b67dded05b905b2a0ba04aa7e915ca9df2d9ebe21 -R 082d403ad4bd97cbce0234772b2da39f +P 10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337 +R 99a507c70268ef6ceed5ff7684eef3c0 +T *branch * rtree-aux-column-fix +T *sym-rtree-aux-column-fix * +T -sym-trunk * U dan -Z 455b5bdcd48088e3f2c57d9eeedfc2e8 +Z 738adb27a795603794b0d94f34d74a91 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e0a53a1a22..0ae5060619 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337 +1740f9a09850f6647fc1f6384353d89a1ac0b2b15c429b576b6014eada71937e From 1c11aa3da22a8fcb5f2b2dd732702d2a127e54a1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Jul 2025 16:05:59 +0000 Subject: [PATCH 76/88] Enhance the "mktoolzip.tcl" script (used by the "tool-zip" makefile target) so that it uses "fossil test-filezip" to build the ZIP archive if available, and so that it also generates windows-dll-*.zip on Windows platforms. FossilOrigin-Name: 63ddc215eb6106985c53d3c8d99f5445a92acf4359a6bb2681882c49583df871 --- Makefile.msc | 2 +- manifest | 17 ++++++++--------- manifest.uuid | 2 +- tool/mktoolzip.tcl | 27 ++++++++++++++++++++++----- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1533cf3ded..85b0456309 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2596,7 +2596,7 @@ extensiontest: testfixture.exe testloadext.dll @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS) -tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe sqlite3_rsync.exe $(TOP)\tool\mktoolzip.tcl +tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe sqlite3_rsync.exe sqlite3.dll $(TOP)\tool\mktoolzip.tcl .\testfixture.exe $(TOP)\tool\mktoolzip.tcl coretestprogs: testfixture.exe sqlite3.exe diff --git a/manifest b/manifest index c61b51d277..4d685ee4f3 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C In\srtree.c,\sensure\sthat\sthe\spReadAux\sstatement\sis\sreset\swhenever\sthe\sbAuxValid\sflag\sis\scleared.\sFix\sfor\s[forum:/forumpost/3e45ed31d8\s|\sforum\spost\s3e45ed31d8]. -D 2025-07-14T15:40:25.099 +C Enhance\sthe\s"mktoolzip.tcl"\sscript\s(used\sby\sthe\s"tool-zip"\smakefile\starget)\sso\sthat\nit\suses\s"fossil\stest-filezip"\sto\sbuild\sthe\sZIP\sarchive\sif\savailable,\sand\sso\sthat\nit\salso\sgenerates\swindows-dll-*.zip\son\sWindows\splatforms. +D 2025-07-14T16:05:59.333 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in a6c14b6906f5322920dd5d1ff9a84808337911068f2a6e777ec7088a87cbc3a8 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc ec2011bbdfc917d6a1c7c173dabb29c14ead0dd8e2e0b67278a00ae4ba576a77 +F Makefile.msc 495e61b4940984b3e25f654c1625115352d6f10af088a4a8d4d360e1c88c5898 F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1 F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2173,7 +2173,7 @@ F tool/mksqlite3c.tcl f11b63445c4840509248bd4aa151a81aea25d5415fef71943c8d436eba F tool/mksqlite3h.tcl 989948c6a26e188e673d7c2f2f093ea3acd816ad6ac65bab596280075c8f3a45 F tool/mksqlite3internalh.tcl 46ef6ed6ccd3c36e23051109dd25085d8edef3887635cea25afa81c4adf4d4db F tool/mksrczip.tcl 81efd9974dbb36005383f2cd655520057a2ae5aa85ac2441a80c7c28f803ac52 -F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c +F tool/mktoolzip.tcl 0beb5f0e58401ab85f71cc57e8de73a248ad481c0b1fbe5e577b440ee326f004 F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 @@ -2213,9 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337 1740f9a09850f6647fc1f6384353d89a1ac0b2b15c429b576b6014eada71937e -R 99a507c70268ef6ceed5ff7684eef3c0 -T +closed 1740f9a09850f6647fc1f6384353d89a1ac0b2b15c429b576b6014eada71937e -U dan -Z e033e0bcf52e68a8125fc82a4c8db140 +P 3c0afda372cd688e9aff7be1c0a41f557c8c8819f5f47420166ce8255cd806c8 +R e290ca399c8e663ed9c1c500434c64ea +U drh +Z 55552671916a227c18ab9a99dcc87aef # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 53427049bc..b83975833f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c0afda372cd688e9aff7be1c0a41f557c8c8819f5f47420166ce8255cd806c8 +63ddc215eb6106985c53d3c8d99f5445a92acf4359a6bb2681882c49583df871 diff --git a/tool/mktoolzip.tcl b/tool/mktoolzip.tcl index c22318441e..130f6677bd 100644 --- a/tool/mktoolzip.tcl +++ b/tool/mktoolzip.tcl @@ -14,7 +14,7 @@ # switch $tcl_platform(os) { {Windows NT} { - set OS win32 + set OS win set EXE .exe } Linux { @@ -55,7 +55,24 @@ close $in scan $vers %d.%d.%d v1 v2 v3 set v2 [format 3%02d%02d00 $v2 $v3] set name sqlite-tools-$OS-$ARCH-$v2.zip -set toollist "sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE sqlite3_rsync$EXE" -puts "zip $name {*}$toollist" -exec zip $name {*}$toollist -puts "$name: [file size $name] bytes" +set filelist "sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE sqlite3_rsync$EXE" +proc make_zip_archive {name filelist} { + file delete -force $name + puts "fossil test-filezip $name $filelist" + if {[catch {exec fossil test-filezip $name {*}$filelist}]} { + puts "^--- Unable. Trying again as:" + puts "zip $name $filelist" + file delete -force $name + exec zip $name {*}$filelist + } + puts "$name: [file size $name] bytes" +} +make_zip_archive $name $filelist + +# On Windows, also try to construct a DLL +# +if {$OS eq "win" && [file exists sqlite3.dll] && [file exists sqlite3.def]} { + set name sqlite-dll-win-$ARCH-$v2.zip + set filelist [list sqlite3.def sqlite3.dll] + make_zip_archive $name $filelist +} From 97e6368abcaff3d202954cc8d493646a388f52d5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Jul 2025 18:27:32 +0000 Subject: [PATCH 77/88] Add the snapshot-zip makefile targets for both Windows and Posix. FossilOrigin-Name: 8c73c0c5935431556f687556bfdb459754609f07c6366c810a55bf7583ee303d --- Makefile.msc | 3 +++ main.mk | 4 ++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mktoolzip.tcl | 37 ++++++++++++++++++++++++++++++++----- 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 85b0456309..e67638287f 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2599,6 +2599,9 @@ extensiontest: testfixture.exe testloadext.dll tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe sqlite3_rsync.exe sqlite3.dll $(TOP)\tool\mktoolzip.tcl .\testfixture.exe $(TOP)\tool\mktoolzip.tcl +snapshot-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe sqlite3_rsync.exe sqlite3.dll $(TOP)\tool\mktoolzip.tcl + .\testfixture.exe $(TOP)\tool\mktoolzip.tcl --snapshot + coretestprogs: testfixture.exe sqlite3.exe testprogs: $(TESTPROGS) srcck1.exe fuzzcheck.exe sessionfuzz.exe diff --git a/main.mk b/main.mk index 34c1cc3cf2..40d059ad42 100644 --- a/main.mk +++ b/main.mk @@ -2113,6 +2113,10 @@ tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) $(TOP)/tool/mktoolzip.tcl strip sqlite3$(T.exe) sqldiff$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) ./testfixture$(T.exe) $(TOP)/tool/mktoolzip.tcl +snapshot-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ + sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) $(TOP)/tool/mktoolzip.tcl + strip sqlite3$(T.exe) sqldiff$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) + ./testfixture$(T.exe) $(TOP)/tool/mktoolzip.tcl --snapshot clean-tool-zip: rm -f sqlite-tools-*.zip clean: clean-tool-zip diff --git a/manifest b/manifest index 4d685ee4f3..df55310f69 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Enhance\sthe\s"mktoolzip.tcl"\sscript\s(used\sby\sthe\s"tool-zip"\smakefile\starget)\sso\sthat\nit\suses\s"fossil\stest-filezip"\sto\sbuild\sthe\sZIP\sarchive\sif\savailable,\sand\sso\sthat\nit\salso\sgenerates\swindows-dll-*.zip\son\sWindows\splatforms. -D 2025-07-14T16:05:59.333 +C Add\sthe\ssnapshot-zip\smakefile\stargets\sfor\sboth\sWindows\sand\sPosix. +D 2025-07-14T18:27:32.150 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in a6c14b6906f5322920dd5d1ff9a84808337911068f2a6e777ec7088a87cbc3a8 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc 495e61b4940984b3e25f654c1625115352d6f10af088a4a8d4d360e1c88c5898 +F Makefile.msc e17608035fb75d3e5b322f846c6c3cbe80a5f34abf5df9e400c40dd55436dc14 F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1 F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -710,7 +710,7 @@ F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 F ext/wasm/wasmfs.make 68999f5bd8c489239592d59a420f8c627c99169bbd6fa16a404751f757b9f702 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 3ced12d068b22957f4e82a0b94a2c1d83b37dcf39c087263691267f7bfb39a84 +F main.mk a5d698cf8d38e4eb42a89f08a9521906b24f4acac61bbafa56d72cd9b39617b6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2173,7 +2173,7 @@ F tool/mksqlite3c.tcl f11b63445c4840509248bd4aa151a81aea25d5415fef71943c8d436eba F tool/mksqlite3h.tcl 989948c6a26e188e673d7c2f2f093ea3acd816ad6ac65bab596280075c8f3a45 F tool/mksqlite3internalh.tcl 46ef6ed6ccd3c36e23051109dd25085d8edef3887635cea25afa81c4adf4d4db F tool/mksrczip.tcl 81efd9974dbb36005383f2cd655520057a2ae5aa85ac2441a80c7c28f803ac52 -F tool/mktoolzip.tcl 0beb5f0e58401ab85f71cc57e8de73a248ad481c0b1fbe5e577b440ee326f004 +F tool/mktoolzip.tcl c9f388b2b0751982aef29a0c1d80f7959dbe38065ebb4421c39844e92622b086 F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3c0afda372cd688e9aff7be1c0a41f557c8c8819f5f47420166ce8255cd806c8 -R e290ca399c8e663ed9c1c500434c64ea +P 63ddc215eb6106985c53d3c8d99f5445a92acf4359a6bb2681882c49583df871 +R d564e67ede86bc5b3c0bb80782639393 U drh -Z 55552671916a227c18ab9a99dcc87aef +Z be924e4628c0fead0c508f3649455f46 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b83975833f..37f76ee003 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63ddc215eb6106985c53d3c8d99f5445a92acf4359a6bb2681882c49583df871 +8c73c0c5935431556f687556bfdb459754609f07c6366c810a55bf7583ee303d diff --git a/tool/mktoolzip.tcl b/tool/mktoolzip.tcl index 130f6677bd..041bf28cdd 100644 --- a/tool/mktoolzip.tcl +++ b/tool/mktoolzip.tcl @@ -12,6 +12,24 @@ # sqlite3_analyzer -- Space analyzer # sqlite3_rsync -- Remote db sync # +# On Windows, add: +# +# sqlite3.def +# sqlite3.dll +# +# Add the --snapshot option to generate a snapshot ZIP archive instead of +# a release ZIP archive. +# +set bSnapshot 0 +for {set i 0} {$i<[llength $argv]} {incr i} { + set a [lindex $argv $i] + if {$a eq "-snapshot" || $a eq "--snapshot"} { + set bSnapshot 1 + continue + } + puts stderr "unknown argument: $a" + exit 1 +} switch $tcl_platform(os) { {Windows NT} { set OS win @@ -49,11 +67,20 @@ switch $tcl_platform(machine) { set ARCH unk } } -set in [open [file join [file dirname [file dirname [info script]]] VERSION]] -set vers [read $in] -close $in -scan $vers %d.%d.%d v1 v2 v3 -set v2 [format 3%02d%02d00 $v2 $v3] +if {$bSnapshot} { + set in [open [file join [file dirname [file dirname [info script]]] manifest]] + set manifest [read $in] + close $in + regexp {\nD (.{16})} $manifest all date + regsub -all {[-:T]} $date {} v2 +} else { + set in [open [file join [file dirname [file dirname [info script]]] VERSION]] + set vers [read $in] + close $in + scan $vers %d.%d.%d v1 v2 v3 + set v2 [format 3%02d%02d00 $v2 $v3] +} + set name sqlite-tools-$OS-$ARCH-$v2.zip set filelist "sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE sqlite3_rsync$EXE" proc make_zip_archive {name filelist} { From 192d0ff8ccf0bf55776a5930cdc64e25f87299d6 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Jul 2025 14:06:15 +0000 Subject: [PATCH 78/88] Optimize allocation of large tombstone arrays in fts5. FossilOrigin-Name: 0fcc3cbdfa21adf97aed01fa76991cccf9380e2755b0182a9e2c94e3c8fb38d7 --- ext/fts5/fts5_index.c | 4 +-- ext/fts5/test/fts5corrupt8.test | 53 +++++++++++++++++++++++++++++++++ manifest | 16 +++++----- manifest.uuid | 2 +- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 7036e57f5f..182936cda9 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1986,9 +1986,9 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ ** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ - const int nTomb = pIter->pSeg->nPgTombstone; + const i64 nTomb = (i64)pIter->pSeg->nPgTombstone; if( nTomb>0 ){ - int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); + i64 nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); Fts5TombstoneArray *pNew; pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ diff --git a/ext/fts5/test/fts5corrupt8.test b/ext/fts5/test/fts5corrupt8.test index a43bbaa039..471a1b0e39 100644 --- a/ext/fts5/test/fts5corrupt8.test +++ b/ext/fts5/test/fts5corrupt8.test @@ -90,5 +90,58 @@ do_execsql_test 3.7 { SELECT * FROM sqlite_schema } +#------------------------------------------------------------------------- +reset_db + +proc hex_to_blob {hex} { + binary encode hex $hex +} +db func hex_to_blob hex_to_blob + +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE x1 USING fts5(x, content='', contentless_delete=1); + BEGIN; + INSERT INTO x1(rowid, x) VALUES(1, 'a b c d e f g h'); + INSERT INTO x1(rowid, x) VALUES(2, 'a b c d e f g h'); + COMMIT; + DELETE FROM x1 WHERE rowid=1; +} + +do_execsql_test 4.1 { + SELECT hex(block) FROM x1_data WHERE id=10 +} { + 00000000FF00000101010200010101010101010102 +} + +do_execsql_test 4.2.1 { + UPDATE x1_data SET block= + X'00000000FF00000101010200010101010101819C9B95A8000102' + WHERE id=10; +} + +do_catchsql_test 4.2.2 { + SELECT * FROM x1('c d e'); +} {1 {out of memory}} + +do_execsql_test 4.3.1 { + UPDATE x1_data SET block= + X'00000000FF000001010102000101010101019282AFF9A0000102' + WHERE id=10; +} + +do_catchsql_test 4.3.2 { + SELECT * FROM x1('c d e'); +} {1 {out of memory}} + +do_execsql_test 4.4.1 { + UPDATE x1_data SET block= + X'00000000FF000001010102000101010101018181808080130102' + WHERE id=10; +} + +do_catchsql_test 4.3.2 { + SELECT * FROM x1('c d e'); +} {1 {out of memory}} + finish_test diff --git a/manifest b/manifest index df55310f69..d10e17ee41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssnapshot-zip\smakefile\stargets\sfor\sboth\sWindows\sand\sPosix. -D 2025-07-14T18:27:32.150 +C Optimize\sallocation\sof\slarge\stombstone\sarrays\sin\sfts5. +D 2025-07-15T14:06:15.269 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0 -F ext/fts5/fts5_index.c 8321944bcabdb3f3cac1c44867758ff9a9baaee5532debed2721d4d64d3c615d +F ext/fts5/fts5_index.c c1ca58fbc4b323d2153ab42ed787d78d5beb64f5710d0dcb83d94c6ddd184492 F ext/fts5/fts5_main.c e558225168845dc708abeb2ad10415696e5a3249bcba1810ba3c7ef80764962e F ext/fts5/fts5_storage.c 19bc7c4cbe1e6a2dd9849ef7d84b5ca1fcbf194cefc3e386b901e00e08bf05c2 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -167,7 +167,7 @@ F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93 F ext/fts5/test/fts5corrupt5.test 73985d4fe6d8f0d5d5c7bcf79ae7c6522c376cd6ad710a0ff2f26e0c2e222abe F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 F ext/fts5/test/fts5corrupt7.test 814aab492d7a09abb5bfdd81cc66fc206d7f3868f9a3bae91876e02efc466fb3 -F ext/fts5/test/fts5corrupt8.test 7618b102b9b3a5a3494271f4975ab5837e2fb3f61f5adfcdeeb31772c859e6df +F ext/fts5/test/fts5corrupt8.test 0b10750caf8aa23fa1c379ca4caf6130d41454505e4d5315590f4061eedcbe44 F ext/fts5/test/fts5delete.test 2a5008f8b1174ef41d1974e606928c20e4f9da77d9f8347aed818994d89cced4 F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4 F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 63ddc215eb6106985c53d3c8d99f5445a92acf4359a6bb2681882c49583df871 -R d564e67ede86bc5b3c0bb80782639393 -U drh -Z be924e4628c0fead0c508f3649455f46 +P 8c73c0c5935431556f687556bfdb459754609f07c6366c810a55bf7583ee303d +R b9c1fa349127612acf8e4eeb19a5b3ea +U dan +Z 4f75a3bfe6c7ec1b805eacccf6dabec6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 37f76ee003..d4fa327eae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c73c0c5935431556f687556bfdb459754609f07c6366c810a55bf7583ee303d +0fcc3cbdfa21adf97aed01fa76991cccf9380e2755b0182a9e2c94e3c8fb38d7 From 7d20c2e8a36e82e0388c7edaa615ba68b27a5d26 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Jul 2025 18:51:46 +0000 Subject: [PATCH 79/88] Add test case to between.test. FossilOrigin-Name: ffebbb7ae977adc6c729d30b51f2ff29d416e018d82e450d87ccd973472819c8 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/between.test | 5 +++++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 87abca403e..714f2b2afa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sevaluating\sspecial\svtab\soperators\s(e.g.\sMATCH)\sthat\sare\spart\sof\sON\sclauses\sattached\sto\sleft\sjoins\sfrom\sbeing\sevaluated\stoo\searly.\sPossible\sfix\sfor\s[forum:/forumpost/428ef7c468\s|\sforum\spost\s428ef7c468]. -D 2025-07-12T18:14:41.159 +C Add\stest\scase\sto\sbetween.test. +D 2025-07-15T18:51:46.505 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -964,7 +964,7 @@ F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572e F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/bestindexC.test 95b4a527b1a5d07951d731604a6d4cf7e5a806b39cea0e7819d4c9667e11c3fc F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 -F test/between.test b301ef0d822a26b31235e10a3b7f1130be1565a7ba080e80a3a1ae3ba5a35ff7 +F test/between.test e7587149796101cbe8d5f8abae8d2a7b87f04d8226610aa1091615005dcf4d54 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc F test/bigmmap.test 6021e205487347c6d7e5a541aa472a4b8efc4e9f4a3799a823b61a8e6616105d @@ -2212,11 +2212,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3 -R eb99b7ab5a76b7191a98fe93227d2428 -T *branch * vtab-leftjoin-fix -T *sym-vtab-leftjoin-fix * -T -sym-trunk * +P 18ba07c152294a96d510a7851a0860f982ff1e0725afeebed9a343f550f6925a +R 666e43c52f95417d6d453e313782ce83 U dan -Z c80dd1f4987fe05a4ba000eae17152fd +Z 2d017df1643869d27e1f37ae6b4030de # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 786e5c76d3..16487b86b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18ba07c152294a96d510a7851a0860f982ff1e0725afeebed9a343f550f6925a +ffebbb7ae977adc6c729d30b51f2ff29d416e018d82e450d87ccd973472819c8 diff --git a/test/between.test b/test/between.test index 4f09f1afec..5e02ef9b22 100644 --- a/test/between.test +++ b/test/between.test @@ -144,6 +144,7 @@ foreach {tn expr res} { reset_db do_execsql_test between-3.0 { CREATE TABLE t1(x, y); + CREATE INDEX i1 ON t1(x); INSERT INTO t1 VALUES(4, 4); CREATE TABLE t2(a, b); } @@ -152,4 +153,8 @@ do_execsql_test between-3.1 { SELECT * FROM t1 LEFT JOIN t2 ON (x BETWEEN 1 AND 3); } {4 4 {} {}} +do_execsql_test between-3.2 { + SELECT * FROM t1 LEFT JOIN t2 ON (x BETWEEN 5 AND 7); +} {4 4 {} {}} + finish_test From 3a97a1ba8c22aabe618c3669e1c46235866f3215 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 09:20:02 +0000 Subject: [PATCH 80/88] Squelch a legitimate but harmless 'discards const' warning. FossilOrigin-Name: 73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5c85b7714b..353f38b6e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\s~/.local/config/...\sto\s~/.config/...\swhen\slooking\sfor\ssqliterc\swhen\sXDG_CONFIG_HOME\sis\snot\sset.\sInternal\sdoc\stouchups. -D 2025-06-30T15:56:10.103 +C Squelch\sa\slegitimate\sbut\sharmless\s'discards\sconst'\swarning. +D 2025-07-16T09:20:02.408 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -786,7 +786,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 -F src/shell.c.in 56f3719f22b1dcab01b4c52dc21224bbc46dcc52a0e95407293736fc88fd41c1 +F src/shell.c.in 550ca8a09f8ac55203e69aae34e429b79d92cb44edf7419d8f3dd88eefab5d39 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6b780655ccd68d068b6ee6621e56ac94c000916b7341651dc79725a0800cd1c0 -R 797b3e78135d622f3aa0a1b4105d4fa3 +P ebb346c5aa427b9e84a035278ee245d54810d9954efef12b898f2d7bc0ff630c +R debb7a97a27a2dab2543b88f76ae8cc2 U stephan -Z bfe5fd02ba4d5c951c96e8138fec5fad +Z affb48d71da77c1ae112258e0a7a4bb5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6777f3edc1..d86bd127b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebb346c5aa427b9e84a035278ee245d54810d9954efef12b898f2d7bc0ff630c +73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b diff --git a/src/shell.c.in b/src/shell.c.in index ccdf89a2f0..7b28bf6842 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12822,7 +12822,7 @@ static void process_sqliterc( const char *sqliterc_override /* Name of config file. NULL to use default */ ){ char *home_dir = NULL; - char *sqliterc = sqliterc_override; + char *sqliterc = (char*)sqliterc_override; FILE *inSaved = p->in; int savedLineno = p->lineno; From f98148be9c527d9f4094380562c4fe43015cf4b2 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 10:34:14 +0000 Subject: [PATCH 81/88] Internal refactoring of the WASM build makefile rule generator, working towards parallelizing the various build modes (which is not currently possible because most modes share the same sqlite3.wasm output file name). FossilOrigin-Name: 1062b61e9c949d76791ed7974cf6c38d1cec9797a930e9ad7ca851130f5e9a48 --- ext/wasm/mkwasmbuilds.c | 212 ++++++++++++++++++++++++---------------- manifest | 13 ++- manifest.uuid | 2 +- 3 files changed, 134 insertions(+), 93 deletions(-) diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index 8aa29c0fed..bc2ae04232 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -33,8 +33,6 @@ #define pf printf #define ps puts -/* Very common printf() args combo. */ -#define zNM zName, zMode /* ** Valid names for the zName arguments. @@ -49,6 +47,86 @@ static const char * zBanner = "\n########################################################################\n"; +/* +** Flags for use with BuildDef::flags and the 3rd argument to +** mk_pre_post(). +** +** Maintenance reminder: do not combine flags within this enum, +** e.g. LIBMODE_BUNDLER_FRIENDLY=0x02|LIBMODE_ESM, as that will lead +** to breakage in some of the flag checks. +*/ +enum LibModeFlags { + /* Sentinel value */ + LIBMODE_PLAIN = 0, + /* Indicates an ESM module build. */ + LIBMODE_ESM = 0x01, + /* Indicates a "bundler-friendly" build mode. */ + LIBMODE_BUNDLER_FRIENDLY = 0x02, + /* Indicates to _not_ add this build to the 'all' target. */ + LIBMODE_DONT_ADD_TO_ALL = 0x04, + /* Indicates a node.js-for-node.js build (untested and + ** unsupported). */ + LIBMODE_NODEJS = 0x08, + /* Indicates a wasmfs build (untested and unsupported). */ + LIBMODE_WASMFS = 0x10 +}; + +/* +** Info needed for building one combination of JS_BUILD_NAMES and +** JS_BUILD_MODE, noting that only a subset of those combinations are +** legal/sensical. +*/ +struct BuildDef { + const char *zName; /* Name from JS_BUILD_NAMES */ + const char *zMode; /* Name from JS_BUILD_MODES */ + int flags; /* Flags from LibModeFlags */ + const char *zApiJsOut; /* Name of generated sqlite3-api.js/.mjs */ + const char *zJsOut; /* Name of generated sqlite3.js/.mjs */ + const char *zCmppD; /* Extra -D... flags for c-pp */ + const char *zEmcc; /* Extra flags for emcc */ +}; +typedef struct BuildDef BuildDef; + +/* +** The set of WASM builds for the library (as opposed to the apps +** (fiddle, speedtest1)). This array must end with an empty sentinel +** entry, but their order is otherwise not significant. +*/ +const BuildDef aBuildDefs[] = { + {/* Core build */ + "sqlite3", "vanilla", LIBMODE_PLAIN, + "$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0}, + + {/* Core ESM */ + "sqlite3", "esm", LIBMODE_ESM, + "$(sqlite3-api.mjs)", "$(sqlite3.mjs)", + "-Dtarget=es6-module", 0}, + + {/* Core bundler-friend. Untested and "not really" supported, but + ** required by the downstream npm subproject. */ + "sqlite3", "bundler-friendly", + LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, + "$(sqlite3-api-bundler-friendly.mjs)", + "$(sqlite3-bundler-friendly.mjs)", + "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0}, + + {/* node.js mode. Untested and unsupported. */ + "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, + "$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)", + "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0}, + + {/* The wasmfs build is optional, untested, unsupported, and + ** needs to be invoked conditionally using info we don't have + ** here. */ + "sqlite3-wasmfs", "esm" , + LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, + "$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)", + "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", + "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"}, + + {/*End-of-list sentinel*/0,0,0,0,0,0,0} +}; + /* ** Emits common vars needed by the rest of the emitted code (but not ** needed by makefile code outside of these generated pieces). @@ -127,7 +205,7 @@ static void mk_prologue(void){ "\t\techo -n 'After wasm-opt: '; \\\n" "\t\tls -l $(1); \\\n" "\telse \\\n" - "\t\techo 'WARNING: ignoring wasm-opt failure'; \\\n" + "\t\techo 'WARNING: ignoring wasm-opt failure for $(1)'; \\\n" "\tfi\n", zOptFlags ); @@ -136,28 +214,6 @@ static void mk_prologue(void){ } } -/* -** Flags for use with the 3rd argument to mk_pre_post() and -** mk_lib_mode(). -** -** Maintenance reminder: do not combine flags within this enum, -** e.g. LIBMODE_BUNDLER_FRIENDLY=0x02|LIBMODE_ESM, as that will lead -** to breakage in some of the flag checks. -*/ -enum LibModeFlags { - /* Indicates an ESM module build. */ - LIBMODE_ESM = 0x01, - /* Indicates a "bundler-friendly" build mode. */ - LIBMODE_BUNDLER_FRIENDLY = 0x02, - /* Indicates to _not_ add this build to the 'all' target. */ - LIBMODE_DONT_ADD_TO_ALL = 0x04, - /* Indicates a node.js-for-node.js build (untested and - ** unsupported). */ - LIBMODE_NODEJS = 0x08, - /* Indicates a wasmfs build (untested and unsupported). */ - LIBMODE_WASMFS = 0x10 -}; - /* ** Emits makefile code for setting up values for the --pre-js=FILE, ** --post-js=FILE, and --extern-post-js=FILE emcc flags, as well as @@ -168,6 +224,9 @@ static void mk_pre_post(const char *zName /* build name */, int flags /* LIBMODE_... mask */, const char *zCmppD /* optional -D flags for c-pp for the ** --pre/--post-js files. */){ +/* Very common printf() args combo. */ +#define zNM zName, zMode + pf("%s# Begin --pre/--post flags for %s-%s\n", zBanner, zNM); pf("c-pp.D.%s-%s := %s\n", zNM, zCmppD ? zCmppD : ""); pf("pre-post-%s-%s.flags ?=\n", zNM); @@ -225,13 +284,14 @@ static void mk_pre_post(const char *zName /* build name */, pf("pre-post-%s-%s.deps := $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n", zNM, zNM, zNM); pf("# End --pre/--post flags for %s-%s%s", zNM, zBanner); +#undef zNM } /* ** Emits rules for the fiddle builds. ** */ -static void mk_fiddle(){ +static void mk_fiddle(void){ int i = 0; mk_pre_post("fiddle-module","vanilla", 0, 0); @@ -280,36 +340,32 @@ static void mk_fiddle(){ ** by the combination of zName and zMode, each of which must be values ** from JS_BUILD_NAMES resp. JS_BUILD_MODES. */ -static void mk_lib_mode(const char *zName /* build name */, - const char *zMode /* build mode */, - int flags /* LIBMODE_... mask */, - const char *zApiJsOut /* name of generated sqlite3-api.js/.mjs */, - const char *zJsOut /* name of generated sqlite3.js/.mjs */, - const char *zCmppD /* extra -D flags for c-pp */, - const char *zEmcc /* extra flags for emcc */){ +static void mk_lib_mode(const BuildDef * pB){ const char * zWasmOut = "$(basename $@).wasm" /* The various targets named X.js or X.mjs (zJsOut) also generate ** X.wasm, and we need that part of the name to perform some ** post-processing after Emscripten generates X.wasm. */; - assert( zName ); - assert( zMode ); - assert( zApiJsOut ); - assert( zJsOut ); - if( !zCmppD ) zCmppD = ""; - if( !zEmcc ) zEmcc = ""; + assert( pB->zName ); + assert( pB->zMode ); + assert( pB->zApiJsOut ); + assert( pB->zJsOut ); +#define MT(X) ((X) ? (X) : "") +/* Very common printf() args combo. */ +#define zNM pB->zName, pB->zMode pf("%s# Begin build [%s-%s]\n", zBanner, zNM); - pf("# zApiJsOut=%s\n# zJsOut=%s\n# zCmppD=%s\n", zApiJsOut, zJsOut, zCmppD); - pf("$(info Setting up build [%s-%s]: %s)\n", zNM, zJsOut); - mk_pre_post(zNM, flags, zCmppD); + pf("# zApiJsOut=%s\n# zJsOut=%s\n# zCmppD=%s\n", + pB->zApiJsOut, pB->zJsOut, MT(pB->zCmppD)); + pf("$(info Setting up build [%s-%s]: %s)\n", zNM, pB->zJsOut); + mk_pre_post(zNM, pB->flags, pB->zCmppD); pf("\nemcc.flags.%s.%s ?=\n", zNM); - if( zEmcc[0] ){ - pf("emcc.flags.%s.%s += %s\n", zNM, zEmcc); + if( pB->zEmcc && pB->zEmcc[0] ){ + pf("emcc.flags.%s.%s += %s\n", zNM, pB->zEmcc); } pf("$(eval $(call SQLITE.CALL.C-PP.FILTER, $(sqlite3-api.js.in), %s, %s))\n", - zApiJsOut, zCmppD); + pB->zApiJsOut, MT(pB->zCmppD)); - /* target zJsOut */ + /* target pB->zJsOut */ pf("%s: %s $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) " "$(pre-post-%s-%s.deps) " "$(sqlite3-api.ext.jses)" @@ -319,22 +375,23 @@ static void mk_lib_mode(const char *zName /* build name */, are still compiling, which is especially helpful when running builds with long build times (like -Oz). */ "\n", - zJsOut, zApiJsOut, zNM); + pB->zJsOut, pB->zApiJsOut, zNM); pf("\t@echo \"Building $@ ...\"\n"); pf("\t$(bin.emcc) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n"); - pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", zMode); + pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", + pB->zMode); pf("\t\t$(pre-post-%s-%s.flags) \\\n", zNM); - pf("\t\t$(emcc.flags.%s) $(emcc.flags.%s.%s) \\\n", zName, zNM); + pf("\t\t$(emcc.flags.%s) $(emcc.flags.%s.%s) \\\n", pB->zName, zNM); pf("\t\t$(cflags.common) $(SQLITE_OPT) \\\n" "\t\t$(cflags.%s) $(cflags.%s.%s) \\\n" - "\t\t$(cflags.wasm_extra_init) $(sqlite3-wasm.cfiles)\n", zName, zNM); - if( (LIBMODE_ESM & flags) || (LIBMODE_NODEJS & flags) ){ + "\t\t$(cflags.wasm_extra_init) $(sqlite3-wasm.cfiles)\n", pB->zName, zNM); + if( (LIBMODE_ESM & pB->flags) || (LIBMODE_NODEJS & pB->flags) ){ /* TODO? Replace this $(call) with the corresponding makefile ** code. OTOH, we also use this $(call) in the speedtest1-wasmfs ** build, which is not part of the rules emitted by this ** program. */ pf("\t@$(call SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT,1,%d)\n", - (LIBMODE_WASMFS & flags) ? 1 : 0); + (LIBMODE_WASMFS & pB->flags) ? 1 : 0); } pf("\t@chmod -x %s; \\\n" "\t\t$(maybe-wasm-strip) %s;\n", @@ -343,7 +400,7 @@ static void mk_lib_mode(const char *zName /* build name */, pf("\t@sed -i -e '/^var _sqlite3.*createExportWrapper/d' %s || exit; \\\n" /* ^^^^^^ reminder: Mac/BSD sed has no -i flag */ "\t\techo 'Stripped out createExportWrapper() parts.'\n", - zJsOut) /* Our JS code installs bindings of each WASM export. The + pB->zJsOut) /* Our JS code installs bindings of each WASM export. The generated Emscripten JS file does the same using its own framework, but we don't use those results and can speed up lib init, and reduce memory cost @@ -356,59 +413,44 @@ static void mk_lib_mode(const char *zName /* build name */, ** resulting .wasm file is identical for all builds for which zEmcc ** is empty. */ - if( (LIBMODE_BUNDLER_FRIENDLY & flags) - || (LIBMODE_NODEJS & flags) ){ - pf("\t@echo 'Patching $@ for %s.wasm...'; \\\n", zName); + if( (LIBMODE_BUNDLER_FRIENDLY & pB->flags) + || (LIBMODE_NODEJS & pB->flags) ){ + pf("\t@echo 'Patching $@ for %s.wasm...'; \\\n", pB->zName); pf("\t\trm -f %s; \\\n", zWasmOut); pf("\t\tsed -i -e 's/%s-%s.wasm/%s.wasm/g' $@ || exit;\n", - /* ^^^^^^ reminder: Mac/BSD sed has no -i flag */ - zNM, zName); + /* ^^^^^^ reminder: Mac/BSD sed has no -i flag but this + ** build process explicitly requires a Linux system. */ + zNM, pB->zName); pf("\t@ls -la $@\n"); - if( LIBMODE_BUNDLER_FRIENDLY & flags ){ + if( LIBMODE_BUNDLER_FRIENDLY & pB->flags ){ /* Avoid a 3rd occurrence of the bug fixed by 65798c09a00662a3, ** which was (in two cases) caused by makefile refactoring and ** not recognized until after a release was made with the broken - ** sqlite3-bundler-friendly.mjs: */ + ** sqlite3-bundler-friendly.mjs (which is used by the npm + ** subproject but is otherwise untested/unsupported): */ pf("\t@if grep -e '^ *importScripts(' $@; " "then echo 'ERROR: bug fixed in 65798c09a00662a3 has re-appeared'; " "exit 1; fi;\n"); } - }else{ pf("\t@ls -la %s $@\n", zWasmOut); } - if( 0==(LIBMODE_DONT_ADD_TO_ALL & flags) ){ - pf("all: %s\n", zJsOut); + if( 0==(LIBMODE_DONT_ADD_TO_ALL & pB->flags) ){ + pf("all: %s\n", pB->zJsOut); } pf("# End build [%s-%s]%s", zNM, zBanner); +#undef MT +#undef zNM } int main(void){ int rc = 0; + const BuildDef *pB = &aBuildDefs[0]; pf("# What follows was GENERATED by %s. Edit at your own risk.\n", __FILE__); mk_prologue(); - mk_lib_mode("sqlite3", "vanilla", 0, - "$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0); - mk_lib_mode("sqlite3", "esm", LIBMODE_ESM, - "$(sqlite3-api.mjs)", "$(sqlite3.mjs)", - "-Dtarget=es6-module", 0); - mk_lib_mode("sqlite3", "bundler-friendly", - LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, - "$(sqlite3-api-bundler-friendly.mjs)", - "$(sqlite3-bundler-friendly.mjs)", - "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0); - mk_lib_mode("sqlite3" , "node", - LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, - "$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)", - "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0); - mk_lib_mode("sqlite3-wasmfs", "esm" , - LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, - /* The sqlite3-wasmfs build is optional and needs to be invoked - ** conditionally using info we don't have here. */ - "$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)", - "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", - "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"); - + for( ; pB->zName; ++pB ){ + mk_lib_mode( pB ); + } mk_fiddle(); mk_pre_post("speedtest1","vanilla", 0, 0); mk_pre_post("speedtest1-wasmfs","esm", 0, diff --git a/manifest b/manifest index 6dd5cd61af..92cb421137 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Teach\sthe\ssqlite3\sCLI\sshell\sto\slook\sin\sXDG_STATE_HOME\sfor\sthe\sCLI\shistory\sfile\sbefore\sfalling\sback\sto\sits\shistorical\slocation\sin\sthe\suser's\shome\sdirectory. -D 2025-07-16T09:27:55.137 +C Internal\srefactoring\sof\sthe\sWASM\sbuild\smakefile\srule\sgenerator,\sworking\stowards\sparallelizing\sthe\svarious\sbuild\smodes\s(which\sis\snot\scurrently\spossible\sbecause\smost\smodes\sshare\sthe\ssame\ssqlite3.wasm\soutput\sfile\sname). +D 2025-07-16T10:34:14.710 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c 5b096a3c9fdf6e67eb20329dc685f995e820248a67fa970633c2c8f49bf472ad +F ext/wasm/mkwasmbuilds.c 37520a569fc2503d294229601badde24104a08054f86da91f36d83f9d4246cd3 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -2213,9 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839 73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b -R 301553834aa3054a0cc5a0c4c21b9798 -T +closed 73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b Closed\sby\sintegrate-merge. +P 1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e +R 4688f06c662343c6a49d62d0942495eb U stephan -Z f8c26aad77c21d4fab9a1de2f2326205 +Z ccdf1d3c1044525847429d3e2a360fc7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index abbd3fd28c..df1720da75 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e +1062b61e9c949d76791ed7974cf6c38d1cec9797a930e9ad7ca851130f5e9a48 From e5a7b815af68e40ab7ec0d2b443fa258ce64cc14 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 11:09:18 +0000 Subject: [PATCH 82/88] Further internal wasm build cleanups. No functional changes. FossilOrigin-Name: 8364d89c3bc1d1dbd95b4324a41bd655251ebd2da5b9f1b9f9aceba9c3d26d3d --- ext/wasm/GNUmakefile | 9 +++------ ext/wasm/mkwasmbuilds.c | 41 ++++++++++++++++++++++++----------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 51a6bf965f..77fdce8107 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -860,15 +860,10 @@ if [ x1 = x$(1) ]; then \ fi endef -sqlite3-api.js := $(dir.dout)/sqlite3-api.js sqlite3.js := $(dir.dout)/sqlite3.js -sqlite3-api.mjs := $(dir.dout)/sqlite3-api.mjs sqlite3.mjs := $(dir.dout)/sqlite3.mjs -sqlite3-api-bundler-friendly.mjs := $(dir.dout)/sqlite3-api-bundler-friendly.mjs sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs -sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs -sqlite3-api-wasmfs.mjs := $(dir.tmp)/sqlite3-api-wasmfs.mjs sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle @@ -913,7 +908,9 @@ $(sqlite3-node.mjs): $(sqlite3.mjs) # bundler-friendly build. Concretely, any supplemental JS files which # themselves use importScripts() or Workers or URL() constructors # which refer to other in-tree (m)JS files require a bundler-friendly -# copy. +# copy. Bundler-friendly builds replace certain references to string +# vars/expressions with string literals, as bundler tools are static +# code analyzers and cannot cope with the former. sqlite3-worker1.js.in := $(dir.api)/sqlite3-worker1.c-pp.js sqlite3-worker1-promiser.js.in := $(dir.api)/sqlite3-worker1-promiser.c-pp.js sqlite3-worker1.js := $(dir.dout)/sqlite3-worker1.js diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index bc2ae04232..5e9bdd6a36 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -11,18 +11,17 @@ ************************************************************************* ** ** This app's single purpose is to emit parts of the Makefile code for -** building sqlite3's WASM build. The main motivation is to generate -** code which "can" be created via GNU Make's eval command but is +** sqlite3's canonical WASM build. The main motivation is to generate +** code which "could" be created via GNU Make's eval command but is ** highly illegible when constructed that way. Attempts to write this -** app in Bash and TCL have suffered from the problem that both -** require escaping $ symbols, making the resulting script code as -** illegible as the eval spaghetti we want to get away from. Writing -** it in C is, somewhat surprisingly, _slightly_ less illegible than -** writing it in bash, tcl, or native Make code. +** app in Bash and TCL have suffered from the problem that those +** languages require escaping $ symbols, making the resulting script +** code as illegible as the eval spaghetti we want to get away +** from. Maintaining it in C is, somewhat surprisingly, _slightly_ +** less illegible than writing it in bash, tcl, or native Make code. ** ** The emitted makefile code is not standalone - it depends on ** variables and $(call)able functions from the main makefile. -** */ #undef NDEBUG @@ -35,15 +34,19 @@ #define ps puts /* -** Valid names for the zName arguments. +** Valid build names. Each build is a combination of one of these and +** one of JS_BUILD_MODES, but only certain combinations are legal. +** This macro and JS_BUILD_MODES exist solely for documentation +** purposes: they are not expanded into code anywhere. */ #define JS_BUILD_NAMES sqlite3 sqlite3-wasmfs /* -** Valid names for the zMode arguments of the "sqlite3" build. For the -** "sqlite3-wasmfs" build, only "esm" (ES6 Module) is legal. +** Valid build modes. For the "sqlite3-wasmfs" build, only "esm" (ES6 +** Module) is legal. */ #define JS_BUILD_MODES vanilla esm bundler-friendly node -/* Separator to help eyeballs find the different sections */ + +/* Separator to help eyeballs find the different output sections */ static const char * zBanner = "\n########################################################################\n"; @@ -82,6 +85,8 @@ struct BuildDef { int flags; /* Flags from LibModeFlags */ const char *zApiJsOut; /* Name of generated sqlite3-api.js/.mjs */ const char *zJsOut; /* Name of generated sqlite3.js/.mjs */ + /* TODO: dynamically determine zApiJsOut and zJsOut based on zName, zMode, + and flags. */ const char *zCmppD; /* Extra -D... flags for c-pp */ const char *zEmcc; /* Extra flags for emcc */ }; @@ -95,24 +100,25 @@ typedef struct BuildDef BuildDef; const BuildDef aBuildDefs[] = { {/* Core build */ "sqlite3", "vanilla", LIBMODE_PLAIN, - "$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0}, + "$(dir.dout)/sqlite3-api.js", "$(sqlite3.js)", 0, 0}, {/* Core ESM */ "sqlite3", "esm", LIBMODE_ESM, - "$(sqlite3-api.mjs)", "$(sqlite3.mjs)", + "$(dir.dout)/sqlite3-api.mjs", "$(sqlite3.mjs)", "-Dtarget=es6-module", 0}, {/* Core bundler-friend. Untested and "not really" supported, but ** required by the downstream npm subproject. */ "sqlite3", "bundler-friendly", LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, - "$(sqlite3-api-bundler-friendly.mjs)", + "$(dir.dout)/sqlite3-api-bundler-friendly.mjs", "$(sqlite3-bundler-friendly.mjs)", "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0}, {/* node.js mode. Untested and unsupported. */ "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, - "$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)", + "$(dir.dout)/sqlite3-api-node.mjs", + "$(sqlite3-node.mjs)", "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0}, {/* The wasmfs build is optional, untested, unsupported, and @@ -120,7 +126,8 @@ const BuildDef aBuildDefs[] = { ** here. */ "sqlite3-wasmfs", "esm" , LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, - "$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)", + "$(dir.tmp)/sqlite3-api-wasmfs.mjs", + "$(sqlite3-wasmfs.mjs)", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"}, diff --git a/manifest b/manifest index 92cb421137..eb07435b60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Internal\srefactoring\sof\sthe\sWASM\sbuild\smakefile\srule\sgenerator,\sworking\stowards\sparallelizing\sthe\svarious\sbuild\smodes\s(which\sis\snot\scurrently\spossible\sbecause\smost\smodes\sshare\sthe\ssame\ssqlite3.wasm\soutput\sfile\sname). -D 2025-07-16T10:34:14.710 +C Further\sinternal\swasm\sbuild\scleanups.\sNo\sfunctional\schanges. +D 2025-07-16T11:09:18.263 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -622,7 +622,7 @@ F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile d62af1b0914eb2e03fa6e4e75e93acadc8f4faeb2d56335da25d61b9ea144c53 +F ext/wasm/GNUmakefile eae071f5b1d3446052cb3f5e59a1306b0c8b1af83626dcf26f7bada7fa258352 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c 37520a569fc2503d294229601badde24104a08054f86da91f36d83f9d4246cd3 +F ext/wasm/mkwasmbuilds.c f6c528b34e1758267b43365532a3e701ff817a00b92ac8ed2fdec62090d6fe62 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e -R 4688f06c662343c6a49d62d0942495eb +P 1062b61e9c949d76791ed7974cf6c38d1cec9797a930e9ad7ca851130f5e9a48 +R b2a9312c73209dce3b276f9c450c5ef5 U stephan -Z ccdf1d3c1044525847429d3e2a360fc7 +Z 2a2a13815507fb8a535b706df3b4d0cb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index df1720da75..78d50ea1e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1062b61e9c949d76791ed7974cf6c38d1cec9797a930e9ad7ca851130f5e9a48 +8364d89c3bc1d1dbd95b4324a41bd655251ebd2da5b9f1b9f9aceba9c3d26d3d From 68b74e2c4211a70381b7fa5ec9472be4b36ec52d Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 11:56:16 +0000 Subject: [PATCH 83/88] Remove an unnecessary step from the wasm builds and account for a recent Emscripten-internal code-generation change which caused a post-build cleanup step to not actually clean up (harmless, but adds about 26k of useless stuff to the resulting JS). FossilOrigin-Name: a8ed16989dcd324bd9caa09aec7979249deaf59ca13bc377379ddd83c53379cd --- ext/wasm/GNUmakefile | 7 +------ ext/wasm/mkwasmbuilds.c | 26 ++++++++------------------ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 77fdce8107..c6843b160b 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -573,12 +573,7 @@ $(SOAP.js.bld): $(SOAP.js) # Sidebar: some of the imports are used soley by the Emscripten glue, # which the sqlite3 JS code does not rely on. # -# We build $(sqlite3-api*.*) "because we can" and because it might be -# a useful point of experimentation for some clients, but the -# above-described caveat may well make them unusable for real-life -# clients. -# -# sqlite3-api.js.in = the generated sqlite3-api.js before it gets +# sqlite3-api.js.in = the amalgamated sqlite3-api.js before it gets # preprocessed. It contains all of $(sqlite3-api.jses) but none of the # Emscripten-specific headers and footers. sqlite3-api.js.in := $(dir.tmp)/sqlite3-api.c-pp.js diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index 5e9bdd6a36..0bba164914 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -83,7 +83,6 @@ struct BuildDef { const char *zName; /* Name from JS_BUILD_NAMES */ const char *zMode; /* Name from JS_BUILD_MODES */ int flags; /* Flags from LibModeFlags */ - const char *zApiJsOut; /* Name of generated sqlite3-api.js/.mjs */ const char *zJsOut; /* Name of generated sqlite3.js/.mjs */ /* TODO: dynamically determine zApiJsOut and zJsOut based on zName, zMode, and flags. */ @@ -99,25 +98,21 @@ typedef struct BuildDef BuildDef; */ const BuildDef aBuildDefs[] = { {/* Core build */ - "sqlite3", "vanilla", LIBMODE_PLAIN, - "$(dir.dout)/sqlite3-api.js", "$(sqlite3.js)", 0, 0}, + "sqlite3", "vanilla", LIBMODE_PLAIN, "$(sqlite3.js)", 0, 0}, {/* Core ESM */ - "sqlite3", "esm", LIBMODE_ESM, - "$(dir.dout)/sqlite3-api.mjs", "$(sqlite3.mjs)", + "sqlite3", "esm", LIBMODE_ESM, "$(sqlite3.mjs)", "-Dtarget=es6-module", 0}, {/* Core bundler-friend. Untested and "not really" supported, but ** required by the downstream npm subproject. */ "sqlite3", "bundler-friendly", LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, - "$(dir.dout)/sqlite3-api-bundler-friendly.mjs", "$(sqlite3-bundler-friendly.mjs)", "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0}, {/* node.js mode. Untested and unsupported. */ "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, - "$(dir.dout)/sqlite3-api-node.mjs", "$(sqlite3-node.mjs)", "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0}, @@ -126,12 +121,11 @@ const BuildDef aBuildDefs[] = { ** here. */ "sqlite3-wasmfs", "esm" , LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, - "$(dir.tmp)/sqlite3-api-wasmfs.mjs", "$(sqlite3-wasmfs.mjs)", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"}, - {/*End-of-list sentinel*/0,0,0,0,0,0,0} + {/*End-of-list sentinel*/0,0,0,0,0,0} }; /* @@ -354,26 +348,22 @@ static void mk_lib_mode(const BuildDef * pB){ ** post-processing after Emscripten generates X.wasm. */; assert( pB->zName ); assert( pB->zMode ); - assert( pB->zApiJsOut ); assert( pB->zJsOut ); #define MT(X) ((X) ? (X) : "") /* Very common printf() args combo. */ #define zNM pB->zName, pB->zMode - pf("%s# Begin build [%s-%s]\n", zBanner, zNM); - pf("# zApiJsOut=%s\n# zJsOut=%s\n# zCmppD=%s\n", - pB->zApiJsOut, pB->zJsOut, MT(pB->zCmppD)); + pf("%s# Begin build [%s-%s]. flags=0x%02x\n", zBanner, zNM, pB->flags); + pf("# zJsOut=%s\n# zCmppD=%s\n", pB->zJsOut, MT(pB->zCmppD)); pf("$(info Setting up build [%s-%s]: %s)\n", zNM, pB->zJsOut); mk_pre_post(zNM, pB->flags, pB->zCmppD); pf("\nemcc.flags.%s.%s ?=\n", zNM); if( pB->zEmcc && pB->zEmcc[0] ){ pf("emcc.flags.%s.%s += %s\n", zNM, pB->zEmcc); } - pf("$(eval $(call SQLITE.CALL.C-PP.FILTER, $(sqlite3-api.js.in), %s, %s))\n", - pB->zApiJsOut, MT(pB->zCmppD)); /* target pB->zJsOut */ - pf("%s: %s $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) " + pf("%s: $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) " "$(pre-post-%s-%s.deps) " "$(sqlite3-api.ext.jses)" /* ^^^ maintenance reminder: we set these as deps so that they @@ -382,7 +372,7 @@ static void mk_lib_mode(const BuildDef * pB){ are still compiling, which is especially helpful when running builds with long build times (like -Oz). */ "\n", - pB->zJsOut, pB->zApiJsOut, zNM); + pB->zJsOut, zNM); pf("\t@echo \"Building $@ ...\"\n"); pf("\t$(bin.emcc) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n"); pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", @@ -404,7 +394,7 @@ static void mk_lib_mode(const BuildDef * pB){ "\t\t$(maybe-wasm-strip) %s;\n", zWasmOut, zWasmOut); pf("\t@$(call SQLITE.CALL.WASM-OPT,%s)\n", zWasmOut); - pf("\t@sed -i -e '/^var _sqlite3.*createExportWrapper/d' %s || exit; \\\n" + pf("\t@sed -i -e '/^.*= *_sqlite.*= *createExportWrapper/d' %s || exit; \\\n" /* ^^^^^^ reminder: Mac/BSD sed has no -i flag */ "\t\techo 'Stripped out createExportWrapper() parts.'\n", pB->zJsOut) /* Our JS code installs bindings of each WASM export. The diff --git a/manifest b/manifest index eb07435b60..00be8a368f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sinternal\swasm\sbuild\scleanups.\sNo\sfunctional\schanges. -D 2025-07-16T11:09:18.263 +C Remove\san\sunnecessary\sstep\sfrom\sthe\swasm\sbuilds\sand\saccount\sfor\sa\srecent\sEmscripten-internal\scode-generation\schange\swhich\scaused\sa\spost-build\scleanup\sstep\sto\snot\sactually\sclean\sup\s(harmless,\sbut\sadds\sabout\s26k\sof\suseless\sstuff\sto\sthe\sresulting\sJS). +D 2025-07-16T11:56:16.567 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -622,7 +622,7 @@ F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile eae071f5b1d3446052cb3f5e59a1306b0c8b1af83626dcf26f7bada7fa258352 +F ext/wasm/GNUmakefile 52fb4cde68470c35e95a0815f575ad039cbe13b7dba7e1da7c71cb0924ad0ea8 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c f6c528b34e1758267b43365532a3e701ff817a00b92ac8ed2fdec62090d6fe62 +F ext/wasm/mkwasmbuilds.c 7468d1775bf3713f568fd2632464094d1792ce25ebd4cb9ee218420b4178bebe F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1062b61e9c949d76791ed7974cf6c38d1cec9797a930e9ad7ca851130f5e9a48 -R b2a9312c73209dce3b276f9c450c5ef5 +P 8364d89c3bc1d1dbd95b4324a41bd655251ebd2da5b9f1b9f9aceba9c3d26d3d +R 0893c79a61f46e221edf5665d49d3e5c U stephan -Z 2a2a13815507fb8a535b706df3b4d0cb +Z 67fac4b4445edb998537bdf8f4c47b0b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 78d50ea1e6..760fc1f022 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8364d89c3bc1d1dbd95b4324a41bd655251ebd2da5b9f1b9f9aceba9c3d26d3d +a8ed16989dcd324bd9caa09aec7979249deaf59ca13bc377379ddd83c53379cd From 522ce567348a34e5e7dd02ea0d18b6d63c4f8d1a Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 13:22:38 +0000 Subject: [PATCH 84/88] wasm: remove some extraneous levels of makefile var and fix the (unsupported) wasmfs speedtest1 build to account for var renaming which happened long before this. FossilOrigin-Name: 35b2315343e22ca12c6ee3f5be8741eba889bb6461e08fad0a8ae7db033319cb --- ext/wasm/GNUmakefile | 81 +++++++++++++--------------- ext/wasm/api/sqlite3-api-oo1.c-pp.js | 2 +- ext/wasm/mkwasmbuilds.c | 57 +++++++++++++------- ext/wasm/wasmfs.make | 35 ++++++------ manifest | 18 +++---- manifest.uuid | 2 +- 6 files changed, 103 insertions(+), 92 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index c6843b160b..1c07953a80 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -505,9 +505,6 @@ $(EXPORTED_FUNCTIONS.api): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c # sqlite3-license-version.js = generated JS file with the license # header and version info. sqlite3-license-version.js := $(dir.tmp)/sqlite3-license-version.js -# sqlite3-license-version-header.js = JS file containing only the -# license header. -sqlite3-license-version-header.js := $(dir.api)/sqlite3-license-version-header.js # sqlite3-api-build-version.js = generated JS file which populates the # sqlite3.version object using $(bin.version-info). sqlite3-api-build-version.js := $(dir.tmp)/sqlite3-api-build-version.js @@ -578,7 +575,7 @@ $(SOAP.js.bld): $(SOAP.js) # Emscripten-specific headers and footers. sqlite3-api.js.in := $(dir.tmp)/sqlite3-api.c-pp.js $(sqlite3-api.js.in): $(MKDIR.bld) $(sqlite3-api.jses) $(MAKEFILE) - @echo "Making $@..." + @echo "Making $@ ..." @for i in $(sqlite3-api.jses); do \ echo "/* BEGIN FILE: $$i */"; \ cat $$i; \ @@ -767,17 +764,17 @@ $(sqlite3-api-build-version.js): $(MKDIR.bld) $(bin.version-info) $(MAKEFILE) # # Maintenance reminder: there are awk binaries out there which do not # support -e SCRIPT. -$(sqlite3-license-version.js): $(MKDIR.bld) $(sqlite3.h) $(sqlite3-license-version-header.js) \ - $(MAKEFILE) +$(sqlite3-license-version.js): $(MKDIR.bld) $(sqlite3.h) \ + $(dir.api)/sqlite3-license-version-header.js $(MAKEFILE) @echo "Making $@..."; { \ - cat $(sqlite3-license-version-header.js); \ + cat $(dir.api)/sqlite3-license-version-header.js; \ echo '/*'; \ echo '** This code was built from sqlite3 version...'; \ echo "**"; \ awk '/define SQLITE_VERSION/{$$1=""; print "**" $$0}' $(sqlite3.h); \ awk '/define SQLITE_SOURCE_ID/{$$1=""; print "**" $$0}' $(sqlite3.h); \ echo "**"; \ - echo "** Using the Emscripten SDK version $(emcc.version)."; \ + echo "** with the help of Emscripten SDK version $(emcc.version)."; \ echo '*/'; \ } > $@ @@ -857,9 +854,6 @@ endef sqlite3.js := $(dir.dout)/sqlite3.js sqlite3.mjs := $(dir.dout)/sqlite3.mjs -sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs -sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs -sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle # The various -D... values used by *.c-pp.js include: @@ -894,26 +888,10 @@ EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle # build time). $(sqlite3.wasm): $(sqlite3.js) $(sqlite3.mjs): $(sqlite3.js) -$(sqlite3-bundler-friendly.mjs): $(sqlite3.mjs) -$(sqlite3-node.mjs): $(sqlite3.mjs) +$(dir.dout)/sqlite3-bundler-friendly.mjs: $(sqlite3.mjs) +$(dir.dout)/sqlite3-node.mjs: $(sqlite3.mjs) #CLEAN_FILES += $(sqlite3.wasm) -######################################################################## -# We need separate copies of certain supplementary JS files for the -# bundler-friendly build. Concretely, any supplemental JS files which -# themselves use importScripts() or Workers or URL() constructors -# which refer to other in-tree (m)JS files require a bundler-friendly -# copy. Bundler-friendly builds replace certain references to string -# vars/expressions with string literals, as bundler tools are static -# code analyzers and cannot cope with the former. -sqlite3-worker1.js.in := $(dir.api)/sqlite3-worker1.c-pp.js -sqlite3-worker1-promiser.js.in := $(dir.api)/sqlite3-worker1-promiser.c-pp.js -sqlite3-worker1.js := $(dir.dout)/sqlite3-worker1.js -sqlite3-worker1-promiser.js := $(dir.dout)/sqlite3-worker1-promiser.js -sqlite3-worker1-promiser.mjs := $(dir.dout)/sqlite3-worker1-promiser.mjs -sqlite3-worker1-bundler-friendly.mjs := $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs -sqlite3-worker1-promiser-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js - ifneq (1,$(MAKING_CLEAN)) # This block MUST come between the above definitions of # sqlite3-...js/mjs and the $(eval) calls below this block which use @@ -926,6 +904,9 @@ ifneq (1,$(MAKING_CLEAN)) # the $ references in those languages made it just as illegible as the # native makefile code. Somewhat surprisingly, moving that code generation # to C makes it slightly less illegible than the previous 3 options. +# +# Maintenance note: the various $(c-pp.D.XYZ) vars are defined in this +# step. bin.mkwb := ./mkwasmbuilds $(bin.mkwb): $(bin.mkwb).c $(MAKEFILE) $(CC) -o $@ $< @@ -938,34 +919,48 @@ DISTCLEAN_FILES += $(bin.mkwb) endif DISTCLEAN_FILES += .wasmbuilds.make -$(eval $(call SQLITE.CALL.C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1.js))) -$(eval $(call SQLITE.CALL.C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.mjs),\ +######################################################################## +# We need separate copies of certain supplementary JS files for the +# bundler-friendly build. Concretely, any supplemental JS files which +# themselves use importScripts() or Workers or URL() constructors +# which refer to other in-tree (m)JS files require a bundler-friendly +# copy. Bundler-friendly builds replace certain references to string +# vars/expressions with string literals, as bundler tools are static +# code analyzers and cannot cope with the former. +# +# Most of what follows is the generation of those copies. +$(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1.c-pp.js,\ + $(dir.dout)/sqlite3-worker1.js)) +$(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1.c-pp.js,\ + $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs,\ $(c-pp.D.sqlite3-bundler-friendly))) -$(eval $(call SQLITE.CALL.C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.js))) -$(eval $(call SQLITE.CALL.C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),\ - $(sqlite3-worker1-promiser-bundler-friendly.js),\ +$(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\ + $(dir.dout)/sqlite3-worker1-promiser.js)) +$(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\ + $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js,\ $(c-pp.D.sqlite3-bundler-friendly))) -$(eval $(call SQLITE.CALL.C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.mjs),\ +$(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\ + $(dir.dout)/sqlite3-worker1-promiser.mjs,\ -Dtarget=es6-module -Dtarget=es6-bundler-friendly)) -$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.mjs) \ - $(sqlite3-worker1-promiser-bundler-friendly.js) +$(dir.dout)/sqlite3-bundler-friendly.mjs: $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs \ + $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.js)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.mjs,\ -Dtarget=es6-module)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser.html)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser-esm.html,\ -Dtarget=es6-module)) -all: $(sqlite3-worker1.js) \ - $(sqlite3-worker1-promiser.js) $(sqlite3-worker1-promiser.mjs) +all: $(dir.dout)/sqlite3-worker1.js \ + $(dir.dout)/sqlite3-worker1-promiser.js $(dir.dout)/sqlite3-worker1-promiser.mjs -demo-worker1-promiser.html: $(sqlite3-worker1-promiser.js) demo-worker1-promiser.js +demo-worker1-promiser.html: $(dir.dout)/sqlite3-worker1-promiser.js demo-worker1-promiser.js demo-worker1-promiser-esm.html: $(sqlite3-worker1-promiser.mjs) demo-worker1-promiser.mjs all: demo-worker1-promiser.html demo-worker1-promiser-esm.html sqlite3-api.ext.jses += \ $(sqlite3-worker1-promiser.mjs) \ - $(sqlite3-worker1-bundler-friendly.mjs) \ - $(sqlite3-worker1.js) + $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs \ + $(dir.dout)/sqlite3-worker1.js all quick: $(sqlite3-api.ext.jses) q: quick @@ -1091,7 +1086,7 @@ $(eval $(call SQLITE.CALL.C-PP.FILTER,tester1.c-pp.js,tester1.mjs,$(c-pp.D.sqlit $(eval $(call SQLITE.CALL.C-PP.FILTER,tester1.c-pp.html,tester1.html)) $(eval $(call SQLITE.CALL.C-PP.FILTER,tester1.c-pp.html,tester1-esm.html,$(c-pp.D.sqlite3-esm))) tester1: tester1.js tester1.mjs tester1.html tester1-esm.html -# Note that we do not include $(sqlite3-bundler-friendly.mjs) in this +# Note that we do not include $(dir.dout)/sqlite3-bundler-friendly.mjs in this # because bundlers are client-specific. all quick: tester1 quick: $(sqlite3.js) diff --git a/ext/wasm/api/sqlite3-api-oo1.c-pp.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index 62c44fa9d0..8663dcddec 100644 --- a/ext/wasm/api/sqlite3-api-oo1.c-pp.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -13,7 +13,7 @@ This file contains the so-called OO #1 API wrapper for the sqlite3 WASM build. It requires that sqlite3-api-glue.js has already run - and it installs its deliverable as globalThis.sqlite3.oo1. + and it installs its deliverable as sqlite3.oo1. */ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)}; diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index 0bba164914..6b09c3456c 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -108,12 +108,12 @@ const BuildDef aBuildDefs[] = { ** required by the downstream npm subproject. */ "sqlite3", "bundler-friendly", LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, - "$(sqlite3-bundler-friendly.mjs)", + "$(dir.dout)/sqlite3-bundler-friendly.mjs", "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0}, {/* node.js mode. Untested and unsupported. */ "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, - "$(sqlite3-node.mjs)", + "$(dir.dout)/sqlite3-node.mjs", "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0}, {/* The wasmfs build is optional, untested, unsupported, and @@ -121,7 +121,7 @@ const BuildDef aBuildDefs[] = { ** here. */ "sqlite3-wasmfs", "esm" , LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, - "$(sqlite3-wasmfs.mjs)", + "$(dir.wasmfs)/sqlite3-wasmfs.mjs", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"}, @@ -133,17 +133,34 @@ const BuildDef aBuildDefs[] = { ** needed by makefile code outside of these generated pieces). */ static void mk_prologue(void){ + /* A 0-terminated list of makefile vars which we expect to have been + ** set up by this point in the build process. */ + char const * aRequiredVars[] = { + "dir.api", "dir.dout", "dir.tmp", + "sqlite3-license-version.js", + /*"just-testing",*/ + 0 + }; + char const * zVar; + int i; + pf("%s# Build setup sanity checks...\n", zBanner); + for( i = 0; (zVar = aRequiredVars[i]); ++i ){ + pf("ifeq (,$(%s))\n", zVar); + pf(" $(error build process error: expecting make var $$(%s) to " + "have been set up by now)\n", zVar); + ps("endif"); + } pf("%s", zBanner); ps("# extern-post-js* and extern-pre-js* are files for use with"); ps("# Emscripten's --extern-pre-js and --extern-post-js flags."); - ps("extern-pre-js.js := $(dir.api)/extern-pre-js.js"); - ps("extern-post-js.js.in := $(dir.api)/extern-post-js.c-pp.js"); + ps("extern-pre-js.js = $(dir.api)/extern-pre-js.js"); + ps("extern-post-js.js.in = $(dir.api)/extern-post-js.c-pp.js"); ps("# Emscripten flags for --[extern-][pre|post]-js=... for the"); ps("# various builds."); - ps("pre-post-common.flags := --extern-pre-js=$(sqlite3-license-version.js)"); - ps("# pre-post-jses.deps.* = a list of dependencies for the"); - ps("# --[extern-][pre/post]-js files."); - ps("pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)"); + ps("pre-post-common.flags = --extern-pre-js=$(sqlite3-license-version.js)"); + ps("# pre-post-jses.deps.* = a list of dependencies for the\n" + "# --[extern-][pre/post]-js files."); + ps("pre-post-jses.deps.common = $(extern-pre-js.js) $(sqlite3-license-version.js)"); { /* SQLITE.CALL.WASM-OPT = shell code to run $(1) (source wasm file @@ -229,20 +246,20 @@ static void mk_pre_post(const char *zName /* build name */, #define zNM zName, zMode pf("%s# Begin --pre/--post flags for %s-%s\n", zBanner, zNM); - pf("c-pp.D.%s-%s := %s\n", zNM, zCmppD ? zCmppD : ""); + pf("c-pp.D.%s-%s = %s\n", zNM, zCmppD ? zCmppD : ""); pf("pre-post-%s-%s.flags ?=\n", zNM); /* --pre-js=... */ - pf("pre-js.js.%s-%s := $(dir.tmp)/pre-js.%s-%s.js\n", + pf("pre-js.js.%s-%s = $(dir.tmp)/pre-js.%s-%s.js\n", zNM, zNM); - pf("$(pre-js.js.%s-%s): $(MAKEFILE_LIST)\n", zNM); + pf("$(pre-js.js.%s-%s): $(MAKEFILE_LIST) $(sqlite3-license-version.js)\n", zNM); #if 1 pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s)," "$(c-pp.D.%s-%s)))\n", zNM, zNM); #else /* This part is needed if/when we re-enable the custom ** Module.instantiateModule() impl in api/pre-js.c-pp.js. */ - pf("pre-js.js.%s-%s.intermediary := $(dir.tmp)/pre-js.%s-%s.intermediary.js\n", + pf("pre-js.js.%s-%s.intermediary = $(dir.tmp)/pre-js.%s-%s.intermediary.js\n", zNM, zNM); pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s.intermediary)," "$(c-pp.D.%s-%s) -Dcustom-Module.instantiateModule))\n", zNM, zNM); @@ -260,17 +277,17 @@ static void mk_pre_post(const char *zName /* build name */, #endif /* --post-js=... */ - pf("post-js.js.%s-%s := $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM); + pf("post-js.js.%s-%s = $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM); pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(post-js.js.in)," "$(post-js.js.%s-%s),$(c-pp.D.%s-%s)))\n", zNM, zNM); /* --extern-post-js=... */ - pf("extern-post-js.js.%s-%s := $(dir.tmp)/extern-post-js.%s-%s.js\n", zNM, zNM); + pf("extern-post-js.js.%s-%s = $(dir.tmp)/extern-post-js.%s-%s.js\n", zNM, zNM); pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(extern-post-js.js.in),$(extern-post-js.js.%s-%s)," "$(c-pp.D.%s-%s)))\n", zNM, zNM); /* Combined flags for use with emcc... */ - pf("pre-post-common.flags.%s-%s := " + pf("pre-post-common.flags.%s-%s = " "$(pre-post-common.flags) " "--post-js=$(post-js.js.%s-%s) " "--extern-post-js=$(extern-post-js.js.%s-%s)\n", zNM, zNM, zNM); @@ -279,10 +296,10 @@ static void mk_pre_post(const char *zName /* build name */, "--pre-js=$(pre-js.js.%s-%s)\n", zNM, zNM, zNM); /* Set up deps... */ - pf("pre-post-jses.%s-%s.deps := $(pre-post-jses.deps.common) " + pf("pre-post-jses.%s-%s.deps = $(pre-post-jses.deps.common) " "$(post-js.js.%s-%s) $(extern-post-js.js.%s-%s)\n", zNM, zNM, zNM); - pf("pre-post-%s-%s.deps := $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n", + pf("pre-post-%s-%s.deps = $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n", zNM, zNM, zNM); pf("# End --pre/--post flags for %s-%s%s", zNM, zBanner); #undef zNM @@ -301,8 +318,8 @@ static void mk_fiddle(void){ const char *zDir = i ? "$(dir.fiddle-debug)" : "$(dir.fiddle)"; pf("%s# Begin fiddle%s\n", zBanner, zTail); - pf("fiddle-module.js%s := %s/fiddle-module.js\n", zTail, zDir); - pf("fiddle-module.wasm%s := " + pf("fiddle-module.js%s = %s/fiddle-module.js\n", zTail, zDir); + pf("fiddle-module.wasm%s = " "$(subst .js,.wasm,$(fiddle-module.js%s))\n", zTail, zTail); pf("$(fiddle-module.js%s):%s $(MAKEFILE_LIST) $(MAKEFILE.fiddle) " "$(EXPORTED_FUNCTIONS.fiddle) " diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make index 2c6fa35bdd..c4515876fd 100644 --- a/ext/wasm/wasmfs.make +++ b/ext/wasm/wasmfs.make @@ -5,7 +5,7 @@ # sqlite3.wasm. It is intended to be "include"d from the main # GNUMakefile. ######################################################################## -MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST)) +MAKEFILE.wasmfs = $(lastword $(MAKEFILE_LIST)) # ensure that the following message starts on line 10 or higher for proper # $(warning) alignment! ifneq (1,$(MAKING_CLEAN)) @@ -17,8 +17,8 @@ ifneq (1,$(MAKING_CLEAN)) $(warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) endif -sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js -sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm +sqlite3-wasmfs.js = $(dir.wasmfs)/sqlite3-wasmfs.js +sqlite3-wasmfs.wasm = $(dir.wasmfs)/sqlite3-wasmfs.wasm ######################################################################## # emcc flags for .c/.o. @@ -43,7 +43,7 @@ emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations emcc.flags.sqlite3-wasmfs += -sMEMORY64=0 emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) # ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js -sqlite3-wasmfs.fsflags := -pthread -sWASMFS \ +sqlite3-wasmfs.fsflags = -pthread -sWASMFS \ -sPTHREAD_POOL_SIZE=1 \ -sERROR_ON_UNDEFINED_SYMBOLS=0 -sLLD_REPORT_UNDEFINED # ^^^^^ why undefined symbols are necessary for the wasmfs build is anyone's guess. @@ -54,9 +54,8 @@ emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0 # see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth] # And, indeed, it runs slowly if memory is permitted to grow. #emcc.flags.sqlite3-wasmfs.vanilla := -#emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META -all: $(sqlite3-wasmfs.mjs) -$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs) +#emcc.flags.sqlite3-wasmfs.esm = -sEXPORT_ES6 -sUSE_ES6_IMPORT_META +$(sqlite3-wasmfs.js) $(dir.wasmfs)/sqlite3-wasmfs.mjs: $(MAKEFILE.wasmfs) ######################################################################## # Build quirk: we cannot build BOTH .js and .mjs with our current # build infrastructure because the supplemental *.worker.js files get @@ -68,31 +67,31 @@ $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs) # names is that it means that the corresponding .wasm file is also # built/saved multiple times. It is likely that anyone wanting to use # WASMFS will want an ES6 module, so that's what we build here. -wasmfs.build.ext := mjs -$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(SOAP.js.bld) +wasmfs.build.ext = mjs +$(sqlite3-wasmfs.js) $(dir.wasmfs)/sqlite3-wasmfs.mjs: $(SOAP.js.bld) ifeq (js,$(wasmfs.build.ext)) $(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.js) wasmfs: $(sqlite3-wasmfs.js) else - $(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.mjs) - wasmfs: $(sqlite3-wasmfs.mjs) + $(sqlite3-wasmfs.wasm): $(dir.wasmfs)/sqlite3-wasmfs.mjs + wasmfs: $(dir.wasmfs)/sqlite3-wasmfs.mjs endif +all: wasmfs ######################################################################## # speedtest1 for wasmfs. -speedtest1-wasmfs.mjs := $(dir.wasmfs)/speedtest1-wasmfs.mjs -speedtest1-wasmfs.wasm := $(subst .mjs,.wasm,$(speedtest1-wasmfs.mjs)) -emcc.flags.speedtest1-wasmfs := $(sqlite3-wasmfs.fsflags) +speedtest1-wasmfs.mjs = $(dir.wasmfs)/speedtest1-wasmfs.mjs +speedtest1-wasmfs.wasm = $(subst .mjs,.wasm,$(speedtest1-wasmfs.mjs)) +emcc.flags.speedtest1-wasmfs = $(sqlite3-wasmfs.fsflags) emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT) emcc.flags.speedtest1-wasmfs += -sALLOW_MEMORY_GROWTH=0 emcc.flags.speedtest1-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) -#$(eval $(call call-make-pre-js,speedtest1-wasmfs,ems)) +$(info speedtest DEPS=pre-post-sqlite3-wasmfs-esm.deps=$(pre-post-sqlite3-wasmfs-esm.deps)) $(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \ - $(MAKEFILE) $(MAKEFILE.wasmfs) \ - $(pre-post-sqlite3-wasmfs-esm.deps) \ + $(MAKEFILE) $(MAKEFILE.wasmfs) $(pre-post-sqlite3-wasmfs-esm.deps) \ $(EXPORTED_FUNCTIONS.speedtest1) @echo "Building $@ ..." - $(emcc.bin) \ + $(bin.emcc) \ $(pre-post-sqlite3-wasmfs-esm.flags) \ $(cflags.common) \ $(cflags.sqlite3-wasmfs) \ diff --git a/manifest b/manifest index 00be8a368f..29b99cbbaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sstep\sfrom\sthe\swasm\sbuilds\sand\saccount\sfor\sa\srecent\sEmscripten-internal\scode-generation\schange\swhich\scaused\sa\spost-build\scleanup\sstep\sto\snot\sactually\sclean\sup\s(harmless,\sbut\sadds\sabout\s26k\sof\suseless\sstuff\sto\sthe\sresulting\sJS). -D 2025-07-16T11:56:16.567 +C wasm:\sremove\ssome\sextraneous\slevels\sof\smakefile\svar\sand\sfix\sthe\s(unsupported)\swasmfs\sspeedtest1\sbuild\sto\saccount\sfor\svar\srenaming\swhich\shappened\slong\sbefore\sthis. +D 2025-07-16T13:22:38.693 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -622,7 +622,7 @@ F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 52fb4cde68470c35e95a0815f575ad039cbe13b7dba7e1da7c71cb0924ad0ea8 +F ext/wasm/GNUmakefile 472720819d2cde9d7d4c957f2bfb8ebb0193fa75dca10a5c2ab0396ba0ef926b F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -642,7 +642,7 @@ F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-glue.c-pp.js 0b76510f3650053bac67ca8947cb6ab9d050ad2218118a2e7796dd37be832ffa -F ext/wasm/api/sqlite3-api-oo1.c-pp.js f59e59f0d94ba5835c6b7fc9b800a4aa5084e1224721a07e3cd6cc7fef1789c2 +F ext/wasm/api/sqlite3-api-oo1.c-pp.js 852f2cd6acddbae487fc4f1c3ec952e6c1e2033aa4e6c7091d330d983c87c032 F ext/wasm/api/sqlite3-api-prologue.js 4f1c2a9dc9caf631907766e9872c27d11b255ccae779e8af01c7f8b932817214 F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c 7468d1775bf3713f568fd2632464094d1792ce25ebd4cb9ee218420b4178bebe +F ext/wasm/mkwasmbuilds.c 5cf96c716367bb5958fd96caa924aca053df8d84081dd46092dd351d1af6ae90 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -708,7 +708,7 @@ F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328 F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 -F ext/wasm/wasmfs.make 68999f5bd8c489239592d59a420f8c627c99169bbd6fa16a404751f757b9f702 +F ext/wasm/wasmfs.make 4f6a679c06b45039a4b0456a546e95c4f24bf6d33455073bb055cc17b6739550 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk a5d698cf8d38e4eb42a89f08a9521906b24f4acac61bbafa56d72cd9b39617b6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8364d89c3bc1d1dbd95b4324a41bd655251ebd2da5b9f1b9f9aceba9c3d26d3d -R 0893c79a61f46e221edf5665d49d3e5c +P a8ed16989dcd324bd9caa09aec7979249deaf59ca13bc377379ddd83c53379cd +R 9ff9d7c107dd129efe8469b678cd73d7 U stephan -Z 67fac4b4445edb998537bdf8f4c47b0b +Z 9b2f15ac0469aa2bbb0879fb5bc3ce42 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 760fc1f022..b205abb7eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8ed16989dcd324bd9caa09aec7979249deaf59ca13bc377379ddd83c53379cd +35b2315343e22ca12c6ee3f5be8741eba889bb6461e08fad0a8ae7db033319cb From 074b1aa42dd5b4304c3a0653de504c8b10083ef4 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 14:51:23 +0000 Subject: [PATCH 85/88] In the wasm makefiles, replace X:=Y with X=Y because := has different semantics depending on the make impl and its use is arguably a bad muscle-memory habit worth breaking. These makefiles are very specifically for GNU make, but long-term it would be nice to eliminate that requirement. FossilOrigin-Name: d4203311a2f39189ed8f30d519468aed8983af7772a5b247e7557d3e1936064e --- ext/wasm/GNUmakefile | 218 ++++++++++++++++++++------------------- ext/wasm/config.make.in | 13 +-- ext/wasm/dist.make | 32 +++--- ext/wasm/fiddle.make | 42 ++++---- ext/wasm/mkwasmbuilds.c | 31 +++--- ext/wasm/speedtest1.html | 7 +- ext/wasm/wasmfs.make | 6 +- manifest | 24 ++--- manifest.uuid | 2 +- 9 files changed, 189 insertions(+), 186 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 1c07953a80..87c2ca2fcb 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -39,10 +39,11 @@ ######################################################################## default: all #default: quick -MAKEFILE := $(lastword $(MAKEFILE_LIST)) -CLEAN_FILES := -DISTCLEAN_FILES := config.make -MAKING_CLEAN := $(if $(filter %clean,$(MAKECMDGOALS)),1,0) +MAKEFILE = $(lastword $(MAKEFILE_LIST)) +MAKEFILE.fiddle = fiddle.make +CLEAN_FILES = +DISTCLEAN_FILES = config.make +MAKING_CLEAN = $(if $(filter %clean,$(MAKECMDGOALS)),1,0) .PHONY: clean distclean clean: -rm -f $(CLEAN_FILES) @@ -53,17 +54,17 @@ distclean: clean ######################################################################## # Special-case builds for which we require certain pre-conditions # which, if not met, may cause warnings or fatal errors in the build. -# This also affects the default optimization level flags. Note that -# the fiddle targets are in this list because they are used for -# generating sqlite.org/fiddle. -OPTIMIZED_TARGETS := dist snapshot fiddle fiddle.debug +# This also affects the default optimization level flags. The fiddle +# targets are in this list because they are used for generating +# sqlite.org/fiddle. +OPTIMIZED_TARGETS = dist snapshot fiddle fiddle.debug ifeq (1,$(MAKING_CLEAN)) - bin.wasm-strip := echo "not stripping" - bin.wasm-opt := irrelevant - bin.emcc := irrelevant - bin.bash := irrelevant - emcc.version := unknown + bin.wasm-strip = echo "not stripping" + bin.wasm-opt = irrelevant + bin.emcc = irrelevant + bin.bash = irrelevant + emcc.version = unknown else # Include config.make and perform some bootstrapping... ifeq (,$(wildcard ./config.make)) @@ -76,7 +77,7 @@ else ifeq (,$(bin.emcc)) $(error Configure script did not find emcc) endif - emcc.version := $(shell $(bin.emcc) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;') + emcc.version = $(shell $(bin.emcc) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;') $(info using emcc version [$(emcc.version)]) ifeq (,$(bin.wasm-strip)) #################################################################### @@ -98,7 +99,7 @@ else ifneq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS))) $(error Cannot make release-quality binary because wasm-strip is not available.) endif - bin.wasm-strip := echo "not wasm-stripping" + bin.wasm-strip = echo "not wasm-stripping" endif ifeq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS))) $(info ==============================================================) @@ -108,7 +109,7 @@ else endif endif # ^^^ end of are-we-MAKING_CLEAN -maybe-wasm-strip := $(bin.wasm-strip) +maybe-wasm-strip = $(bin.wasm-strip) ######################################################################## # JS_BUILD_NAMES exists for documentation purposes only. It enumerates @@ -118,7 +119,7 @@ maybe-wasm-strip := $(bin.wasm-strip) # # - sqlite3-wasmfs = WASMFS-capable library build # -JS_BUILD_NAMES := sqlite3 sqlite3-wasmfs +JS_BUILD_NAMES = sqlite3 sqlite3-wasmfs ######################################################################## # JS_BUILD_MODES exists for documentation purposes only. It enumerates @@ -140,31 +141,31 @@ JS_BUILD_NAMES := sqlite3 sqlite3-wasmfs # that persistent storage (OPFS) is not available in these builds. # These builds are UNTESTED and UNSUPPORTED! # -JS_BUILD_MODES := vanilla esm bunder-friendly node +JS_BUILD_MODES = vanilla esm bunder-friendly node ######################################################################## # dir.top = the top dir of the canonical build tree, where # sqlite3.[ch] live. -dir.top := ../.. +dir.top = ../.. # Maintenance reminder: some Emscripten flags require absolute paths # but we want relative paths for most stuff simply to reduce # noise. The $(abspath...) GNU make function can transform relative # paths to absolute. -dir.wasm := $(patsubst %/,%,$(dir $(MAKEFILE))) -dir.api := api -dir.jacc := jaccwabyt -dir.common := common -dir.fiddle := fiddle -dir.fiddle-debug := fiddle-debug -dir.tool := $(dir.top)/tool +dir.wasm = $(patsubst %/,%,$(dir $(MAKEFILE))) +dir.api = api +dir.jacc = jaccwabyt +dir.common = common +dir.fiddle = fiddle +dir.fiddle-debug = fiddle-debug +dir.tool = $(dir.top)/tool # dir.dout = output dir for deliverables -dir.dout := $(dir.wasm)/jswasm +dir.dout = $(dir.wasm)/jswasm # dir.tmp = output dir for intermediary build files, as opposed to # end-user deliverables. -dir.tmp := $(dir.wasm)/bld -dir.wasmfs := $(dir.dout) +dir.tmp = $(dir.wasm)/bld +dir.wasmfs = $(dir.dout) -MKDIR.bld := $(dir.tmp) +MKDIR.bld = $(dir.tmp) $(MKDIR.bld): @mkdir -p $@ $(dir.dout) @@ -188,17 +189,17 @@ CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ # $(sqlite3.canonical.c) must point to the sqlite3.c in # the sqlite3 canonical source tree, as that source file # is required for certain utility and test code. -sqlite3.canonical.c := $(dir.top)/sqlite3.c +sqlite3.canonical.c = $(dir.top)/sqlite3.c sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c)) -sqlite3.h := $(dir.top)/sqlite3.h +sqlite3.h = $(dir.top)/sqlite3.h ifeq (1,$(MAKING_CLEAN)) - SQLITE_C_IS_SEE := 0 + SQLITE_C_IS_SEE = 0 else ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c))) - SQLITE_C_IS_SEE := 0 + SQLITE_C_IS_SEE = 0 else - SQLITE_C_IS_SEE := 1 + SQLITE_C_IS_SEE = 1 $(info This is an SEE build) endif endif @@ -216,19 +217,19 @@ $(sqlite3.c): $(sqlite3.h) # barebones=1 disables all "extraneous" stuff from sqlite3-wasm.c, the # goal being to create a WASM file with only the core APIs. ifeq (1,$(barebones)) - wasm-bare-bones := 1 + wasm-bare-bones = 1 $(info ==============================================================) $(info == This is a bare-bones build. It trades away features for) $(info == a smaller .wasm file.) $(info ==============================================================) else - wasm-bare-bones := 0 + wasm-bare-bones = 0 endif # undefine barebones # relatively new gmake feature, not ubiquitous # Common options for building sqlite3-wasm.c and speedtest1.c. # Explicit ENABLEs... -SQLITE_OPT.common := \ +SQLITE_OPT.common = \ -DSQLITE_THREADSAFE=0 \ -DSQLITE_TEMP_STORE=2 \ -DSQLITE_ENABLE_MATH_FUNCTIONS \ @@ -249,7 +250,7 @@ SQLITE_OPT.common := \ SQLITE_OPT.common += -DSQLITE_WASM_ENABLE_C_TESTS # Extra flags for full-featured builds... -SQLITE_OPT.full-featured := \ +SQLITE_OPT.full-featured = \ -DSQLITE_ENABLE_BYTECODE_VTAB \ -DSQLITE_ENABLE_DBPAGE_VTAB \ -DSQLITE_ENABLE_DBSTAT_VTAB \ @@ -265,12 +266,12 @@ SQLITE_OPT.full-featured := \ ifeq (0,$(wasm-bare-bones)) # The so-called canonical build is full-featured: - SQLITE_OPT := \ + SQLITE_OPT = \ $(SQLITE_OPT.common) \ $(SQLITE_OPT.full-featured) else # The so-called bare-bones build is exactly that: - SQLITE_OPT := \ + SQLITE_OPT = \ $(SQLITE_OPT.common) \ -DSQLITE_WASM_BARE_BONES # SQLITE_WASM_BARE_BONES tells sqlite3-wasm.c to explicitly omit @@ -345,10 +346,10 @@ endif # See example_extra_init.c for an example implementation. ######################################################################## sqlite3_wasm_extra_init.c ?= $(wildcard sqlite3_wasm_extra_init.c) -cflags.wasm_extra_init := +cflags.wasm_extra_init = ifneq (,$(sqlite3_wasm_extra_init.c)) $(info Enabling SQLITE_EXTRA_INIT via $(sqlite3_wasm_extra_init.c).) - cflags.wasm_extra_init := -DSQLITE_WASM_EXTRA_INIT + cflags.wasm_extra_init = -DSQLITE_WASM_EXTRA_INIT endif ######################################################################### @@ -362,7 +363,7 @@ endif # end result is that the generated JS files may have static version # info from $(bin.version-info) which differ from their runtime-emitted # version info (e.g. from sqlite3_libversion()). -bin.version-info := $(dir.top)/version-info +bin.version-info = $(dir.top)/version-info .NOTPARALLEL: $(bin.version-info) $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile $(MAKE) -C $(dir.top) version-info @@ -373,7 +374,7 @@ $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile # don't need for all builds. That app's -k flag is of particular # importance here, as it allows us to retain the opening comment # block(s), which contain the license header and version info. -bin.stripccomments := $(dir.tool)/stripccomments +bin.stripccomments = $(dir.tool)/stripccomments $(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE) $(CC) -o $@ $< DISTCLEAN_FILES += $(bin.stripccomments) @@ -410,7 +411,7 @@ DISTCLEAN_FILES += $(bin.stripccomments) # # -D... flags which should be included in all invocations should be # appended to $(SQLITE.CALL.C-PP.FILTER.global). -bin.c-pp := ./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) \ -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ @@ -435,7 +436,7 @@ endef ######################################################################## # cflags.common = C compiler flags for all builds -cflags.common := -I. -I$(dir $(sqlite3.c)) +cflags.common = -I. -I$(dir $(sqlite3.c)) # emcc.WASM_BIGINT = 1 for BigInt (C int64) support, else 0. The API # disables certain features if BigInt is not enabled and such builds # _are not tested_ on any regular basis. @@ -458,7 +459,7 @@ endif # When passing emcc_opt from the CLI, += and re-assignment have no # effect, so emcc_opt+=-g3 doesn't work. So... -emcc_opt_full := $(emcc_opt) -g3 +emcc_opt_full = $(emcc_opt) -g3 # ^^^ ALWAYS use -g3. See below for why. # # ^^^ -flto improves runtime speed at -O0 considerably but doubles @@ -489,28 +490,28 @@ emcc_opt_full := $(emcc_opt) -g3 ######################################################################## # EXPORTED_FUNCTIONS.* = files for use with Emscripten's # -sEXPORTED_FUNCTION flag. -EXPORTED_FUNCTIONS.api.core := $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core -EXPORTED_FUNCTIONS.api.in := $(EXPORTED_FUNCTIONS.api.core) +EXPORTED_FUNCTIONS.api.core = $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core +EXPORTED_FUNCTIONS.api.in = $(EXPORTED_FUNCTIONS.api.core) ifeq (1,$(SQLITE_C_IS_SEE)) EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see endif ifeq (0,$(wasm-bare-bones)) EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras endif -EXPORTED_FUNCTIONS.api := $(dir.tmp)/EXPORTED_FUNCTIONS.api +EXPORTED_FUNCTIONS.api = $(dir.tmp)/EXPORTED_FUNCTIONS.api $(EXPORTED_FUNCTIONS.api): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE) cat $(EXPORTED_FUNCTIONS.api.in) > $@ ######################################################################## # sqlite3-license-version.js = generated JS file with the license # header and version info. -sqlite3-license-version.js := $(dir.tmp)/sqlite3-license-version.js +sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js # sqlite3-api-build-version.js = generated JS file which populates the # sqlite3.version object using $(bin.version-info). -sqlite3-api-build-version.js := $(dir.tmp)/sqlite3-api-build-version.js +sqlite3-api-build-version.js = $(dir.tmp)/sqlite3-api-build-version.js # sqlite3-api.jses = the list of JS files which make up # $(sqlite3-api.js.in), in the order they need to be assembled. -sqlite3-api.jses := $(sqlite3-license-version.js) +sqlite3-api.jses = $(sqlite3-license-version.js) # sqlite3-api-prologue.js: initial bootstrapping bits: sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js # whwhasm.js and jaccwabyt.js: Low-level utils, mostly replacing @@ -544,13 +545,13 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js # SOAP.js is an external API file which is part of our distribution # but not part of the sqlite3-api.js amalgamation. It's a component of # the first OPFS VFS and necessarily an external file. -SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js -SOAP.js.bld := $(dir.dout)/$(notdir $(SOAP.js)) +SOAP.js = $(dir.api)/sqlite3-opfs-async-proxy.js +SOAP.js.bld = $(dir.dout)/$(notdir $(SOAP.js)) # # $(sqlite3-api.ext.jses) = API-related files which are standalone files, # not part of the amalgamation. # -sqlite3-api.ext.jses := $(SOAP.js.bld) +sqlite3-api.ext.jses = $(SOAP.js.bld) $(SOAP.js.bld): $(SOAP.js) cp $< $@ @@ -573,7 +574,7 @@ $(SOAP.js.bld): $(SOAP.js) # sqlite3-api.js.in = the amalgamated sqlite3-api.js before it gets # preprocessed. It contains all of $(sqlite3-api.jses) but none of the # Emscripten-specific headers and footers. -sqlite3-api.js.in := $(dir.tmp)/sqlite3-api.c-pp.js +sqlite3-api.js.in = $(dir.tmp)/sqlite3-api.c-pp.js $(sqlite3-api.js.in): $(MKDIR.bld) $(sqlite3-api.jses) $(MAKEFILE) @echo "Making $@ ..." @for i in $(sqlite3-api.jses); do \ @@ -584,7 +585,7 @@ $(sqlite3-api.js.in): $(MKDIR.bld) $(sqlite3-api.jses) $(MAKEFILE) ######################################################################## # emcc flags for .c/.o/.wasm/.js. -emcc.flags := +emcc.flags = ifeq (1,$(emcc.verbose)) emcc.flags += -v # -v is _very_ loud but also informative about what it's doing @@ -593,7 +594,7 @@ endif ######################################################################## # emcc flags for .c/.o. -emcc.cflags := +emcc.cflags = emcc.cflags += -std=c99 -fPIC # -------------^^^^^^^^ we need c99 for $(sqlite3-wasm.c), primarily # for variadic macros and snprintf() to implement @@ -601,14 +602,14 @@ emcc.cflags += -std=c99 -fPIC emcc.cflags += -I. -I$(dir.top) ######################################################################## # emcc flags specific to building .js/.wasm files... -emcc.jsflags := -fPIC +emcc.jsflags = -fPIC emcc.jsflags += --no-entry emcc.jsflags += -sWASM_BIGINT=$(emcc.WASM_BIGINT) emcc.jsflags += -sMODULARIZE emcc.jsflags += -sDYNAMIC_EXECUTION=0 emcc.jsflags += -sNO_POLYFILL emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.api) -emcc.exportedRuntimeMethods := \ +emcc.exportedRuntimeMethods = \ -sEXPORTED_RUNTIME_METHODS=wasmMemory # wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY # Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default. @@ -633,10 +634,10 @@ emcc.jsflags += -sSTRICT_JS=0 # tools should be installing, e.g. __syscall_geteuid32 # -sENVIRONMENT values for the various build modes: -emcc.environment.vanilla := web,worker -emcc.environment.bundler-friendly := $(emcc.environment.vanilla) -emcc.environment.esm := $(emcc.environment.vanilla) -emcc.environment.node := node +emcc.environment.vanilla = web,worker +emcc.environment.bundler-friendly = $(emcc.environment.vanilla) +emcc.environment.esm = $(emcc.environment.vanilla) +emcc.environment.node = node # Note that adding ",node" to the list for the other builds causes # Emscripten to generate code which confuses node: it cannot reliably # determine whether the build is for a browser or for node. @@ -658,12 +659,12 @@ emcc.environment.node := node # supported in all configurations (#21071)." # https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md emcc.jsflags += -sALLOW_MEMORY_GROWTH -emcc.INITIAL_MEMORY.128 := 134217728 -emcc.INITIAL_MEMORY.96 := 100663296 -emcc.INITIAL_MEMORY.64 := 67108864 -emcc.INITIAL_MEMORY.32 := 33554432 -emcc.INITIAL_MEMORY.16 := 16777216 -emcc.INITIAL_MEMORY.8 := 8388608 +emcc.INITIAL_MEMORY.128 = 134217728 +emcc.INITIAL_MEMORY.96 = 100663296 +emcc.INITIAL_MEMORY.64 = 67108864 +emcc.INITIAL_MEMORY.32 = 33554432 +emcc.INITIAL_MEMORY.16 = 16777216 +emcc.INITIAL_MEMORY.8 = 8388608 emcc.INITIAL_MEMORY ?= 16 ifeq (,$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))) $(error emcc.INITIAL_MEMORY must be one of: 8, 16, 32, 64, 96, 128 (megabytes)) @@ -696,7 +697,7 @@ emcc.jsflags += -sSTACK_SIZE=512KB # symbols: we cannot "delete" the Emscripten-defined # $(sqlite3.js.init-func) from vanilla builds (as opposed to ESM # builds) because it's declared with "var". -sqlite3.js.init-func := sqlite3InitModule +sqlite3.js.init-func = sqlite3InitModule emcc.jsflags += -sEXPORT_NAME=$(sqlite3.js.init-func) emcc.jsflags += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr. #emcc.jsflags += -sSTRICT # fails due to missing __syscall_...() @@ -786,9 +787,9 @@ $(sqlite3-license-version.js): $(MKDIR.bld) $(sqlite3.h) \ # --post-js injects code which runs after the WASM module is loaded # and includes the entirety of the library plus some # Emscripten-specific post-bootstrapping code. -pre-js.js.in := $(dir.api)/pre-js.c-pp.js -post-js.js.in := $(dir.tmp)/post-js.c-pp.js -post-jses.js := \ +pre-js.js.in = $(dir.api)/pre-js.c-pp.js +post-js.js.in = $(dir.tmp)/post-js.c-pp.js +post-jses.js = \ $(dir.api)/post-js-header.js \ $(sqlite3-api.js.in) \ $(dir.api)/post-js-footer.js @@ -804,10 +805,10 @@ $(post-js.js.in): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE) # Undocumented Emscripten feature: if the target file extension is # "mjs", it defaults to ES6 module builds: # https://github.com/emscripten-core/emscripten/issues/14383 -sqlite3.wasm := $(dir.dout)/sqlite3.wasm -sqlite3-wasm.c := $(dir.api)/sqlite3-wasm.c -sqlite3-wasm.cfiles := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c) -sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles) +sqlite3.wasm = $(dir.dout)/sqlite3.wasm +sqlite3-wasm.c = $(dir.api)/sqlite3-wasm.c +sqlite3-wasm.cfiles = $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c) +sqlite3-wasmfs.cfiles = $(sqlite3-wasm.cfiles) # sqlite3-wasm.o vs sqlite3-wasm.c: building against the latter # (predictably) results in a slightly faster binary. We're close # enough to the target speed requirements that the 500ms makes a @@ -852,9 +853,9 @@ if [ x1 = x$(1) ]; then \ fi endef -sqlite3.js := $(dir.dout)/sqlite3.js -sqlite3.mjs := $(dir.dout)/sqlite3.mjs -EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle +sqlite3.js = $(dir.dout)/sqlite3.js +sqlite3.mjs = $(dir.dout)/sqlite3.mjs +EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle # The various -D... values used by *.c-pp.js include: # @@ -907,7 +908,7 @@ ifneq (1,$(MAKING_CLEAN)) # # Maintenance note: the various $(c-pp.D.XYZ) vars are defined in this # step. -bin.mkwb := ./mkwasmbuilds +bin.mkwb = ./mkwasmbuilds $(bin.mkwb): $(bin.mkwb).c $(MAKEFILE) $(CC) -o $@ $< DISTCLEAN_FILES += $(bin.mkwb) @@ -967,11 +968,11 @@ q: quick ######################################################################## # batch-runner.js is part of one of the test apps which reads in SQL # dumps generated by $(speedtest1) and executes them. -dir.sql := sql -speedtest1 := ../../speedtest1 -speedtest1.c := ../../test/speedtest1.c -speedtest1.sql := $(dir.sql)/speedtest1.sql -speedtest1.cliflags := --size 10 --big-transactions +dir.sql = sql +speedtest1 = ../../speedtest1 +speedtest1.c = ../../test/speedtest1.c +speedtest1.sql = $(dir.sql)/speedtest1.sql +speedtest1.cliflags = --size 10 --big-transactions $(speedtest1): $(MAKE) -C ../.. speedtest1 $(speedtest1.sql): $(speedtest1) $(MAKEFILE) @@ -992,8 +993,8 @@ batch: batch-runner.list # # emcc.speedtest1.common = emcc flags used by multiple builds of speedtest1 # emcc.speedtest1 = emcc flags used by main build of speedtest1 -emcc.speedtest1.common := $(emcc_opt_full) -emcc.speedtest1 := -I. -I$(dir $(sqlite3.canonical.c)) +emcc.speedtest1.common = $(emcc_opt_full) +emcc.speedtest1 = -I. -I$(dir $(sqlite3.canonical.c)) emcc.speedtest1 += -sENVIRONMENT=web emcc.speedtest1 += -sALLOW_MEMORY_GROWTH emcc.speedtest1 += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY)) @@ -1006,7 +1007,7 @@ emcc.speedtest1.common += -Wno-limited-postlink-optimizations emcc.speedtest1.common += -Wno-unused-main # ^^^^ -Wno-unused-main is for emcc 3.1.52+. speedtest1 has a wasm_main() which is # exported and called by the JS code. -EXPORTED_FUNCTIONS.speedtest1 := $(abspath $(dir.tmp)/EXPORTED_FUNCTIONS.speedtest1) +EXPORTED_FUNCTIONS.speedtest1 = $(abspath $(dir.tmp)/EXPORTED_FUNCTIONS.speedtest1) emcc.speedtest1.common += -sSTACK_SIZE=512KB emcc.speedtest1.common += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.speedtest1) emcc.speedtest1.common += $(emcc.exportedRuntimeMethods) @@ -1015,8 +1016,8 @@ emcc.speedtest1.common += -sDYNAMIC_EXECUTION=0 emcc.speedtest1.common += --minify 0 emcc.speedtest1.common += -sEXPORT_NAME=$(sqlite3.js.init-func) emcc.speedtest1.common += -sWASM_BIGINT=$(emcc.WASM_BIGINT) -speedtest1.exit-runtime0 := -sEXIT_RUNTIME=0 -speedtest1.exit-runtime1 := -sEXIT_RUNTIME=1 +speedtest1.exit-runtime0 = -sEXIT_RUNTIME=0 +speedtest1.exit-runtime1 = -sEXIT_RUNTIME=1 # Re -sEXIT_RUNTIME=1 vs 0: if it's 1 and speedtest1 crashes, we get # this error from emscripten: # @@ -1037,10 +1038,10 @@ speedtest1.exit-runtime1 := -sEXIT_RUNTIME=1 $(EXPORTED_FUNCTIONS.speedtest1): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.core) @echo "Making $@ ..." @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ -speedtest1.js := $(dir.dout)/speedtest1.js -speedtest1.wasm := $(dir.dout)/speedtest1.wasm -emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM -speedtest1.cfiles := $(speedtest1.c) $(sqlite3-wasm.c) +speedtest1.js = $(dir.dout)/speedtest1.js +speedtest1.wasm = $(dir.dout)/speedtest1.wasm +emcc.flags.speedtest1-vanilla = $(cflags.common) -DSQLITE_SPEEDTEST1_WASM +speedtest1.cfiles = $(speedtest1.c) $(sqlite3-wasm.c) $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ $(pre-post-speedtest1-vanilla.deps) \ $(EXPORTED_FUNCTIONS.speedtest1) @@ -1098,7 +1099,7 @@ quick: $(sqlite3.js) # painful. .PHONY: o0 o1 o2 o3 os oz -emcc-opt-extra := +emcc-opt-extra = #ifeq (1,$(wasm-bare-bones)) #emcc-opt-extra += -flto # ^^^^ -flto can have a considerably performance boost at -O0 but @@ -1126,7 +1127,7 @@ oz: clean # Sub-makes... # sqlite.org/fiddle application... -include fiddle.make +include $(MAKEFILE.fiddle) # Only add wasmfs if wasmfs.enable=1 or we're running (dist)clean ifneq (,$(filter wasmfs,$(MAKECMDGOALS))) @@ -1144,16 +1145,17 @@ ifeq (1,$(wasmfs.enable)) # little benefit. # ######################################################################## -# Some platforms do not support the WASMFS build. Raspberry Pi OS is one -# of them. As such platforms are discovered, add their (uname -m) name -# to PLATFORMS_WITH_NO_WASMFS to exclude the wasmfs build parts. -PLATFORMS_WITH_NO_WASMFS := aarch64 # add any others here -THIS_ARCH := $(shell /usr/bin/uname -m) +# Some platforms do not support the WASMFS build. Raspberry Pi OS is +# one of them (or was when that comment was initially written). As +# such platforms are discovered, add their (uname -m) name to +# PLATFORMS_WITH_NO_WASMFS to exclude the wasmfs build parts. +PLATFORMS_WITH_NO_WASMFS = aarch64 # add any others here +THIS_ARCH = $(shell /usr/bin/uname -m) ifneq (,$(filter $(THIS_ARCH),$(PLATFORMS_WITH_NO_WASMFS))) $(info This platform does not support the WASMFS build.) -HAVE_WASMFS := 0 +HAVE_WASMFS = 0 else -HAVE_WASMFS := 1 +HAVE_WASMFS = 1 include wasmfs.make endif endif @@ -1191,7 +1193,7 @@ update-docs: echo "Pass wasm.docs.home=/path/to/wasm/docs/checkout or edit this makefile to suit."; \ exit 127 else -wasm.docs.jswasm := $(wasm.docs.home)/jswasm +wasm.docs.jswasm = $(wasm.docs.home)/jswasm update-docs: $(bin.stripccomments) $(sqlite3.js) $(sqlite3.wasm) @echo "Copying files to the /wasm docs. Be sure to use an -Oz build for this!" cp $(sqlite3.wasm) $(wasm.docs.jswasm)/. diff --git a/ext/wasm/config.make.in b/ext/wasm/config.make.in index f30baac3f1..4c8d7893b3 100644 --- a/ext/wasm/config.make.in +++ b/ext/wasm/config.make.in @@ -1,15 +1,16 @@ -# Gets filtered by the configure script +# config.make.in gets filtered by the top-most configure script to +# create config.make. bin.bash = @BIN_BASH@ bin.emcc = @EMCC_WRAPPER@ bin.wasm-strip = @BIN_WASM_STRIP@ bin.wasm-opt = @BIN_WASM_OPT@ -SHELL := $(bin.bash) +SHELL = $(bin.bash) # The following overrides can be uncommented to test various # validation and if/else branches the makefile code: # -#bin.bash := -#bin.emcc := -#bin.wasm-strip := -#bin.wasm-opt := +#bin.bash = +#bin.emcc = +#bin.wasm-strip = +#bin.wasm-opt = diff --git a/ext/wasm/dist.make b/ext/wasm/dist.make index 60699ff5c0..176972fd70 100644 --- a/ext/wasm/dist.make +++ b/ext/wasm/dist.make @@ -11,7 +11,7 @@ # distinctly different zip file and top directory name to distinguish # them from release builds. ####################################################################### -MAKEFILE.dist := $(lastword $(MAKEFILE_LIST)) +MAKEFILE.dist = $(lastword $(MAKEFILE_LIST)) ######################################################################## # Chicken/egg situation: we need $(bin.version-info) to get the @@ -20,16 +20,16 @@ MAKEFILE.dist := $(lastword $(MAKEFILE_LIST)) # have to use a temporary name for the archive until we can get # that binary built. ifeq (1,$(SQLITE_C_IS_SEE)) -dist-name-extra := -see +dist-name-extra = -see else -dist-name-extra := +dist-name-extra = endif ifeq (,$(filter snapshot,$(MAKECMDGOALS))) -dist-name-prefix := sqlite-wasm$(dist-name-extra) +dist-name-prefix = sqlite-wasm$(dist-name-extra) else -dist-name-prefix := sqlite-wasm$(dist-name-extra)-snapshot-$(shell /usr/bin/date +%Y%m%d) +dist-name-prefix = sqlite-wasm$(dist-name-extra)-snapshot-$(shell /usr/bin/date +%Y%m%d) endif -dist-name := $(dist-name-prefix)-TEMP +dist-name = $(dist-name-prefix)-TEMP ######################################################################## # dist.build must be the name of a target which triggers the build of @@ -45,10 +45,10 @@ dist-name := $(dist-name-prefix)-TEMP # reason not to. dist.build ?= oz -dist-dir.top := $(dist-name) -dist-dir.jswasm := $(dist-dir.top)/$(notdir $(dir.dout)) -dist-dir.common := $(dist-dir.top)/common -dist.top.extras := \ +dist-dir.top = $(dist-name) +dist-dir.jswasm = $(dist-dir.top)/$(notdir $(dir.dout)) +dist-dir.common = $(dist-dir.top)/common +dist.top.extras = \ demo-123.html demo-123-worker.html demo-123.js \ tester1.html tester1-worker.html tester1-esm.html \ tester1.js tester1.mjs \ @@ -56,9 +56,9 @@ dist.top.extras := \ demo-worker1.html demo-worker1.js \ demo-worker1-promiser.html demo-worker1-promiser.js \ demo-worker1-promiser-esm.html demo-worker1-promiser.mjs -dist.jswasm.extras := $(sqlite3.wasm) \ +dist.jswasm.extras = $(sqlite3.wasm) \ $(sqlite3-api.ext.jses) -dist.common.extras := \ +dist.common.extras = \ $(wildcard $(dir.common)/*.css) \ $(dir.common)/SqliteTestUtil.js @@ -77,12 +77,12 @@ $(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. -STRIP_K1.js := $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) \ +STRIP_K1.js = $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) \ $(sqlite3-worker1-bundler-friendly.js) \ $(sqlite3-api.ext.jses) # STRIP_K2.js = list of JS files which need to be passed through # $(bin.stripcomments) with two -k flags. -STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \ +STRIP_K2.js = $(sqlite3.js) $(sqlite3.mjs) \ $(sqlite3-bundler-friendly.mjs) $(sqlite3-node.mjs) ######################################################################## # dist: create the end-user deliverable archive. @@ -104,8 +104,8 @@ STRIP_K2.js := $(sqlite3.js) $(sqlite3.mjs) \ # to know that it's in a regex or string literal. Because of that, # comment-stripping is currently disabled, which means the builds will # be significantly larger than before. -#apply_comment_stripper := false -apply_comment_stripper := true +#apply_comment_stripper = false +apply_comment_stripper = true # ^^^ shell command true or false dist: \ $(bin.stripccomments) $(bin.version-info) \ diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index 5b1eb5e778..0cd6b4d367 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -3,13 +3,12 @@ # # Intended to include'd by ./GNUmakefile. ####################################################################### -MAKEFILE.fiddle := $(lastword $(MAKEFILE_LIST)) ######################################################################## # shell.c and its build flags... ifneq (1,$(MAKING_CLEAN)) - make-np-0 := make -C $(dir.top) -n -p - make-np-1 := sed -e 's/(TOP)/(dir.top)/g' + make-np-0 = make -C $(dir.top) -n -p + make-np-1 = sed -e 's/(TOP)/(dir.top)/g' # Extract SHELL_OPT and SHELL_DEP from the top-most makefile and import # them as vars here... $(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1))) @@ -27,7 +26,7 @@ endif # /shell.c ######################################################################## -EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle +EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle fiddle.emcc-flags = \ $(emcc.cflags) $(emcc_opt_full) \ --minify 0 \ @@ -52,12 +51,12 @@ fiddle.emcc-flags = \ # Flags specifically for debug builds of fiddle. Performance suffers # greatly in debug builds. -fiddle.emcc-flags.debug := $(fiddle.emcc-flags) \ +fiddle.emcc-flags.debug = $(fiddle.emcc-flags) \ -DSQLITE_DEBUG \ -DSQLITE_ENABLE_SELECTTRACE \ -DSQLITE_ENABLE_WHERETRACE -fiddle.EXPORTED_FUNCTIONS.in := \ +fiddle.EXPORTED_FUNCTIONS.in = \ EXPORTED_FUNCTIONS.fiddle.in \ $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \ $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras @@ -66,7 +65,7 @@ $(EXPORTED_FUNCTIONS.fiddle): $(MKDIR.bld) $(fiddle.EXPORTED_FUNCTIONS.in) \ $(MAKEFILE.fiddle) sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@ -fiddle.cses := $(dir.top)/shell.c $(sqlite3-wasm.c) +fiddle.cses = $(dir.top)/shell.c $(sqlite3-wasm.c) fiddle: $(fiddle-module.js) $(fiddle-module.js.debug) fiddle.debug: $(fiddle-module.js.debug) @@ -83,10 +82,9 @@ clean-fiddle: all: fiddle ######################################################################## -# fiddle_remote is the remote destination for the fiddle app. It -# must be a [user@]HOST:/path for rsync. -# Note that the target "should probably" contain a symlink of -# index.html -> fiddle.html. +# fiddle_remote is the remote destination for the fiddle app. It must +# be a [user@]HOST:/path for rsync. The target "should probably" +# contain a symlink of index.html -> fiddle.html. fiddle_remote ?= ifeq (,$(fiddle_remote)) ifneq (,$(wildcard /home/stephan)) @@ -153,11 +151,6 @@ push-fiddle: fiddle # because certain execution environments disallow those constructs. # This flag is not strictly necessary, however. # -# -sWASM_BIGINT is UNTESTED but "should" allow the int64-using C APIs -# to work with JS/wasm, insofar as the JS environment supports the -# BigInt type. That support requires an extremely recent browser: -# Safari didn't get that support until late 2020. -# # --no-entry: for compiling library code with no main(). If this is # not supplied and the code has a main(), it is called as part of the # module init process. Note that main() is #if'd out of shell.c @@ -179,14 +172,15 @@ push-fiddle: fiddle # minification makes little difference in terms of overall # distributable size. # -# --minify 0: disables minification of the generated JS code, -# regardless of optimization level. Minification of the JS has -# minimal overall effect in the larger scheme of things and results -# in JS files which can neither be edited nor viewed as text files in -# Fossil (which flags them as binary because of their extreme line -# lengths). Interestingly, whether or not the comments in the -# generated JS file get stripped is unaffected by this setting and -# depends entirely on the optimization level. Higher optimization +# --minify 0: supposedly disables minification of the generated JS +# code, regardless of optimization level, but that's not quite true: +# search the main makefile for wasm-strip for details. Minification +# of the JS has minimal overall effect in the larger scheme of things +# and results in JS files which can neither be edited nor viewed as +# text files in Fossil (which flags them as binary because of their +# extreme line lengths). Interestingly, whether or not the comments +# in the generated JS file get stripped is unaffected by this setting +# and depends entirely on the optimization level. Higher optimization # levels reduce the size of the JS considerably even without # minification. # diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index 6b09c3456c..d70de042e6 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -84,8 +84,8 @@ struct BuildDef { const char *zMode; /* Name from JS_BUILD_MODES */ int flags; /* Flags from LibModeFlags */ const char *zJsOut; /* Name of generated sqlite3.js/.mjs */ - /* TODO: dynamically determine zApiJsOut and zJsOut based on zName, zMode, - and flags. */ + /* TODO: dynamically determine zJsOut based on zName, zMode, and + flags. */ const char *zCmppD; /* Extra -D... flags for c-pp */ const char *zEmcc; /* Extra flags for emcc */ }; @@ -94,7 +94,10 @@ typedef struct BuildDef BuildDef; /* ** The set of WASM builds for the library (as opposed to the apps ** (fiddle, speedtest1)). This array must end with an empty sentinel -** entry, but their order is otherwise not significant. +** entry. Their order is mostly insignificant, but some makefile vars +** used by some builds are set up by prior builds. Because of that, +** the (sqlite3, vanilla), (sqlite3, esm), and (sqlite3, +** bundler-friendly) builds should be defined first (in that order). */ const BuildDef aBuildDefs[] = { {/* Core build */ @@ -136,8 +139,14 @@ static void mk_prologue(void){ /* A 0-terminated list of makefile vars which we expect to have been ** set up by this point in the build process. */ char const * aRequiredVars[] = { + "dir.top", "dir.api", "dir.dout", "dir.tmp", "sqlite3-license-version.js", + "MAKEFILE", "MAKEFILE_LIST", + /* Fiddle... */ + "dir.fiddle", "dir.fiddle-debug", + "MAKEFILE.fiddle", + "EXPORTED_FUNCTIONS.fiddle", /*"just-testing",*/ 0 }; @@ -239,7 +248,6 @@ static void mk_prologue(void){ */ static void mk_pre_post(const char *zName /* build name */, const char *zMode /* build mode */, - int flags /* LIBMODE_... mask */, const char *zCmppD /* optional -D flags for c-pp for the ** --pre/--post-js files. */){ /* Very common printf() args combo. */ @@ -307,13 +315,13 @@ static void mk_pre_post(const char *zName /* build name */, /* ** Emits rules for the fiddle builds. -** */ static void mk_fiddle(void){ int i = 0; - mk_pre_post("fiddle-module","vanilla", 0, 0); + mk_pre_post("fiddle-module","vanilla", 0); for( ; i < 2; ++i ){ + /* 0==normal, 1==debug */ const char *zTail = i ? ".debug" : ""; const char *zDir = i ? "$(dir.fiddle-debug)" : "$(dir.fiddle)"; @@ -366,14 +374,14 @@ static void mk_lib_mode(const BuildDef * pB){ assert( pB->zName ); assert( pB->zMode ); assert( pB->zJsOut ); -#define MT(X) ((X) ? (X) : "") /* Very common printf() args combo. */ #define zNM pB->zName, pB->zMode pf("%s# Begin build [%s-%s]. flags=0x%02x\n", zBanner, zNM, pB->flags); - pf("# zJsOut=%s\n# zCmppD=%s\n", pB->zJsOut, MT(pB->zCmppD)); + pf("# zJsOut=%s\n# zCmppD=%s\n", pB->zJsOut, + pB->zCmppD ? pB->zCmppD : ""); pf("$(info Setting up build [%s-%s]: %s)\n", zNM, pB->zJsOut); - mk_pre_post(zNM, pB->flags, pB->zCmppD); + mk_pre_post(zNM, pB->zCmppD); pf("\nemcc.flags.%s.%s ?=\n", zNM); if( pB->zEmcc && pB->zEmcc[0] ){ pf("emcc.flags.%s.%s += %s\n", zNM, pB->zEmcc); @@ -453,7 +461,6 @@ static void mk_lib_mode(const BuildDef * pB){ pf("all: %s\n", pB->zJsOut); } pf("# End build [%s-%s]%s", zNM, zBanner); -#undef MT #undef zNM } @@ -466,8 +473,8 @@ int main(void){ mk_lib_mode( pB ); } mk_fiddle(); - mk_pre_post("speedtest1","vanilla", 0, 0); - mk_pre_post("speedtest1-wasmfs","esm", 0, + mk_pre_post("speedtest1","vanilla", 0); + mk_pre_post("speedtest1-wasmfs","esm", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs"); return rc; } diff --git a/ext/wasm/speedtest1.html b/ext/wasm/speedtest1.html index 3bad62006f..a841c7fa07 100644 --- a/ext/wasm/speedtest1.html +++ b/ext/wasm/speedtest1.html @@ -23,11 +23,10 @@
Downloading...
- +
This page starts running the main exe when it loads, which will - block the UI until it finishes! Adding UI controls to manually configure and start it - are TODO.
+ block the UI until it finishes!
Achtung: running it with the dev tools open may drastically slow it down. For faster results, keep the dev @@ -118,7 +117,7 @@ argv.push("--vfs", vfs); log2('',"Using VFS:",vfs); if('kvvfs' === vfs){ - forceSize = 2 /* 5 uses approx. 4.96mb */; + forceSize = 2 /* >2 is too big as of mid-2025 */; dbFile = 'session'; log2('warning',"kvvfs VFS: forcing --size",forceSize, "and filename '"+dbFile+"'."); diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make index c4515876fd..19086d4b03 100644 --- a/ext/wasm/wasmfs.make +++ b/ext/wasm/wasmfs.make @@ -22,14 +22,14 @@ sqlite3-wasmfs.wasm = $(dir.wasmfs)/sqlite3-wasmfs.wasm ######################################################################## # emcc flags for .c/.o. -cflags.sqlite3-wasmfs := +cflags.sqlite3-wasmfs = cflags.sqlite3-wasmfs += -std=c99 -fPIC cflags.sqlite3-wasmfs += -pthread cflags.sqlite3-wasmfs += -DSQLITE_ENABLE_WASMFS ######################################################################## # emcc flags specific to building the final .js/.wasm file... -emcc.flags.sqlite3-wasmfs := +emcc.flags.sqlite3-wasmfs = emcc.flags.sqlite3-wasmfs += \ -sEXPORTED_RUNTIME_METHODS=wasmMemory # wasmMemory ==> for -sIMPORTED_MEMORY @@ -53,7 +53,7 @@ emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0 # USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, # see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth] # And, indeed, it runs slowly if memory is permitted to grow. -#emcc.flags.sqlite3-wasmfs.vanilla := +#emcc.flags.sqlite3-wasmfs.vanilla = #emcc.flags.sqlite3-wasmfs.esm = -sEXPORT_ES6 -sUSE_ES6_IMPORT_META $(sqlite3-wasmfs.js) $(dir.wasmfs)/sqlite3-wasmfs.mjs: $(MAKEFILE.wasmfs) ######################################################################## diff --git a/manifest b/manifest index 29b99cbbaf..9bb70c6c2d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C wasm:\sremove\ssome\sextraneous\slevels\sof\smakefile\svar\sand\sfix\sthe\s(unsupported)\swasmfs\sspeedtest1\sbuild\sto\saccount\sfor\svar\srenaming\swhich\shappened\slong\sbefore\sthis. -D 2025-07-16T13:22:38.693 +C In\sthe\swasm\smakefiles,\sreplace\sX:=Y\swith\sX=Y\sbecause\s:=\shas\sdifferent\ssemantics\sdepending\son\sthe\smake\simpl\sand\sits\suse\sis\sarguably\sa\sbad\smuscle-memory\shabit\sworth\sbreaking.\sThese\smakefiles\sare\svery\sspecifically\sfor\sGNU\smake,\sbut\slong-term\sit\swould\sbe\snice\sto\seliminate\sthat\srequirement. +D 2025-07-16T14:51:23.528 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -622,7 +622,7 @@ F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 472720819d2cde9d7d4c957f2bfb8ebb0193fa75dca10a5c2ab0396ba0ef926b +F ext/wasm/GNUmakefile b9217715b615bfe51a8c13f6fa9889fb7b734e0f26bffc656ff52652e9906cc1 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -663,7 +663,7 @@ F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b5318317 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f F ext/wasm/common/whwasmutil.js 5e7fe4a2547831e003356c201ca28d9a0d6a19ab1fe2c8f63f82464fecd2cef7 -F ext/wasm/config.make.in 4bc43443f768a61efd43cf995a5e618f58ac9afc0936706014193537d82c41cb +F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js c7b3cca50c55841c381a9ca4f9396e5bbdc6114273d0b10a43e378e32e7be5bf @@ -673,9 +673,9 @@ F ext/wasm/demo-worker1-promiser.c-pp.html 635cf90685805e21772a5f7a35d1ace80f98a F ext/wasm/demo-worker1-promiser.c-pp.js af168699d3cab1c27ad2364ebe06cd49db300bdbf404e23b00d5742ed52816ba F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js 08720227e98fa5b44761cf6e219269cee3e9dd0421d8d91459535da776950314 -F ext/wasm/dist.make 92ef4ffe33022a50f92d602acabad10bd8dd91759f3eb7df27fc6d7d37072b96 +F ext/wasm/dist.make c29018b4db479a4c170569393e5399f0625446123a7eb6ffb0677495292bb954 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make 2df87f12bcbae2c966c2cef34ce71bb1584c440c69e14ca6d32f443d8d550dc5 +F ext/wasm/fiddle.make 88885c5a2102e1516d0fb89e0cdb023e5b5d73baff9a8ebf97a657f6fb63668b F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js 2a2f27b4be2674f501fff61c4a09e44dcf2295731a26b5c28e439f3a573bd269 F ext/wasm/fiddle/index.html 7fcfb221165183bef0e05d5af9ceb79b527e799b1708ab05de0ec0eaebd5b7bf @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c 5cf96c716367bb5958fd96caa924aca053df8d84081dd46092dd351d1af6ae90 +F ext/wasm/mkwasmbuilds.c f5c143c10aeb7a519f7c08f98f90927f43c1991af3373bc6f80d8631a58acd42 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -691,7 +691,7 @@ F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2 F ext/wasm/speedtest1-wasmfs.mjs c77c7231338ed5c0e1ce16aa29106df8e5b5cf11a48319c49433490a8d3ded30 F ext/wasm/speedtest1-worker.html d24d1e06caf3dcd83430c8c3d87761ff7555fd06eaeaf2fc02ce49cf45f0d032 F ext/wasm/speedtest1-worker.js 95e549e13a4d35863a9a7fc66122b5f546c0130d3be7b06dfcc556eb66d24bde -F ext/wasm/speedtest1.html 217bf15d43065634a27a06dbd5c9a320f6da9932dbcdfc963d482bc2f99dbea9 +F ext/wasm/speedtest1.html e2a0e0bd12243ca34b11235bf9f3c229f4574ea1125f2ecf2bf0589853d6f9c8 F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5 @@ -708,7 +708,7 @@ F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328 F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 -F ext/wasm/wasmfs.make 4f6a679c06b45039a4b0456a546e95c4f24bf6d33455073bb055cc17b6739550 +F ext/wasm/wasmfs.make d9da19b6b4b438a7d4b932093820882532802eb929f4320e8f032a2b722fcd67 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk a5d698cf8d38e4eb42a89f08a9521906b24f4acac61bbafa56d72cd9b39617b6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a8ed16989dcd324bd9caa09aec7979249deaf59ca13bc377379ddd83c53379cd -R 9ff9d7c107dd129efe8469b678cd73d7 +P 35b2315343e22ca12c6ee3f5be8741eba889bb6461e08fad0a8ae7db033319cb +R 1b41f3a033df88a8072a18a3668f851c U stephan -Z 9b2f15ac0469aa2bbb0879fb5bc3ce42 +Z af3ba49056e2f127c99be56e513ada3c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b205abb7eb..662d4849d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35b2315343e22ca12c6ee3f5be8741eba889bb6461e08fad0a8ae7db033319cb +d4203311a2f39189ed8f30d519468aed8983af7772a5b247e7557d3e1936064e From 10687e283a4071a66dbb8dd22037965e3a22fe17 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 16:56:33 +0000 Subject: [PATCH 86/88] Remove some stray makefile debug output. FossilOrigin-Name: 7ef22c3d11088210d2267375ec188bd352b067614200394b9877f2e40dc12bb2 --- ext/wasm/wasmfs.make | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make index 19086d4b03..712418fa4e 100644 --- a/ext/wasm/wasmfs.make +++ b/ext/wasm/wasmfs.make @@ -86,7 +86,7 @@ emcc.flags.speedtest1-wasmfs = $(sqlite3-wasmfs.fsflags) emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT) emcc.flags.speedtest1-wasmfs += -sALLOW_MEMORY_GROWTH=0 emcc.flags.speedtest1-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) -$(info speedtest DEPS=pre-post-sqlite3-wasmfs-esm.deps=$(pre-post-sqlite3-wasmfs-esm.deps)) +#$(info speedtest DEPS=pre-post-sqlite3-wasmfs-esm.deps=$(pre-post-sqlite3-wasmfs-esm.deps)) $(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \ $(MAKEFILE) $(MAKEFILE.wasmfs) $(pre-post-sqlite3-wasmfs-esm.deps) \ $(EXPORTED_FUNCTIONS.speedtest1) diff --git a/manifest b/manifest index 9bb70c6c2d..5485ecf3fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\swasm\smakefiles,\sreplace\sX:=Y\swith\sX=Y\sbecause\s:=\shas\sdifferent\ssemantics\sdepending\son\sthe\smake\simpl\sand\sits\suse\sis\sarguably\sa\sbad\smuscle-memory\shabit\sworth\sbreaking.\sThese\smakefiles\sare\svery\sspecifically\sfor\sGNU\smake,\sbut\slong-term\sit\swould\sbe\snice\sto\seliminate\sthat\srequirement. -D 2025-07-16T14:51:23.528 +C Remove\ssome\sstray\smakefile\sdebug\soutput. +D 2025-07-16T16:56:33.482 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -708,7 +708,7 @@ F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328 F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 -F ext/wasm/wasmfs.make d9da19b6b4b438a7d4b932093820882532802eb929f4320e8f032a2b722fcd67 +F ext/wasm/wasmfs.make bde552956ae47f21c3eb1bb727e5fd416a6df19758f96b77ba72b20612359b8a F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk a5d698cf8d38e4eb42a89f08a9521906b24f4acac61bbafa56d72cd9b39617b6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 35b2315343e22ca12c6ee3f5be8741eba889bb6461e08fad0a8ae7db033319cb -R 1b41f3a033df88a8072a18a3668f851c +P d4203311a2f39189ed8f30d519468aed8983af7772a5b247e7557d3e1936064e +R ba4aacc796c389ef7dfc5c4dcd68fec3 U stephan -Z af3ba49056e2f127c99be56e513ada3c +Z 4b13663095b96ba0896611543740e3b6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 662d4849d0..3d8ab5ceef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4203311a2f39189ed8f30d519468aed8983af7772a5b247e7557d3e1936064e +7ef22c3d11088210d2267375ec188bd352b067614200394b9877f2e40dc12bb2 From 91db1c413b6d066db0a401f9cc2092483f86e56d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Jul 2025 17:24:31 +0000 Subject: [PATCH 87/88] Fix vtabH.test so that it works on windows even if there are files that begin with "$" in the root directory. FossilOrigin-Name: 19a79219a7d52272102ff09d19e6b9b87e88e0070592fd7e6040bd8ce66ad238 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/vtabH.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5485ecf3fa..2ebf685952 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sstray\smakefile\sdebug\soutput. -D 2025-07-16T16:56:33.482 +C Fix\svtabH.test\sso\sthat\sit\sworks\son\swindows\seven\sif\sthere\sare\sfiles\sthat\sbegin\swith\s"$"\sin\sthe\sroot\sdirectory. +D 2025-07-16T17:24:31.516 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1994,7 +1994,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test a9417d92111629e2c33e0f3b06cc84bcd611753d0fc017b3ce6ae96572bc2f2f +F test/vtabH.test 3fe4c1cbc93a85971990f379116255e2d4f14b583be4d0b9cca67e90226041f1 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtabJ.test a6aef49d558af90fae10565b29501f82a95781cb4f797f2d13e2d19f9b6bc77b F test/vtabK.test 13293177528fada1235c0112db0d187d754af1355c5a39371abd365104e3afbf @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d4203311a2f39189ed8f30d519468aed8983af7772a5b247e7557d3e1936064e -R ba4aacc796c389ef7dfc5c4dcd68fec3 -U stephan -Z 4b13663095b96ba0896611543740e3b6 +P 7ef22c3d11088210d2267375ec188bd352b067614200394b9877f2e40dc12bb2 +R 3ef038ae9187f207008c5c09bc7a42a8 +U dan +Z 562bf6bcb2e06809b99eb8ab4d03b298 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3d8ab5ceef..a03432876b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ef22c3d11088210d2267375ec188bd352b067614200394b9877f2e40dc12bb2 +19a79219a7d52272102ff09d19e6b9b87e88e0070592fd7e6040bd8ce66ad238 diff --git a/test/vtabH.test b/test/vtabH.test index 07704cefb1..1496f49b53 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -190,10 +190,10 @@ if {$tcl_platform(platform) ne "windows" || \ lappend res "/$p" } } - set num_root_files [llength $root_files] + set num_root_files [llength $res] do_test 3.1 { sort_files [execsql { - SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $num_root_files; + SELECT path FROM fstree WHERE path NOT GLOB '*$*' LIMIT $num_root_files }] true } [sort_files $res true] From cf05295a8538479e06713fca0c037e27eef44105 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Jul 2025 20:50:40 +0000 Subject: [PATCH 88/88] Diverse wasm build cleanups. FossilOrigin-Name: 14ca18f72a7edde7c65a6c6b23fdc3f5ed6860371795926045c987f7b2c75e1b --- ext/wasm/GNUmakefile | 38 ++++++++++++++------- ext/wasm/fiddle.make | 3 -- ext/wasm/mkwasmbuilds.c | 74 +++++++++++++++++++---------------------- ext/wasm/wasmfs.make | 5 +-- manifest | 20 +++++------ manifest.uuid | 2 +- 6 files changed, 73 insertions(+), 69 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 87c2ca2fcb..5cd0aa66a6 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -457,6 +457,21 @@ else emcc_opt ?= -Oz endif +# Our JS code installs bindings of each sqlite3_...() WASM export. The +# generated Emscripten JS file does the same using its own framework, +# but we don't use those results and can speed up lib init, and reduce +# memory cost a bit, by stripping them out. Emscripten-side changes +# can "break" this, causing this to be a no-op, but the worst that can +# happen in that case is that it doesn't actually strip anything, +# leading to slightly larger JS files. +# +# This snippet is intended to be used in makefile targets which +# generate an Emscripten module and where $@ is the module's .js/.mjs +# file. +SQLITE.strip-createExportWrapper = \ + sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]* = createExportWrapper/d' $@ || exit; \ + echo '(Probably) stripped out extraneous createExportWrapper() parts.' + # When passing emcc_opt from the CLI, += and re-assignment have no # effect, so emcc_opt+=-g3 doesn't work. So... emcc_opt_full = $(emcc_opt) -g3 @@ -598,7 +613,7 @@ emcc.cflags = emcc.cflags += -std=c99 -fPIC # -------------^^^^^^^^ we need c99 for $(sqlite3-wasm.c), primarily # for variadic macros and snprintf() to implement -# sqlite3_wasm_enum_json(). +# sqlite3__wasm_enum_json(). emcc.cflags += -I. -I$(dir.top) ######################################################################## # emcc flags specific to building .js/.wasm files... @@ -943,23 +958,24 @@ $(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1-promiser.c-pp.j $(eval $(call SQLITE.CALL.C-PP.FILTER,$(dir.api)/sqlite3-worker1-promiser.c-pp.js,\ $(dir.dout)/sqlite3-worker1-promiser.mjs,\ -Dtarget=es6-module -Dtarget=es6-bundler-friendly)) -$(dir.dout)/sqlite3-bundler-friendly.mjs: $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs \ - $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.js)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.mjs,\ -Dtarget=es6-module)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser.html)) $(eval $(call SQLITE.CALL.C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser-esm.html,\ -Dtarget=es6-module)) -all: $(dir.dout)/sqlite3-worker1.js \ - $(dir.dout)/sqlite3-worker1-promiser.js $(dir.dout)/sqlite3-worker1-promiser.mjs + +$(dir.dout)/sqlite3-bundler-friendly.mjs: \ + $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs \ + $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js demo-worker1-promiser.html: $(dir.dout)/sqlite3-worker1-promiser.js demo-worker1-promiser.js demo-worker1-promiser-esm.html: $(sqlite3-worker1-promiser.mjs) demo-worker1-promiser.mjs all: demo-worker1-promiser.html demo-worker1-promiser-esm.html sqlite3-api.ext.jses += \ - $(sqlite3-worker1-promiser.mjs) \ + $(dir.dout)/sqlite3-worker1-promiser.mjs \ + $(dir.dout)/sqlite3-worker1-promiser.js \ $(dir.dout)/sqlite3-worker1-bundler-friendly.mjs \ $(dir.dout)/sqlite3-worker1.js all quick: $(sqlite3-api.ext.jses) @@ -1039,7 +1055,6 @@ $(EXPORTED_FUNCTIONS.speedtest1): $(MKDIR.bld) $(EXPORTED_FUNCTIONS.api.core) @echo "Making $@ ..." @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ speedtest1.js = $(dir.dout)/speedtest1.js -speedtest1.wasm = $(dir.dout)/speedtest1.wasm emcc.flags.speedtest1-vanilla = $(cflags.common) -DSQLITE_SPEEDTEST1_WASM speedtest1.cfiles = $(speedtest1.c) $(sqlite3-wasm.c) $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ @@ -1055,14 +1070,13 @@ $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \ $(speedtest1.exit-runtime0) \ -o $@ $(speedtest1.cfiles) -lm - $(maybe-wasm-strip) $(speedtest1.wasm) - sed -i -e '/^var _sqlite3.*createExportWrapper/d' $@ - chmod -x $(speedtest1.wasm) - ls -la $@ $(speedtest1.wasm) + @chmod -x $(basename $@).wasm + @$(maybe-wasm-strip) $(basename $@).wasm + @$(SQLITE.strip-createExportWrapper) + @ls -la $@ $(speedtest1.wasm) speedtest1: $(speedtest1.js) all: speedtest1 -#CLEAN_FILES += $(speedtest1.js) $(speedtest1.wasm) # end speedtest1.js ######################################################################## diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index 0cd6b4d367..6bdf441959 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -67,9 +67,6 @@ $(EXPORTED_FUNCTIONS.fiddle): $(MKDIR.bld) $(fiddle.EXPORTED_FUNCTIONS.in) \ fiddle.cses = $(dir.top)/shell.c $(sqlite3-wasm.c) -fiddle: $(fiddle-module.js) $(fiddle-module.js.debug) -fiddle.debug: $(fiddle-module.js.debug) - clean: clean-fiddle clean-fiddle: rm -f $(dir.fiddle)/fiddle-module.js \ diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index d70de042e6..d33a10c016 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -59,14 +59,14 @@ static const char * zBanner = ** to breakage in some of the flag checks. */ enum LibModeFlags { - /* Sentinel value */ - LIBMODE_PLAIN = 0, /* Indicates an ESM module build. */ LIBMODE_ESM = 0x01, /* Indicates a "bundler-friendly" build mode. */ LIBMODE_BUNDLER_FRIENDLY = 0x02, - /* Indicates to _not_ add this build to the 'all' target. */ - LIBMODE_DONT_ADD_TO_ALL = 0x04, + /* Indicates that this build is unsupported. Such builds are not + ** added to the 'all' target. The unsupported builds exist primarily + ** for experimentation's sake. */ + LIBMODE_UNSUPPORTED = 0x04, /* Indicates a node.js-for-node.js build (untested and ** unsupported). */ LIBMODE_NODEJS = 0x08, @@ -101,29 +101,30 @@ typedef struct BuildDef BuildDef; */ const BuildDef aBuildDefs[] = { {/* Core build */ - "sqlite3", "vanilla", LIBMODE_PLAIN, "$(sqlite3.js)", 0, 0}, + "sqlite3", "vanilla", 0, "$(sqlite3.js)", 0, 0}, {/* Core ESM */ "sqlite3", "esm", LIBMODE_ESM, "$(sqlite3.mjs)", "-Dtarget=es6-module", 0}, - {/* Core bundler-friend. Untested and "not really" supported, but - ** required by the downstream npm subproject. */ + {/* Core bundler-friendly build. Untested and "not really" + ** supported, but required by the downstream npm subproject. + ** Testing these would require special-purpose node-based tools and + ** custom test apps. Or we can pass them off as-is to the npm + ** subproject and they spot failures pretty quickly ;). */ "sqlite3", "bundler-friendly", LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM, "$(dir.dout)/sqlite3-bundler-friendly.mjs", "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0}, {/* node.js mode. Untested and unsupported. */ - "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL, + "sqlite3", "node", LIBMODE_UNSUPPORTED | LIBMODE_NODEJS, "$(dir.dout)/sqlite3-node.mjs", "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0}, - {/* The wasmfs build is optional, untested, unsupported, and - ** needs to be invoked conditionally using info we don't have - ** here. */ + {/* Wasmfs build. Fully unsupported and largely untested. */ "sqlite3-wasmfs", "esm" , - LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL, + LIBMODE_UNSUPPORTED | LIBMODE_WASMFS | LIBMODE_ESM, "$(dir.wasmfs)/sqlite3-wasmfs.mjs", "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs", "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"}, @@ -327,8 +328,6 @@ static void mk_fiddle(void){ pf("%s# Begin fiddle%s\n", zBanner, zTail); pf("fiddle-module.js%s = %s/fiddle-module.js\n", zTail, zDir); - pf("fiddle-module.wasm%s = " - "$(subst .js,.wasm,$(fiddle-module.js%s))\n", zTail, zTail); pf("$(fiddle-module.js%s):%s $(MAKEFILE_LIST) $(MAKEFILE.fiddle) " "$(EXPORTED_FUNCTIONS.fiddle) " "$(fiddle.cses) $(pre-post-fiddle-module-vanilla.deps) " @@ -340,7 +339,9 @@ static void mk_fiddle(void){ pf("\t$(bin.emcc) -o $@ $(fiddle.emcc-flags%s) " "$(pre-post-fiddle-module-vanilla.flags) $(fiddle.cses)\n", zTail); - pf("\t$(maybe-wasm-strip) $(fiddle-module.wasm%s)\n", zTail); + ps("\t@chmod -x $(basename $@).wasm"); + ps("\t@$(maybe-wasm-strip) $(basename $@).wasm"); + ps("\t@$(SQLITE.strip-createExportWrapper)"); pf("\t@cp -p $(SOAP.js) $(dir $@)\n"); if( 1==i ){/*fiddle.debug*/ pf("\tcp -p $(dir.fiddle)/index.html " @@ -349,13 +350,13 @@ static void mk_fiddle(void){ "$(dir $@)\n"); } pf("\t@for i in %s/*.*js %s/*.html %s/*.wasm; do \\\n" - "\t\ttest -f $${i} || continue; \\\n" + "\t\ttest -f $${i} || continue; \\\n" "\t\tgzip < $${i} > $${i}.gz; \\\n" "\tdone\n", zDir, zDir, zDir); if( 0==i ){ ps("fiddle: $(fiddle-module.js)"); }else{ - ps("fiddle-debug: $(fiddle-module-debug.js)"); + ps("fiddle-debug: $(fiddle-module.js.debug)"); } pf("# End fiddle%s%s", zTail, zBanner); } @@ -392,13 +393,17 @@ static void mk_lib_mode(const BuildDef * pB){ "$(pre-post-%s-%s.deps) " "$(sqlite3-api.ext.jses)" /* ^^^ maintenance reminder: we set these as deps so that they - get copied into place early. That allows the developer to - reload the base-most test pages while the later-stage builds - are still compiling, which is especially helpful when running - builds with long build times (like -Oz). */ + ** get copied into place early. That allows the developer to + ** reload the base-most test pages while the later-stage builds + ** are still compiling, which is especially helpful when running + ** builds with long build times (like -Oz). */ "\n", pB->zJsOut, zNM); pf("\t@echo \"Building $@ ...\"\n"); + if( LIBMODE_UNSUPPORTED & pB->flags ){ + ps("\t@echo 'ACHTUNG: $@ is an unsupported build. " + "Use at your own risk.'"); + } pf("\t$(bin.emcc) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n"); pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", pB->zMode); @@ -415,28 +420,19 @@ static void mk_lib_mode(const BuildDef * pB){ pf("\t@$(call SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT,1,%d)\n", (LIBMODE_WASMFS & pB->flags) ? 1 : 0); } - pf("\t@chmod -x %s; \\\n" - "\t\t$(maybe-wasm-strip) %s;\n", - zWasmOut, zWasmOut); + pf("\t@chmod -x %s\n", zWasmOut); + pf("\t@$(maybe-wasm-strip) %s\n", zWasmOut); pf("\t@$(call SQLITE.CALL.WASM-OPT,%s)\n", zWasmOut); - pf("\t@sed -i -e '/^.*= *_sqlite.*= *createExportWrapper/d' %s || exit; \\\n" - /* ^^^^^^ reminder: Mac/BSD sed has no -i flag */ - "\t\techo 'Stripped out createExportWrapper() parts.'\n", - pB->zJsOut) /* Our JS code installs bindings of each WASM export. The - generated Emscripten JS file does the same using its - own framework, but we don't use those results and can - speed up lib init, and reduce memory cost - considerably, by stripping them out. */; + ps("\t@$(SQLITE.strip-createExportWrapper)"); /* - ** The above $(bin.emcc) call will write zJsOut and will create a - ** like-named .wasm file (zWasmOut). That .wasm file name gets - ** hard-coded into zJsOut so we need to, for some cases, patch - ** zJsOut to use the name sqlite3.wasm instead. Note that the + ** The above $(bin.emcc) call will write pB->zJsOut, a.k.a. $@, and + ** will create a like-named .wasm file (zWasmOut). That .wasm file + ** name gets hard-coded into $@ so we need to, for some cases, patch + ** zJsOut to use the name sqlite3.wasm instead. Note that the ** resulting .wasm file is identical for all builds for which zEmcc ** is empty. */ - if( (LIBMODE_BUNDLER_FRIENDLY & pB->flags) - || (LIBMODE_NODEJS & pB->flags) ){ + if( (LIBMODE_BUNDLER_FRIENDLY & pB->flags) ){ pf("\t@echo 'Patching $@ for %s.wasm...'; \\\n", pB->zName); pf("\t\trm -f %s; \\\n", zWasmOut); pf("\t\tsed -i -e 's/%s-%s.wasm/%s.wasm/g' $@ || exit;\n", @@ -457,7 +453,7 @@ static void mk_lib_mode(const BuildDef * pB){ }else{ pf("\t@ls -la %s $@\n", zWasmOut); } - if( 0==(LIBMODE_DONT_ADD_TO_ALL & pB->flags) ){ + if( 0==(LIBMODE_UNSUPPORTED & pB->flags) ){ pf("all: %s\n", pB->zJsOut); } pf("# End build [%s-%s]%s", zNM, zBanner); diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make index 712418fa4e..0d1fb4043a 100644 --- a/ext/wasm/wasmfs.make +++ b/ext/wasm/wasmfs.make @@ -10,10 +10,7 @@ MAKEFILE.wasmfs = $(lastword $(MAKEFILE_LIST)) # $(warning) alignment! ifneq (1,$(MAKING_CLEAN)) $(warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) - $(warning !! The WASMFS build is not well-supported. WASMFS is a proverbial) - $(warning !! moving target, sometimes changing in incompatible ways between) - $(warning !! Emscripten versions. This build is provided for adventurous folks) - $(warning !! and is not a supported deliverable of the SQLite project.) + $(warning !! The WASMFS build is unsupported. Use at your own risk. $(warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) endif diff --git a/manifest b/manifest index 2ebf685952..994611c2c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\svtabH.test\sso\sthat\sit\sworks\son\swindows\seven\sif\sthere\sare\sfiles\sthat\sbegin\swith\s"$"\sin\sthe\sroot\sdirectory. -D 2025-07-16T17:24:31.516 +C Diverse\swasm\sbuild\scleanups. +D 2025-07-16T20:50:40.841 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -622,7 +622,7 @@ F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7 F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile b9217715b615bfe51a8c13f6fa9889fb7b734e0f26bffc656ff52652e9906cc1 +F ext/wasm/GNUmakefile 35e730a01b32481f5483ea5bd72c3d4609e25f34cb5aab9f85eb3eba6f0c4935 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -675,7 +675,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 08720227e98fa5b44761cf6e219269cee3e9dd0421d8d91459535da776950314 F ext/wasm/dist.make c29018b4db479a4c170569393e5399f0625446123a7eb6ffb0677495292bb954 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make 88885c5a2102e1516d0fb89e0cdb023e5b5d73baff9a8ebf97a657f6fb63668b +F ext/wasm/fiddle.make ea505d11aa2a89551e1693ed4c71ee6a163364ca14f806dda295d0beb26ec0ea F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js 2a2f27b4be2674f501fff61c4a09e44dcf2295731a26b5c28e439f3a573bd269 F ext/wasm/fiddle/index.html 7fcfb221165183bef0e05d5af9ceb79b527e799b1708ab05de0ec0eaebd5b7bf @@ -683,7 +683,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1 F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf -F ext/wasm/mkwasmbuilds.c f5c143c10aeb7a519f7c08f98f90927f43c1991af3373bc6f80d8631a58acd42 +F ext/wasm/mkwasmbuilds.c cc66cfaf8673ece3c30ca7fe28f6111481090648098a143ea619a8820b8fbe82 F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -708,7 +708,7 @@ F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328 F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 -F ext/wasm/wasmfs.make bde552956ae47f21c3eb1bb727e5fd416a6df19758f96b77ba72b20612359b8a +F ext/wasm/wasmfs.make 411dd94b40406572caddf88392a1ccc4deed0f88d260516e59ca6e0c887ee861 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk a5d698cf8d38e4eb42a89f08a9521906b24f4acac61bbafa56d72cd9b39617b6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7ef22c3d11088210d2267375ec188bd352b067614200394b9877f2e40dc12bb2 -R 3ef038ae9187f207008c5c09bc7a42a8 -U dan -Z 562bf6bcb2e06809b99eb8ab4d03b298 +P 19a79219a7d52272102ff09d19e6b9b87e88e0070592fd7e6040bd8ce66ad238 +R 30226b4a55673400a1aa3c71febc4b89 +U stephan +Z 7a7ad60cbd528275276e18c6ff4c005a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a03432876b..f1c904a3d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19a79219a7d52272102ff09d19e6b9b87e88e0070592fd7e6040bd8ce66ad238 +14ca18f72a7edde7c65a6c6b23fdc3f5ed6860371795926045c987f7b2c75e1b