]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the LIKE optimization so that it works for arbitrary expressions on
authordrh <drh@noemail.net>
Fri, 10 Feb 2017 21:37:57 +0000 (21:37 +0000)
committerdrh <drh@noemail.net>
Fri, 10 Feb 2017 21:37:57 +0000 (21:37 +0000)
the LHS as long as the pattern on the RHS does not begin with a digit or
a minus sign.

FossilOrigin-Name: 158290c0abafde67ee3f2363f0b6646887841df3

manifest
manifest.uuid
src/whereexpr.c
test/vtab1.test
test/vtabH.test

index 53d7e16ed6c33c18e1ddd2a0c0dfc3d843bf9783..9d7931aab5b7181e41e37337b463844fe04ec57d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\s","\sflag\sto\sprintf().
-D 2017-02-10T19:38:36.506
+C Enhance\sthe\sLIKE\soptimization\sso\sthat\sit\sworks\sfor\sarbitrary\sexpressions\son\nthe\sLHS\sas\slong\sas\sthe\spattern\son\sthe\sRHS\sdoes\snot\sbegin\swith\sa\sdigit\sor\na\sminus\ssign.
+D 2017-02-10T21:37:57.808
 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99
@@ -478,7 +478,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
 F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2
 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d
 F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28
-F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6
+F src/whereexpr.c 980109826ba02750421c3fa7ab0ecabbac0a639d
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1374,7 +1374,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
-F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
+F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a
 F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
 F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
@@ -1389,7 +1389,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
 F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
-F test/vtabH.test a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3
+F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764
 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
@@ -1555,7 +1555,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 798fb9d70d2e5f95e64237b04d6692360133381a
-R c3dc7f748658995c87bb25e10706fab3
+P 064445b12f99f76e9a12957be97edd520ab3ae27
+R db970521e4fc7396c9c380bbcef0e8ad
 U drh
-Z 3add84968b9ef1dfcf3d7b3eaefd30ad
+Z 2c915b2d7e6621ed4f4d2fbc11d0cc6c
index 8090b2db3660bf045ce6100b4a3d6d4453ed9a41..0e09e9b7312235ebc1df013a0e76ef061da4e925 100644 (file)
@@ -1 +1 @@
-064445b12f99f76e9a12957be97edd520ab3ae27
\ No newline at end of file
+158290c0abafde67ee3f2363f0b6646887841df3
\ No newline at end of file
index 826d329b7f1d8f91c942e053ef531e38815093b3..f511452e52a09f623753f0a131c025626efbb14d 100644 (file)
@@ -213,15 +213,6 @@ static int isLikeOrGlob(
 #endif
   pList = pExpr->x.pList;
   pLeft = pList->a[1].pExpr;
-  if( pLeft->op!=TK_COLUMN 
-   || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
-   || IsVirtual(pLeft->pTab)  /* Value might be numeric */
-  ){
-    /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
-    ** be the name of an indexed column with TEXT affinity. */
-    return 0;
-  }
-  assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
 
   pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
   op = pRight->op;
@@ -238,6 +229,23 @@ static int isLikeOrGlob(
     z = pRight->u.zToken;
   }
   if( z ){
+
+    /* If the RHS begins with a digit or a minus sign, then the LHS must
+    ** be an ordinary column (not a virtual table column) with TEXT affinity.
+    ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
+    ** even though "lhs LIKE rhs" is true.  But if the RHS does not start
+    ** with a digit or '-', then "lhs LIKE rhs" will always be false if
+    ** the LHS is numeric and so the optimization still works.
+    */
+    if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
+      if( pLeft->op!=TK_COLUMN 
+       || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
+       || IsVirtual(pLeft->pTab)  /* Value might be numeric */
+      ){
+        sqlite3ValueFree(pVal);
+        return 0;
+      }
+    }
     cnt = 0;
     while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
       cnt++;
index 6b6a0e2683bcb126c03daa3f6920a7f88a65f446..59ab9597464466b50d9107d4e52593a2468c1d75 100644 (file)
@@ -1295,25 +1295,25 @@ do_execsql_test 18.1.0 {
   CREATE INDEX i6 ON t6(b, a);
   INSERT INTO t6 VALUES(1, 'Peter');
   INSERT INTO t6 VALUES(2, 'Andrew');
-  INSERT INTO t6 VALUES(3, 'James');
-  INSERT INTO t6 VALUES(4, 'John');
+  INSERT INTO t6 VALUES(3, '8James');
+  INSERT INTO t6 VALUES(4, '8John');
   INSERT INTO t6 VALUES(5, 'Phillip');
   INSERT INTO t6 VALUES(6, 'Bartholomew');
   CREATE VIRTUAL TABLE e6 USING echo(t6);
 }
 
 foreach {tn sql res filter} {
-  1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James}
+  1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James}
 
-  1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K}
+  1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9}
 
-  1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
+  1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
 
-  1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
+  1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
 } {
   set echo_module {}
   do_execsql_test 18.$tn.1 $sql $res
@@ -1322,11 +1322,11 @@ foreach {tn sql res filter} {
 
 do_execsql_test 18.2.0 {  PRAGMA case_sensitive_like = ON }
 foreach {tn sql res filter} {
-  2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
+  2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
 
-  2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
-    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
+  2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {}
+    {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
 } {
   set echo_module {}
   do_execsql_test 18.$tn.1 $sql $res
index 3ce457ff0b219ab14cf1bec76ab4dad4f1e7cb67..c5684ff516890209e3d504d48cbd1242e44b2661 100644 (file)
@@ -31,14 +31,14 @@ do_execsql_test 1.0 {
 }
 
 foreach {tn sql expect} {
-  1 "SELECT * FROM e6 WHERE b LIKE 'abc'" {
+  1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
     xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
-    xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc
+    xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc
   }
 
-  2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
+  2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
     xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
-    xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc
+    xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc
   }
 } {
   do_test 1.$tn {