]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with affinity changes and vector range comparisons.
authordan <dan@noemail.net>
Fri, 26 Aug 2016 17:54:46 +0000 (17:54 +0000)
committerdan <dan@noemail.net>
Fri, 26 Aug 2016 17:54:46 +0000 (17:54 +0000)
FossilOrigin-Name: b34413ac7e34369b4420e57b0132249dca68a7b0

manifest
manifest.uuid
src/wherecode.c

index 1bca06079a1df658e1025c4b291b99bd34ba3d72..cb2c5f28b510c83effa31c1aadaf904644862d87 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Allow\sROWID\svalues\sin\sindexed\svector\scomparisons.
-D 2016-08-26T13:19:49.916
+C Fix\sa\sproblem\swith\saffinity\schanges\sand\svector\srange\scomparisons.
+D 2016-08-26T17:54:46.350
 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c
@@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09
 F src/where.c bad93f9bc5e62c38d2e0d2f572dd01d359c8d4cb
 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
-F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f
+F src/wherecode.c 71de4d2d36fa3afe6160e98334f1a717c226ee86
 F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1521,7 +1521,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 397617009e07004596476d6f5644fdf84c376f54
-R bebe23f740f385ed54a0790b48a77a67
-U drh
-Z b30339a1eb9e7f2b74488db2fab0ab4b
+P b0cc6be4eb81f21b11796e1f14d4412bf21dea6e
+R 0bd9bba299be3b1c19235baf0c5a546b
+U dan
+Z 7b1a4a5a11db26063e955544de8c89fc
index f2f928f54a561c0d908e43d46a2008ae03ecb331..ab39b9341fa3d449dc77e32d57be6958de0f7535 100644 (file)
@@ -1 +1 @@
-b0cc6be4eb81f21b11796e1f14d4412bf21dea6e
\ No newline at end of file
+b34413ac7e34369b4420e57b0132249dca68a7b0
\ No newline at end of file
index 65079872e14d1faa0a29d38f3bdd3a06118b3167..34894fe1bb8f807f2c9d6a2d096fd9f4ddd77f57 100644 (file)
@@ -350,6 +350,32 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
   }
 }
 
+/*
+** Expression pRight, which is the RHS of a comparison operation, is 
+** either a vector of n elements or, if n==1, a scalar expression.
+** Before the comparison operation, affinity zAff is to be applied
+** to the pRight values. This function modifies characters within the
+** affinity string to SQLITE_AFF_BLOB if either:
+**
+**   * the comparison will be performed with no affinity, or
+**   * the affinity change in zAff is guaranteed not to change the value.
+*/
+static void updateRangeAffinityStr(
+  Parse *pParse,                  /* Parse context */
+  Expr *pRight,                   /* RHS of comparison */
+  int n,                          /* Number of vector elements in comparison */
+  char *zAff                      /* Affinity string to modify */
+){
+  int i;
+  for(i=0; i<n; i++){
+    Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
+    if( sqlite3CompareAffinity(p, zAff[i])==SQLITE_AFF_BLOB
+     || sqlite3ExprNeedsNoAffinityChange(p, zAff[i])
+    ){
+      zAff[i] = SQLITE_AFF_BLOB;
+    }
+  }
+}
 
 /*
 ** Generate code for a single equality term of the WHERE clause.  An equality
@@ -1330,7 +1356,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
     int nExtraReg = 0;           /* Number of extra registers needed */
     int op;                      /* Instruction opcode */
     char *zStartAff;             /* Affinity for start of range constraint */
-    char cEndAff = 0;            /* Affinity for end of range constraint */
+    char *zEndAff = 0;           /* Affinity for end of range constraint */
     u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
     u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
 
@@ -1417,7 +1443,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
     codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
     regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
     assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
-    if( zStartAff ) cEndAff = zStartAff[nEq];
+    if( zStartAff && nTop ){
+      zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
+    }
     addrNxt = pLevel->addrNxt;
 
     testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
@@ -1441,15 +1469,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
         VdbeCoverage(v);
       }
       if( zStartAff ){
-        if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_BLOB){
-          /* Since the comparison is to be performed with no conversions
-          ** applied to the operands, set the affinity to apply to pRight to 
-          ** SQLITE_AFF_BLOB.  */
-          zStartAff[nEq] = SQLITE_AFF_BLOB;
-        }
-        if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
-          zStartAff[nEq] = SQLITE_AFF_BLOB;
-        }
+        updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]);
       }  
       nConstraint += nBtm;
       testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
@@ -1498,11 +1518,8 @@ Bitmask sqlite3WhereCodeOneLoopStart(
         sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
         VdbeCoverage(v);
       }
-      if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_BLOB
-       && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
-      ){
-        codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff);
-      }
+      updateRangeAffinityStr(pParse, pRight, nTop, zEndAff);
+      codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
       nConstraint += nTop;
       testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
 
@@ -1517,6 +1534,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
       nConstraint++;
     }
     sqlite3DbFree(db, zStartAff);
+    sqlite3DbFree(db, zEndAff);
 
     /* Top of the loop body */
     pLevel->p2 = sqlite3VdbeCurrentAddr(v);