]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Test cases added. Comments fixed. Proposed solution for
authordrh <drh@noemail.net>
Fri, 6 Mar 2015 20:49:52 +0000 (20:49 +0000)
committerdrh <drh@noemail.net>
Fri, 6 Mar 2015 20:49:52 +0000 (20:49 +0000)
ticket [05f43be8fdda9fbd9].

FossilOrigin-Name: 6b993bd54035b67f4d84941e3f444ca79b7feee1

manifest
manifest.uuid
src/vdbe.c
src/where.c
test/analyze3.test
test/like.test
test/like3.test [new file with mode: 0644]
test/where8.test

index 4af39ccdfbed7e55abf5d97d7826657bb16710e3..254c6a0b57539d025a57eac2d08ba1bed7f8e196 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sLIKE\soptimization\seven\swhen\scomparing\smixed-case\sBLOBs.
-D 2015-03-06T19:47:38.505
+C Test\scases\sadded.\s\sComments\sfixed.\s\sProposed\ssolution\sfor\nticket\s[05f43be8fdda9fbd9].
+D 2015-03-06T20:49:52.770
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
 F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
 F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
-F src/vdbe.c 6bee3b85a2f013a8fdc496996089d3b6bedfb525
+F src/vdbe.c c9f4ad2c62bccebed38b1fd253064ed2a2c659ae
 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
 F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a
 F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4
@@ -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 cace7eef1838ea22f549e824236eaaa4195b83e6
+F src/where.c 8cd4fc29addda0945b28b1f849a7998e3749d8b9
 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -321,7 +321,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
 F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
-F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275
+F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
 F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
@@ -689,8 +689,9 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
-F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991
+F test/like.test 4f2a71d36a536233727f71995fef900756705e56
 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
+F test/like3.test 9c85587224f739c81b51d8cdd2727c11ec678526
 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
 F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
@@ -1158,7 +1159,7 @@ F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
 F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
-F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1
+F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e
 F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
 F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
@@ -1240,7 +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 5757e803cb5759b476bbc6453c58340089611420
-R 1a18426c5e280ce5513288eef4bf379e
+P a58aafdb4e1422b6a8ffc07a67984928bbedf919
+R d75eaf03976986bf457292a7b369e1ff
 U drh
-Z 4902bd060fa099614e1fc5278ee9e5b6
+Z 9b58e75e5227e2cbfcfb68532871937f
index 95ba3aa55015320d5fede1a0c2acf86059861cde..7643f850793cb8c4efe4ea3b519a314a4b2bb758 100644 (file)
@@ -1 +1 @@
-a58aafdb4e1422b6a8ffc07a67984928bbedf919
\ No newline at end of file
+6b993bd54035b67f4d84941e3f444ca79b7feee1
\ No newline at end of file
index 0c9a67e56b6f9075b4d9cfe1f98ce5535d572968..6adea67960040ba885c678bd77b968bdea61d46c 100644 (file)
@@ -1053,9 +1053,9 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */
 ** The string value P4 of length P1 (bytes) is stored in register P2.
 **
 ** If P5!=0 and the content of register P3 is greater than zero, then
