diff --git a/manifest b/manifest index 78850cff06..ed505a6910 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sgenerate\sa\sBloom\sfilter\sif\sit\scannot\sbe\sused\sprior\sto\sthe\snext\sseek,\nas\sthat\sleads\sto\sa\smisleading\sEXPLAIN\sQUERY\sPLAN. -D 2021-12-07T22:37:50.686 +C Merge\sthe\sWhereClause\sfix\sfrom\strunk +D 2021-12-08T16:15:41.698 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 328e5c6f5a91f8c1e36417159cc93ea180700ae97726f934f69e68c8c60030b5 -F src/whereInt.h 5c6601d6d0b7b8936482506d2d835981cc6efcd8e106a829893a27a14cfb10b8 -F src/wherecode.c f82a322a8849a0290587d968f5c1c71b0d5018e078f43ea732a4cdbf837ed42b -F src/whereexpr.c 19394cb463003e9cc9305730b1508b8817a22bb7247170d81234b691a7f05b89 +F src/where.c 74382d720f2a9a06f738467929ecf0d79fcdd6b9779184bddbb97352895a1b23 +F src/whereInt.h d55d5ce5c9de361e16cf5cd23da054cdecc1ae7735682ee55c2f40e58e960d22 +F src/wherecode.c e2207f011b7e5bdef5722da5e8d95eb30ad01051b3526757901ecb19a9e98ff3 +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 00070e1fff6aec3d7c7b121f2b02bbca38a1664aca9afc3fb7e293f07fd1704f -R 6ef1a6c68af918fb5dc855e869b3769c +P 2739ed5192058fbcc816ecbc252be687efc606e038bfcd6cf71194a3f4f5684e 6024682ca467fa4fe49608772b0bbfa2f8a419b32cebfa715941073c8b29da49 +R d3afb24f2c63fc5d59ade7856914b3ad U drh -Z 7a26146d090468562610338a13462117 +Z 246d691185204c115a5a684ad14acaf7 diff --git a/manifest.uuid b/manifest.uuid index f1d3a5f29a..1416a80b0a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2739ed5192058fbcc816ecbc252be687efc606e038bfcd6cf71194a3f4f5684e \ No newline at end of file +d3250256772e3348abe887c0ca3550a6647cce3804c9456a9d0112aea7ee1c46 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 1eb9f36017..bf10262a76 100644 --- a/src/where.c +++ b/src/where.c @@ -2490,11 +2490,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; @@ -3765,6 +3765,7 @@ static int whereLoopAddOr( tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.nTerm = 1; + tempWC.nBase = 1; tempWC.a = pOrTerm; sSubBuild.pWC = &tempWC; }else{ @@ -5256,7 +5257,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 4da6015f16..558a1e3eb9 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -321,6 +321,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 c04a73c2a8..42cfcc9eac 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1033,7 +1033,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; @@ -2598,7 +2598,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; @@ -2643,7 +2643,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);