]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The optimization of check-in [9b2879629c34fc0a] is incorrectly reasoned.
authordrh <drh@noemail.net>
Sun, 3 Nov 2019 00:07:41 +0000 (00:07 +0000)
committerdrh <drh@noemail.net>
Sun, 3 Nov 2019 00:07:41 +0000 (00:07 +0000)
The WHERE clause of the partial index might not be true if the table of
the partial index is the right table of a left join.  So disable the
optimization in that case.  Ticket [623eff57e76d45f6]

FossilOrigin-Name: 3be19e1151af1850b65991edb82420f9412a7798dd756c86eaa9ffdde573263a

manifest
manifest.uuid
src/wherecode.c
test/join.test

index 8cbd2dbb6252b926471cd7075841fd24f23d2805..d9d313e82eb55697224283ca7307e9aede18bcd9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\sin\sVIEW\screation\sthat\swas\sintroduced\sby\sthe\sgenerated\scolumns\nfeature.
-D 2019-11-02T17:59:10.372
+C The\soptimization\sof\scheck-in\s[9b2879629c34fc0a]\sis\sincorrectly\sreasoned.\nThe\sWHERE\sclause\sof\sthe\spartial\sindex\smight\snot\sbe\strue\sif\sthe\stable\sof\nthe\spartial\sindex\sis\sthe\sright\stable\sof\sa\sleft\sjoin.\s\sSo\sdisable\sthe\noptimization\sin\sthat\scase.\s\sTicket\s[623eff57e76d45f6]
+D 2019-11-03T00:07:41.595
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -614,7 +614,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
 F src/where.c 6e56bef94dc1e2d4461fca49604602312dc620333572aad9511e5ca2120aff31
 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
-F src/wherecode.c 28a3f27b44165e05bac3031f9a9ee9901305647b6c9dfc0214544578066ab097
+F src/wherecode.c 123cd05eae51dd2d9e9e0483680298c3a62529a6ed3ec29ce217a2834427cabb
 F src/whereexpr.c 0705f608f6dbbd4e95d440528d6c760b91b6f402ba4eb8b8d964c110e2010780
 F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -1083,7 +1083,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
 F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
 F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a
-F test/join.test 832f7c7550a7c59a71c5e2886979a0770ba3b184f021387712680f804fae1df0
+F test/join.test debdadab636bb35c73084902c12ce4d2012bfa7a5f8a2c693bb3ba13059f2224
 F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417
 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
@@ -1849,7 +1849,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 167cd574d6a1d4fe2253f5bc5aaa7b031cbc82853e4d33b8d9b72eaf049003d4
-R 794e59eee68ad1454caf01bc0c6b2777
+P 9c795c4d2b042d2932774bd1274fa0167ca2dc9838e127e0cf31eb9273a32f2c
+R 5e53c74cccd75d696adb47595d7bc2ca
 U drh
-Z 3ce02ac4b8e69a52ea025b6134fd1022
+Z 9c91bb1be2f76e50e900200e5b535282
index 91fbc9e7f6915e14770b7520bf4c4bb0e2cbb3d0..367204177ca44dc3a6b1001d055f01a79f91c9e1 100644 (file)
@@ -1 +1 @@
-9c795c4d2b042d2932774bd1274fa0167ca2dc9838e127e0cf31eb9273a32f2c
\ No newline at end of file
+3be19e1151af1850b65991edb82420f9412a7798dd756c86eaa9ffdde573263a
\ No newline at end of file
index 351af766e64bb52cd2fac114ca67f15431405ec6..7447fafb5aea8437c384c3907a26207e5e35e354 100644 (file)
@@ -1870,35 +1870,43 @@ Bitmask sqlite3WhereCodeOneLoopStart(
                            iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
     }
 
-    /* If pIdx is an index on one or more expressions, then look through
-    ** all the expressions in pWInfo and try to transform matching expressions
-    ** into reference to index columns.  Also attempt to translate references
-    ** to virtual columns in the table into references to (stored) columns
-    ** of the index.
-    **
-    ** Do not do this for the RHS of a LEFT JOIN. This is because the 
-    ** expression may be evaluated after OP_NullRow has been executed on
-    ** the cursor. In this case it is important to do the full evaluation,
-    ** as the result of the expression may not be NULL, even if all table
-    ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
-    **
-    ** Also, do not do this when processing one index an a multi-index
-    ** OR clause, since the transformation will become invalid once we
-    ** move forward to the next index.
-    ** https://sqlite.org/src/info/4e8e4857d32d401f
-    */
-    if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
-      whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
-    }
-
-    /* If a partial index is driving the loop, try to eliminate WHERE clause
-    ** terms from the query that must be true due to the WHERE clause of
-    ** the partial index
-    */
-    if( pIdx->pPartIdxWhere ){
-      whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
+    if( pLevel->iLeftJoin==0 ){
+      /* If pIdx is an index on one or more expressions, then look through
+      ** all the expressions in pWInfo and try to transform matching expressions
+      ** into reference to index columns.  Also attempt to translate references
+      ** to virtual columns in the table into references to (stored) columns
+      ** of the index.
+      **
+      ** Do not do this for the RHS of a LEFT JOIN. This is because the 
+      ** expression may be evaluated after OP_NullRow has been executed on
+      ** the cursor. In this case it is important to do the full evaluation,
+      ** as the result of the expression may not be NULL, even if all table
+      ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
+      **
+      ** Also, do not do this when processing one index an a multi-index
+      ** OR clause, since the transformation will become invalid once we
+      ** move forward to the next index.
+      ** https://sqlite.org/src/info/4e8e4857d32d401f
+      */
+      if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+        whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
+      }
+  
+      /* If a partial index is driving the loop, try to eliminate WHERE clause
+      ** terms from the query that must be true due to the WHERE clause of
+      ** the partial index.
+      **
+      ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work
+      ** for a LEFT JOIN.
+      */
+      if( pIdx->pPartIdxWhere ){
+        whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
+      }
+    }else{
+      testcase( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
+      testcase( pIdx->pPartIdxWhere );
     }
-
+  
     /* Record the instruction used to terminate the loop. */
     if( pLoop->wsFlags & WHERE_ONEROW ){
       pLevel->op = OP_Noop;
index 7d7524508d6089989efde01056f9257a38a2f95d..0edfe0d84b5027479d734173b40401ce4bb244ad 100644 (file)
@@ -935,4 +935,22 @@ do_execsql_test join-19.5 {
     (b IS NOT NULL AND b IS NOT NULL) IS NOT NULL; 
 } {0 {}}
 
+# 2019-11-02 ticket 623eff57e76d45f6
+# The optimization of exclusing the WHERE expression of a partial index
+# from the WHERE clause of the query if the index is used does not work
+# of the table of the index is the right-hand table of a LEFT JOIN.
+#
+db close
+sqlite3 db :memory:
+do_execsql_test join-20.1 {
+  CREATE TABLE t1(c1);
+  CREATE TABLE t0(c0);
+  INSERT INTO t0(c0) VALUES (0);
+  SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1);
+} {}
+do_execsql_test join-20.2 {
+  CREATE INDEX t1x ON t1(0) WHERE NULL IN (c1);
+  SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1);
+} {}
+
 finish_test