]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Always use LIKE optimization range constraints in pairs. like-opt-fix
authordrh <drh@noemail.net>
Mon, 9 Mar 2015 12:11:56 +0000 (12:11 +0000)
committerdrh <drh@noemail.net>
Mon, 9 Mar 2015 12:11:56 +0000 (12:11 +0000)
FossilOrigin-Name: 0e02dc94fd1bb891d0edd1e34b57e923b17712a7

manifest
manifest.uuid
src/where.c

index 8ac17721f1ff2469e93b6835ecc9a990910720cf..1c5b59c03397ca5106a9f6def979ca8cdae854c6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sanother\sproblem\swith\sthe\sLIKE\soptimization.
-D 2015-03-07T20:32:49.790
+C Always\suse\sLIKE\soptimization\srange\sconstraints\sin\spairs.
+D 2015-03-09T12:11:56.889
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
-F src/where.c 65813699926c15b7041ff2021731f03183aac493
+F src/where.c 21c96bc0265228dbca2feb3f65c464bc464ec4c2
 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1241,10 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 74cb0b032fcf598537fae04412771450124ae712
-R 23dd5631417bc0e4cabfa079f9a22509
-T *branch * like-opt-fix
-T *sym-like-opt-fix *
-T -sym-trunk *
+P 465bfc72d252f94778248253142faeba78ceea02
+R 3b7b3881e4a2944ad5c0176e96b8fcf3
 U drh
-Z c34701a311a2e64477c46e48ef38102d
+Z 1e9efc602031c231aa2c489f96b95b11
index e3c05917013e5ce30d58410c42b260003bdbff6e..9abd00976ed372ff4a788778b4d6bcc567aea254 100644 (file)
@@ -1 +1 @@
-465bfc72d252f94778248253142faeba78ceea02
\ No newline at end of file
+0e02dc94fd1bb891d0edd1e34b57e923b17712a7
\ No newline at end of file
index 3e2558d00e62adc42b348d28cd214fdd77306b21..d6bce65d2e5724a18d4b938ca29b38eae8a5834f 100644 (file)
@@ -3013,8 +3013,8 @@ static void addScanStatus(
 #endif
 
 /*
-** Look at the last instruction coded.  If that instruction is OP_String8
-** and if pLoop->iLikeRepCntr is non-zero, then change the P3 to be
+** If the most recently coded instruction is a constant range contraint
+** that originated from the LIKE optimization, then change the P3 to be
 ** pLoop->iLikeRepCntr and set P5.
 **
 ** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
@@ -3030,11 +3030,14 @@ static void whereLikeOptimizationStringFixup(
   WhereTerm *pTerm        /* The upper or lower bound just coded */
 ){
   if( pTerm->wtFlags & TERM_LIKEOPT ){
-    VdbeOp *pOp = sqlite3VdbeGetOp(v, -1);
-    if( pLevel->iLikeRepCntr && pOp->opcode==OP_String8 ){
-      pOp->p3 = pLevel->iLikeRepCntr;
-      pOp->p5 = 1;
-    }
+    VdbeOp *pOp;
+    assert( pLevel->iLikeRepCntr>0 );
+    pOp = sqlite3VdbeGetOp(v, -1);
+    assert( pOp!=0 );
+    assert( pOp->opcode==OP_String8 
+            || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
+    pOp->p3 = pLevel->iLikeRepCntr;
+    pOp->p5 = 1;
   }
 }
 
@@ -3370,9 +3373,9 @@ static Bitmask codeOneLoopStart(
     if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
       pRangeEnd = pLoop->aLTerm[j++];
       nExtraReg = 1;
-      if( (pRangeStart && (pRangeStart->wtFlags & TERM_LIKEOPT)!=0)
-       || (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0
-      ){
+      if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
+        assert( pRangeStart!=0 );
+        assert( pRangeStart->wtFlags & TERM_LIKEOPT );
         pLevel->iLikeRepCntr = ++pParse->nMem;
         testcase( bRev );
         testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
@@ -4547,6 +4550,10 @@ static int whereLoopAddBtreeIndex(
     }
     if( pTerm->prereqRight & pNew->maskSelf ) continue;
 
+    /* Do not allow the upper bound of a LIKE optimization range constraint
+    ** to mix with a lower range bound from some other source */
+    if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
+
     pNew->wsFlags = saved_wsFlags;
     pNew->u.btree.nEq = saved_nEq;
     pNew->nLTerm = saved_nLTerm;
@@ -4590,6 +4597,17 @@ static int whereLoopAddBtreeIndex(
       pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
       pBtm = pTerm;
       pTop = 0;
+      if( pTerm->wtFlags & TERM_LIKEOPT ){
+        /* Make sure that range contraints that come from the LIKE
+        ** optimization are always used in pairs. */
+        pTop = &pTerm[1];
+        assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
+        assert( pTop->wtFlags & TERM_LIKEOPT );
+        assert( pTop->eOperator==WO_LT );
+        if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+        pNew->aLTerm[pNew->nLTerm++] = pTop;
+        pNew->wsFlags |= WHERE_TOP_LIMIT;
+      }
     }else{
       assert( eOp & (WO_LT|WO_LE) );
       testcase( eOp & WO_LT );