]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When we play games with COLLATE in order to commute an operator in the
authordrh <drh@noemail.net>
Tue, 3 Sep 2019 14:27:25 +0000 (14:27 +0000)
committerdrh <drh@noemail.net>
Tue, 3 Sep 2019 14:27:25 +0000 (14:27 +0000)
WHERE clause processing, be sure not to use the commuted operator to qualify
a partial index, as insufficient COLLATE information is preserved to verify
that the expression will correctly qualify the index.
Ticket [767a8cbc6d20bd68]

FossilOrigin-Name: 5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a

manifest
manifest.uuid
src/where.c
src/whereInt.h
src/whereexpr.c
test/index6.test

index 8a800c1dc32b2ccb5dc8b2615a676f58c5dadc21..05386d4075d541cd3ccc3cfdb1caf1742846a092 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbug\sintroduced\searlier\stoday\sby\scheck-in\s[88833a9c2849c959].\nTicket\s[29f635e0af71234b]
-D 2019-09-02T22:13:06.403
+C When\swe\splay\sgames\swith\sCOLLATE\sin\sorder\sto\scommute\san\soperator\sin\sthe\nWHERE\sclause\sprocessing,\sbe\ssure\snot\sto\suse\sthe\scommuted\soperator\sto\squalify\na\spartial\sindex,\sas\sinsufficient\sCOLLATE\sinformation\sis\spreserved\sto\sverify\nthat\sthe\sexpression\swill\scorrectly\squalify\sthe\sindex.\nTicket\s[767a8cbc6d20bd68]
+D 2019-09-03T14:27:25.935
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -610,10 +610,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
-F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716
-F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
+F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64
+F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9
 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b
-F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f
+F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4
 F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e
@@ -1048,7 +1048,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
-F test/index6.test bae04b456a1845d8d48af751ac5b9bba5571551b96ef39d2b5b1db48cadd0fac
+F test/index6.test 4d1dd3cab97fba2ddf30bb70afc82eab35bd6e61788b3ac941e55263f81ef7e9
 F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020
 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
@@ -1839,7 +1839,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 9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef
-R 931628c07078d6a1ec560a2e18a3f53f
+P 6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73
+R f93cc76f663e94933b1f2f65b53349fd
 U drh
-Z 31499ded87036041191e77b0df0459dc
+Z 391da90ad359183d92b0ba19729274a1
index d9a9e049c686fddb70996eb7b3a4de978f98e6e8..63c1adf712ff7ef66a9c6879e07ab7a532892704 100644 (file)
@@ -1 +1 @@
-6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73
\ No newline at end of file
+5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a
\ No newline at end of file
index b51d4485c49f3ead46b34f18a59a3401a614d5f8..8c7874dc57c0ff35b44345d87477197020942a37 100644 (file)
@@ -2800,7 +2800,9 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
   }
   if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
   for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
-    Expr *pExpr = pTerm->pExpr;
+    Expr *pExpr;
+    if( pTerm->wtFlags & TERM_NOPARTIDX ) continue;
+    pExpr = pTerm->pExpr;
     if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
      && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) 
     ){
index e63ca46d53d09ea0e284a12cfb680cfd2d7114f2..64978cf110b3d2ff1b245b7b5817c65d9b9f4f2a 100644 (file)
@@ -291,6 +291,7 @@ struct WhereTerm {
 #define TERM_LIKE       0x400  /* The original LIKE operator */
 #define TERM_IS         0x800  /* Term.pExpr is an IS operator */
 #define TERM_VARSELECT  0x1000 /* Term.pExpr contains a correlated sub-query */
+#define TERM_NOPARTIDX  0x2000 /* Not for use to enable a partial index */
 
 /*
 ** An instance of the WhereScan object is used as an iterator for locating
index d878bdb9ecc8800306c55f3114b195d0645da2bb..f6f966b9e1a55929e3c5921ecb1edfbc19692c1e 100644 (file)
@@ -117,10 +117,16 @@ static int allowedOp(int op){
 ** the left hand side of a comparison overrides any collation sequence 
 ** attached to the right. For the same reason the EP_Collate flag
 ** is not commuted.
+**
+** The return value is extra flags that are added to the WhereTerm object
+** after it is commuted.  The only extra flag ever added is TERM_NOPARTIDX
+** which prevents the term from being used to enable a partial index if
+** COLLATE changes have been made.
 */
-static void exprCommute(Parse *pParse, Expr *pExpr){
+static u16 exprCommute(Parse *pParse, Expr *pExpr){
   u16 expRight = (pExpr->pRight->flags & EP_Collate);
   u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
+  u16 wtFlags = 0;
   assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
   if( expRight==expLeft ){
     /* Either X and Y both have COLLATE operator or neither do */
@@ -128,11 +134,13 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
       /* Both X and Y have COLLATE operators.  Make sure X is always
       ** used by clearing the EP_Collate flag from Y. */
       pExpr->pRight->flags &= ~EP_Collate;
+      wtFlags |= TERM_NOPARTIDX;
     }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
       /* Neither X nor Y have COLLATE operators, but X has a non-default
       ** collating sequence.  So add the EP_Collate marker on X to cause
       ** it to be searched first. */
       pExpr->pLeft->flags |= EP_Collate;
+      wtFlags |= TERM_NOPARTIDX;
     }
   }
   SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
@@ -144,6 +152,7 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
     assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
     pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
   }
+  return wtFlags;
 }
 
 /*
@@ -1140,7 +1149,7 @@ static void exprAnalyze(
         pDup = pExpr;
         pNew = pTerm;
       }
-      exprCommute(pParse, pDup);
+      pNew->wtFlags |= exprCommute(pParse, pDup);
       pNew->leftCursor = aiCurCol[0];
       pNew->u.leftColumn = aiCurCol[1];
       testcase( (prereqLeft | extraRight) != prereqLeft );
index d5bc77c0db06c527aaa79713b58691eb9ee5cd4b..976c49fb86ad70a6f357ab4547f15b5a03d54abf 100644 (file)
@@ -462,5 +462,23 @@ do_execsql_test index6-15.5 {
   SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE);
 } {1}
 
+# 2019-09-03
+# Ticket https://sqlite.org/src/info/767a8cbc6d20bd68
+do_execsql_test index6-16.1 {
+  DROP TABLE t0;
+  CREATE TABLE t0(c0 COLLATE NOCASE, c1);
+  CREATE INDEX i0 ON t0(0) WHERE c0 >= c1;
+  INSERT INTO t0 VALUES('a', 'B');
+  SELECT c1 <= c0, c0 >= c1 FROM t0;
+} {1 0}
+do_execsql_test index6-16.2 {
+  SELECT 2 FROM t0 WHERE c0 >= c1;
+} {}
+do_execsql_test index6-16.3 {
+  SELECT 3 FROM t0 WHERE c1 <= c0;
+} {3}
+
+
+
 
 finish_test