-** the datatype of the register P2 is convert to BLOB.  The content is
-** the same string text, it is merely interpreted as a BLOB as if it
-** had been CAST.  
+** the datatype of the register P2 is converted to BLOB.  The content is
+** the same sequence of bytes, it is merely interpreted as a BLOB instead
+** of a string, as if it had been CAST.
 */
 case OP_String: {          /* out2-prerelease */
   assert( pOp->p4.z!=0 );
index 24c3843472d2b909fee9b972983cc2f90a742d6d..e79e7d33bcce4f2e4d7a31805127129aab626eb2 100644 (file)
@@ -1109,7 +1109,7 @@ static void exprAnalyze(
   Bitmask extraRight = 0;          /* Extra dependencies on LEFT JOIN */
   Expr *pStr1 = 0;                 /* RHS of LIKE/GLOB operator */
   int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
-  int noCase = 0;                  /* LIKE/GLOB distinguishes case */
+  int noCase = 0;                  /* uppercase equivalent to lowercase */
   int op;                          /* Top-level operator.  pExpr->op */
   Parse *pParse = pWInfo->pParse;  /* Parsing context */
   sqlite3 *db = pParse->db;        /* Database connection */
@@ -1247,12 +1247,15 @@ static void exprAnalyze(
   /* Add constraints to reduce the search space on a LIKE or GLOB
   ** operator.
   **
-  ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
+  ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
   **
-  **          x>='abc' AND x<'abd' AND x LIKE 'abc%'
+  **          x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
   **
   ** The last character of the prefix "abc" is incremented to form the
-  ** termination condition "abd".
+  ** termination condition "abd".  If case is not significant (the default
+  ** for LIKE) then the lower-bound is made all uppercase and the upper-
+  ** bound is made all lowercase so that the bounds also work when comparing
+  ** BLOBs.
   */
   if( pWC->op==TK_AND 
    && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
@@ -1266,7 +1269,6 @@ static void exprAnalyze(
     Token sCollSeqName;  /* Name of collating sequence */
     const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
 
-    pTerm->wtFlags |= TERM_LIKE;
     pLeft = pExpr->x.pList->a[1].pExpr;
     pStr2 = sqlite3ExprDup(db, pStr1, 0);
 
@@ -1277,6 +1279,7 @@ static void exprAnalyze(
     if( noCase && !pParse->db->mallocFailed ){
       int i;
       char c;
+      pTerm->wtFlags |= TERM_LIKE;
       for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
         pStr1->u.zToken[i] = sqlite3Toupper(c);
         pStr2->u.zToken[i] = sqlite3Tolower(c);
@@ -2502,6 +2505,12 @@ static int whereInScanEst(
 ** and child2 terms were added by the LIKE optimization.  If both of
 ** the virtual child terms are valid, then testing of the parent can be 
 ** skipped.
+**
+** Usually the parent term is marked as TERM_CODED.  But if the parent
+** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
+** The TERM_LIKECOND marking indicates that the term should be coded inside
+** a conditional such that is only evaluated on the second pass of a
+** LIKE-optimization loop, when scanning BLOBs instead of strings.
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
   int nLoop = 0;
index e7416d5730337d821be10f6c5480faa6599aa510..d22387dcc3a17fdda730d2ac83aff281e1455937 100644 (file)
@@ -281,35 +281,35 @@ do_eqp_test analyze3-2.3 {
 
 do_test analyze3-2.4 {
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
-} {101 0 100}
+} {102 0 100}
 do_test analyze3-2.5 {
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
 } {999 999 100}
 
-do_test analyze3-2.4 {
+do_test analyze3-2.6 {
   set like "a%"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
-} {101 0 100}
-do_test analyze3-2.5 {
+} {102 0 100}
+do_test analyze3-2.7 {
   set like "%a"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
 } {999 999 100}
-do_test analyze3-2.6 {
+do_test analyze3-2.8 {
   set like "a"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
-} {101 0 0}
-do_test analyze3-2.7 {
+} {102 0 0}
+do_test analyze3-2.9 {
   set like "ab"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
-} {11 0 0}
-do_test analyze3-2.8 {
+} {12 0 0}
+do_test analyze3-2.10 {
   set like "abc"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
-} {2 0 1}
-do_test analyze3-2.9 {
+} {3 0 1}
+do_test analyze3-2.11 {
   set like "a_c"
   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
-} {101 0 10}
+} {102 0 10}
 
 
 #-------------------------------------------------------------------------
index 923272cfb2be24e1bc95baacac5c8cd8e0c6b1f3..18a01dc9967e50108d14e6c6cdd703b611976345 100644 (file)
@@ -749,7 +749,7 @@ ifcapable like_opt&&!icu {
     count {
       SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
     }
-  } {12 123 scan 3 like 0}
+  } {12 123 scan 4 like 0}
   do_test like-10.6 {
     count {
       SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
@@ -790,7 +790,7 @@ ifcapable like_opt&&!icu {
     count {
       SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
     }
-  } {12 123 scan 3 like 0}
+  } {12 123 scan 4 like 0}
   do_test like-10.15 {
     count {
       SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
diff --git a/test/like3.test b/test/like3.test
new file mode 100644 (file)
index 0000000..b3af2cd
--- /dev/null
@@ -0,0 +1,60 @@
+# 2015-03-06
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file implements regression tests for SQLite library.  The
+# focus of this file is testing the LIKE and GLOB operators and
+# in particular the optimizations that occur to help those operators
+# run faster and that those optimizations work correctly when there
+# are both strings and blobs being tested.
+#
+# Ticket 05f43be8fdda9fbd948d374319b99b054140bc36 shows that the following
+# SQL was not working correctly:
+#
+#     CREATE TABLE t1(x TEXT UNIQUE COLLATE nocase);
+#     INSERT INTO t1(x) VALUES(x'616263');
+#     SELECT 'query-1', x FROM t1 WHERE x LIKE 'a%';
+#     SELECT 'query-2', x FROM t1 WHERE +x LIKE 'a%';
+#
+# This script verifies that it works right now.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_execsql_test like3-1.1 {
+  PRAGMA encoding=UTF8;
+  CREATE TABLE t1(a,b TEXT COLLATE nocase);
+  INSERT INTO t1(a,b)
+     VALUES(1,'abc'),
+           (2,'ABX'),
+           (3,'BCD'),
+           (4,x'616263'),
+           (5,x'414258'),
+           (6,x'424344');
+  CREATE INDEX t1ba ON t1(b,a);
+
+  SELECT a, b FROM t1 WHERE b LIKE 'aB%' ORDER BY +a;
+} {1 abc 2 ABX 4 abc 5 ABX}
+do_execsql_test like3-1.2 {
+  SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a;
+} {1 abc 2 ABX 4 abc 5 ABX}
+
+do_execsql_test like3-1.3 {
+  CREATE TABLE t2(a, b TEXT);
+  INSERT INTO t2 SELECT a, b FROM t1;
+  CREATE INDEX t2ba ON t2(b,a);
+  SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a;
+} {1 abc 4 abc}
+do_execsql_test like3-1.4 {
+  SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a;
+} {1 abc 4 abc}
+
+finish_test
index 139251aa0729fca54adb348248ae451cb2190dd8..a155a95ab222dcd1e6f0f1e2f69314d3802c014d 100644 (file)
@@ -66,11 +66,11 @@ do_test where8-1.3 {
 
 do_test where8-1.4 { 
   execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' }
-} {IX X III II 0 0 9}
+} {IX X III II 0 0 10}
 
 do_test where8-1.5 { 
   execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' }
-} {IX X V IV 0 0 9}
+} {IX X V IV 0 0 10}
 
 do_test where8-1.6 { 
   execsql_status { SELECT c FROM t1 WHERE a = 1 OR b = 'three' ORDER BY rowid }