]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Provide hints for all terms in a range constraint if there are any equality
authordrh <drh@noemail.net>
Tue, 18 Aug 2015 15:58:05 +0000 (15:58 +0000)
committerdrh <drh@noemail.net>
Tue, 18 Aug 2015 15:58:05 +0000 (15:58 +0000)
terms anywhere in the constraint.  Range constraint terms are only omitted
for a pure range constraint with no equality prefix.

FossilOrigin-Name: b5897bc0f003c470eeb2a75e0a2b2bb202681531

manifest
manifest.uuid
src/wherecode.c
test/cursorhint.test

index f152345340b3d2679095818c14712ae4965ad41e..1f849deb21efa6b112423be793da8122c229e46c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\sgenerating\shints\susing\sconstraints\sthat\sare\salso\sused\sto\sinitialize\sthe\ncursor,\ssince\spresumably\sthe\scursor\salready\sknows\sabout\sthose\sconstraints.
-D 2015-08-17T17:19:28.483
+C Provide\shints\sfor\sall\sterms\sin\sa\srange\sconstraint\sif\sthere\sare\sany\sequality\nterms\sanywhere\sin\sthe\sconstraint.\s\sRange\sconstraint\sterms\sare\sonly\somitted\nfor\sa\spure\srange\sconstraint\swith\sno\sequality\sprefix.
+D 2015-08-18T15:58:05.895
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -414,7 +414,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
 F src/where.c ef95e56b6e7cdfa3ae0b6f72e3578391addfa965
 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047
-F src/wherecode.c 148c5dc225551309f489a5c44b8a0f7800c9794b
+F src/wherecode.c ec90321e51bd13a0396f305403bc8ced2af7407e
 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -560,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
 F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
-F test/cursorhint.test b1f86e9c959231094d8fe214518667548083063e
+F test/cursorhint.test 7d94f7602e22ec129ca51836f333b5ff994a2b02
 F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
@@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P bee73d429cb0e99b43fb191ac15e298d0353b135
-R f415b0a9be4e26d1aeb927a138261bed
+P 142b048ac778620dd4e448c2e969982eb8188501
+R e232e29543e31c41650c4e43b7879d83
 U drh
-Z dbc2b5253d321af49bf9c502e3a1dded
+Z 6f609828180274045282332efd8f8026
index 6fdfe94f71d85571005431f6a76543e0a1adfe9f..c4758539e8703d6d901e45b8da561f0d94920782 100644 (file)
@@ -1 +1 @@
-142b048ac778620dd4e448c2e969982eb8188501
\ No newline at end of file
+b5897bc0f003c470eeb2a75e0a2b2bb202681531
\ No newline at end of file
index 5e7710ae8af8d24620ded437b406c094a21c6420..0428495d40d7d7420d027fc05c6d446b27a777ee 100644 (file)
@@ -681,7 +681,6 @@ static void codeCursorHint(
   int iCur;
   WhereClause *pWC;
   WhereTerm *pTerm;
-  WhereLoop *pWLoop;
   int i, j;
   struct CCurHint sHint;
   Walker sWalker;
@@ -696,7 +695,6 @@ static void codeCursorHint(
   sWalker.pParse = pParse;
   sWalker.u.pCCurHint = &sHint;
   pWC = &pWInfo->sWC;
-  pWLoop = pLevel->pWLoop;
   for(i=0; i<pWC->nTerm; i++){
     pTerm = &pWC->a[i];
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
@@ -704,10 +702,11 @@ static void codeCursorHint(
     if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
 
     /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
-    ** the cursor.  No need to hint initialization terms. */
-    if( pTerm!=pEndRange ){
-      for(j=0; j<pWLoop->nLTerm && pWLoop->aLTerm[j]!=pTerm; j++){}
-      if( j<pWLoop->nLTerm ) continue;
+    ** the cursor.  These terms are not needed as hints for a pure range
+    ** scan (that has no == terms) so omit them. */
+    if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
+      for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
+      if( j<pLoop->nLTerm ) continue;
     }
 
     /* No subqueries or non-deterministic functions allowed */
@@ -1094,15 +1093,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
     }
     assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
 
-    /* Generate code to evaluate all constraint terms using == or IN
-    ** and store the values of those terms in an array of registers
-    ** starting at regBase.
-    */
-    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
-    assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
-    if( zStartAff ) cEndAff = zStartAff[nEq];
-    addrNxt = pLevel->addrNxt;
-
     /* If we are doing a reverse order scan on an ascending index, or
     ** a forward order scan on a descending index, interchange the 
     ** start and end terms (pRangeStart and pRangeEnd).
@@ -1114,6 +1104,16 @@ Bitmask sqlite3WhereCodeOneLoopStart(
       SWAP(u8, bSeekPastNull, bStopAtNull);
     }
 
+    /* Generate code to evaluate all constraint terms using == or IN
+    ** and store the values of those terms in an array of registers
+    ** starting at regBase.
+    */
+    codeCursorHint(pWInfo, pLevel, pRangeEnd);
+    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+    assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
+    if( zStartAff ) cEndAff = zStartAff[nEq];
+    addrNxt = pLevel->addrNxt;
+
     testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
     testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
     testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
@@ -1123,7 +1123,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
     start_constraints = pRangeStart || nEq>0;
 
     /* Seek the index cursor to the start of the range. */
-    codeCursorHint(pWInfo, pLevel, pRangeEnd);
     nConstraint = nEq;
     if( pRangeStart ){
       Expr *pRight = pRangeStart->pExpr->pRight;
index 4ff7faa859b9e0556fcda859b2f7f99ff2051296..75f3eb04e22f86359d2983da9aada6c77e2afbfb 100644 (file)
@@ -139,15 +139,19 @@ do_test 4.5desc {
     SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC;
   }
 } {GE(c0,10)}
+
+# If there are any equality terms used in the constraint, then all terms
+# should be hinted.
+#
 do_test 4.6asc {
   p4_of_opcode db CursorHint {
     SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC;
   }
-} {LE(c1,20)}
+} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
 do_test 4.6desc {
   p4_of_opcode db CursorHint {
     SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC;
   }
-} {GE(c1,10)}
+} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
 
 finish_test