diff --git a/manifest b/manifest index bd016deb39..d59214aeb8 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 85e543009e..4c34bfe654 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb9b1a15f7e80483162049dfd981d059dc69d03348b521f7ac164a8cd3ae3cc4 \ No newline at end of file +6024682ca467fa4fe49608772b0bbfa2f8a419b32cebfa715941073c8b29da49 \ No newline at end of file diff --git a/src/where.c b/src/where.c index f1abd5483c..649b786520 100644 --- a/src/where.c +++ b/src/where.c @@ -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; iinTerm; ii++){ + for(ii=0; iinBase; ii++){ WhereTerm *pT = &sWLB.pWC->a[ii]; if( pT->wtFlags & TERM_VIRTUAL ) continue; if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ diff --git a/src/whereInt.h b/src/whereInt.h index 217dd0ba2a..0df84ad6c0 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -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[] */ diff --git a/src/wherecode.c b/src/wherecode.c index 460ac4fe30..a6633967a2 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -970,7 +970,7 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; - for(i=0; inTerm; i++){ + for(i=0; inBase; 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; jnTerm; j++, pTerm++){ + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; diff --git a/src/whereexpr.c b/src/whereexpr.c index eff7f4ab22..5a3fbe2d7f 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -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; inTerm; i++){ + assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 ); + } +#endif while(1){ if( a->wtFlags & TERM_DYNAMIC ){ sqlite3ExprDelete(db, a->pExpr);