]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the WhereClause object, do not assume that all TERM_VIRTUAL terms appear
authordrh <>
Wed, 8 Dec 2021 16:07:22 +0000 (16:07 +0000)
committerdrh <>
Wed, 8 Dec 2021 16:07:22 +0000 (16:07 +0000)
at the end of the list, because that is no longer true.  Instead, keep a
separate nBase count that is the size of the list excluding the tail of
virtual terms.  Use nBase instead of nTerm when scanning terms that are not
virtual.  Add assert()s to validate correctness of WhereClause.

FossilOrigin-Name: 6024682ca467fa4fe49608772b0bbfa2f8a419b32cebfa715941073c8b29da49

manifest
manifest.uuid
src/where.c
src/whereInt.h
src/wherecode.c
src/whereexpr.c

index bd016deb39aba820d97368e1ec8fab74aa2392b9..d59214aeb8198bc17b190f3ea9de1efe85d5f2b1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sOOB\sread\sthat\scould\soccur\sin\sfts5\swhen\sprocessing\scorrupt\srecords.
-D 2021-12-06T18:57:02.055
+C In\sthe\sWhereClause\sobject,\sdo\snot\sassume\sthat\sall\sTERM_VIRTUAL\sterms\sappear\nat\sthe\send\sof\sthe\slist,\sbecause\sthat\sis\sno\slonger\strue.\s\sInstead,\skeep\sa\nseparate\snBase\scount\sthat\sis\sthe\ssize\sof\sthe\slist\sexcluding\sthe\stail\sof\nvirtual\sterms.\s\sUse\snBase\sinstead\sof\snTerm\swhen\sscanning\sterms\sthat\sare\snot\nvirtual.\s\sAdd\sassert()s\sto\svalidate\scorrectness\sof\sWhereClause.
+D 2021-12-08T16:07:22.778
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -638,10 +638,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c ed0398a7adf02c31e34aada42cc86c58f413a7afe5f741a5d373ad087abde028
 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
 F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
