From ba56f7020d5829aa9b4b9a7556ca23785fa771f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Jun 2025 20:19:19 +0000 Subject: [PATCH 01/13] 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 02/13] 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 03/13] 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 04/13] 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 05/13] 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 06/13] 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 07/13] 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 08/13] 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 bfb4993364a2f20929ae306156d0030269ca5cb4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Jul 2025 11:52:17 +0000 Subject: [PATCH 09/13] 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 10/13] 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 11/13] 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 12/13] 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 13/13] 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