-F src/where.c 5bd26902ddf3e385c0df9429b10e7358bbd0430c470ec1d2a53065723c4a55d2
-F src/whereInt.h 1630d9418512b080598e9a72b8af6b8bd1b9ab13fee1458f151762b6df206791
-F src/wherecode.c 1f5b62f46d284c8886945eb7438415bc27e23e87bb60b9ee468fa6bd31268f33
-F src/whereexpr.c 19394cb463003e9cc9305730b1508b8817a22bb7247170d81234b691a7f05b89
+F src/where.c 6e07a2ebfccedec1926f9cd13f773741002a56c40dd90adc3ea25e41354db46f
+F src/whereInt.h 14ebb040acac47091a4dd3075f4ab511cad7fc31010fc5e6a750e06b7950c021
+F src/wherecode.c 280f1f87311827f8921a815dbb9b8e84bb394556716fa6a2e111c855b299de20
+F src/whereexpr.c 791544603b254cf11f8e84e3b50b0863c57322e9f213b828680f658e232ebc57
 F src/window.c 5d3b397b0c026d0ff5890244ac41359e524c01ae31e78782e1ff418c3e271a9e
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
@@ -1934,7 +1934,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 8fd5b8ec4ab9b5554d27f25a4638d56e347eab78b60900f24b15a815d3731330
-R c3401645c738abc52212977ced7d66bd
-U dan
-Z bbca536d76f68538aaa5d06c505e1b60
+P bb9b1a15f7e80483162049dfd981d059dc69d03348b521f7ac164a8cd3ae3cc4
+R 2e19e97323a5794a031526354d3fd247
+U drh
+Z 8c650a14815db39748cc380bbb1958b3
index 85e543009ee1cb812b9209d003d310a832b0148a..4c34bfe6541b5b838d49c5f41d11e8527db2289e 100644 (file)
@@ -1 +1 @@
-bb9b1a15f7e80483162049dfd981d059dc69d03348b521f7ac164a8cd3ae3cc4
\ No newline at end of file
+6024682ca467fa4fe49608772b0bbfa2f8a419b32cebfa715941073c8b29da49
\ No newline at end of file
index f1abd5483c3c4587797c5fef37c912b3a40d50a2..649b786520efb10c00c86d84fb3d8ef901cfaa71 100644 (file)
@@ -2361,11 +2361,11 @@ static void whereLoopOutputAdjust(
   LogEst iReduce = 0;    /* pLoop->nOut should not exceed nRow-iReduce */
 
   assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
-  for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
+  for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){
     assert( pTerm!=0 );
-    if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
-    if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
     if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
+    if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
+    if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue;
     for(j=pLoop->nLTerm-1; j>=0; j--){
       pX = pLoop->aLTerm[j];
       if( pX==0 ) continue;
@@ -3636,6 +3636,7 @@ static int whereLoopAddOr(
           tempWC.pOuter = pWC;
           tempWC.op = TK_AND;
           tempWC.nTerm = 1;
+          tempWC.nBase = 1;
           tempWC.a = pOrTerm;
           sSubBuild.pWC = &tempWC;
         }else{
@@ -5085,7 +5086,7 @@ WhereInfo *sqlite3WhereBegin(
   **   FROM ... WHERE random()>0;           -- eval random() once per row
   **   FROM ... WHERE (SELECT random())>0;  -- eval random() once overall
   */
-  for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+  for(ii=0; ii<sWLB.pWC->nBase; ii++){
     WhereTerm *pT = &sWLB.pWC->a[ii];
     if( pT->wtFlags & TERM_VIRTUAL ) continue;
     if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
index 217dd0ba2a1472777d0a3748506995af17a62827..0df84ad6c04a61d5c45b813e2c3f7d271e9a3504 100644 (file)
@@ -320,6 +320,7 @@ struct WhereClause {
   u8 hasOr;                /* True if any a[].eOperator is WO_OR */
   int nTerm;               /* Number of terms */
   int nSlot;               /* Number of entries in a[] */
+  int nBase;               /* Number of terms through the last non-Virtual */
   WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
 #if defined(SQLITE_SMALL_STACK)
   WhereTerm aStatic[1];    /* Initial static space for a[] */
index 460ac4fe30a123f325bc667a1734e22f00e19399..a6633967a2cc909d6b0a403e9b67eaa245b45235 100644 (file)
@@ -970,7 +970,7 @@ static void codeCursorHint(
   sWalker.pParse = pParse;
   sWalker.u.pCCurHint = &sHint;
   pWC = &pWInfo->sWC;
-  for(i=0; i<pWC->nTerm; i++){
+  for(i=0; i<pWC->nBase; i++){
     pTerm = &pWC->a[i];
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
     if( pTerm->prereqAll & pLevel->notReady ) continue;
@@ -2467,7 +2467,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
   ** then we cannot use the "t1.a=t2.b" constraint, but we can code
   ** the implied "t1.a=123" constraint.
   */
-  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+  for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){
     Expr *pE, sEAlt;
     WhereTerm *pAlt;
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
@@ -2512,7 +2512,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
     pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
     sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
     VdbeComment((v, "record LEFT JOIN hit"));
-    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
+    for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
       testcase( pTerm->wtFlags & TERM_VIRTUAL );
       testcase( pTerm->wtFlags & TERM_CODED );
       if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
index eff7f4ab22b1528e7bb06c79c759753c10978cd4..5a3fbe2d7fc490af42643c6ab80c7315c8af492c 100644 (file)
@@ -79,6 +79,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
     pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
   }
   pTerm = &pWC->a[idx = pWC->nTerm++];
+  if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
   if( p && ExprHasProperty(p, EP_Unlikely) ){
     pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
   }else{
@@ -1532,6 +1533,7 @@ void sqlite3WhereClauseInit(
   pWC->hasOr = 0;
   pWC->pOuter = 0;
   pWC->nTerm = 0;
+  pWC->nBase = 0;
   pWC->nSlot = ArraySize(pWC->aStatic);
   pWC->a = pWC->aStatic;
 }
@@ -1543,9 +1545,17 @@ void sqlite3WhereClauseInit(
 */
 void sqlite3WhereClauseClear(WhereClause *pWC){
   sqlite3 *db = pWC->pWInfo->pParse->db;
+  assert( pWC->nTerm>=pWC->nBase );
   if( pWC->nTerm>0 ){
     WhereTerm *a = pWC->a;
     WhereTerm *aLast = &pWC->a[pWC->nTerm-1];
+#ifdef SQLITE_DEBUG
+    int i;
+    /* Verify that every term past pWC->nBase is virtual */
+    for(i=pWC->nBase; i<pWC->nTerm; i++){
+      assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
+    }
+#endif
     while(1){
       if( a->wtFlags & TERM_DYNAMIC ){
         sqlite3ExprDelete(db, a->pExpr);