]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with processing "LEFT JOIN tbl ON tbl.a = ? AND (tbl.b=? OR
authordan <dan@noemail.net>
Tue, 24 Apr 2018 18:53:24 +0000 (18:53 +0000)
committerdan <dan@noemail.net>
Tue, 24 Apr 2018 18:53:24 +0000 (18:53 +0000)
tbl.c=?)" in cases where there are indexes on both tbl(a, b) and tbl(a, c).

FossilOrigin-Name: ce35e39c5cc2b00dd6b4a9ffaa9d5eb7d9b862759e87d5f053729de7643eee9c

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

index 4754d46a07dd106bb6ee5855ed5046f7b7ebd81c..425acebba3342947e06f02d029cfb79c55499c5c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\sattempt\sto\suse\sterms\sfrom\sthe\sWHERE\sclause\sto\sdrive\sindexes\son\sthe\nright\stable\sof\sa\sLEFT\sJOIN.\s\sFix\sfor\sticket\s[4ba5abf65c5b0f9a96a7a40cd18b]
-D 2018-04-24T17:34:03.981
+C Fix\sa\sproblem\swith\sprocessing\s"LEFT\sJOIN\stbl\sON\stbl.a\s=\s?\sAND\s(tbl.b=?\sOR\ntbl.c=?)"\sin\scases\swhere\sthere\sare\sindexes\son\sboth\stbl(a,\sb)\sand\stbl(a,\sc).
+D 2018-04-24T18:53:24.943
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
@@ -578,7 +578,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
 F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
 F src/where.c 7a1c5555c00bcf49c677472ae83bb49bf24c8d8e9a060d475e86dee39be2fb3a
 F src/whereInt.h 2610cb87dd95509995b63decc674c60f2757697a206cfe0c085ee53d9c43cfff
-F src/wherecode.c 52225f6b519c7742a593341a13308d8fd08af7f91af0fa765c6adad85978d525
+F src/wherecode.c 3cb591fe7323e1bfd49059d75fcab75e383dfcf16a51c0e4f9368ac1b93e291b
 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1011,7 +1011,7 @@ F test/join.test 2ad9d7fe10e0cc06bc7803c22e5533be11cdadbc592f5f95d789a873b57a5a6
 F test/join2.test f5ea0fd3b0a441c8e439706339dcd17cec63a896a755c04a30bfd442ecce1190
 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
-F test/join5.test cb052e7126fe3492dce2e851b980b487a823a0a4cb2ce2d773c92f14a453dad7
+F test/join5.test 000a18e9ccc9fc716e550eb2337729d3aee99031d0ddd9682f6b7d73aa99b924
 F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
@@ -1725,7 +1725,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 8acb42f48929d908fe67a8536e240ca252a9ab780dce79eaa85b8fba35d52250
-R 4eebdb5072e10414126cf7987af3576c
-U drh
-Z 0f34fac3f1b4f07abfd291b9539f090e
+P aeb694e3f787f1f8b55650c17f90c197eee3f7f9b890a88f458c33e43009a082
+R 56c49ae18195fa15548a505c9f447aff
+U dan
+Z 3395e9aff5f6302e6b05ef897c94003f
index 93572b4b4f7738a988ef11a6ecea203d1faa9a5f..728dc6f2e2a0de602cf7b31a4bea3473f9d1d56d 100644 (file)
@@ -1 +1 @@
-aeb694e3f787f1f8b55650c17f90c197eee3f7f9b890a88f458c33e43009a082
\ No newline at end of file
+ce35e39c5cc2b00dd6b4a9ffaa9d5eb7d9b862759e87d5f053729de7643eee9c
\ No newline at end of file
index 3432d4b6b1a7cb94908359bb246077d9cdb0ef2f..818a7a208ba241e8c72794b34c905a0596eb8d42 100644 (file)
@@ -1215,6 +1215,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
   ** initialize a memory cell that records if this table matches any
   ** row of the left table of the join.
   */
+  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
+  );
   if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
     pLevel->iLeftJoin = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
@@ -1913,7 +1916,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
       for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
         Expr *pExpr = pWC->a[iTerm].pExpr;
         if( &pWC->a[iTerm] == pTerm ) continue;
-        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
         testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
         testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
         if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
@@ -1938,7 +1940,10 @@ Bitmask sqlite3WhereCodeOneLoopStart(
         WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
         Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
         int jmp1 = 0;                   /* Address of jump operation */
-        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
+        assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 
+             || ExprHasProperty(pOrExpr, EP_FromJoin) 
+        );
+        if( pAndExpr ){
           pAndExpr->pLeft = pOrExpr;
           pOrExpr = pAndExpr;
         }
@@ -2121,7 +2126,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
       }
       pE = pTerm->pExpr;
       assert( pE!=0 );
-      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
+      if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
         continue;
       }
       
index 9e994cede5c09cf99815f9982ce27991a23cf547..12fe56cb9273463819b5252fd8d7942d1bcfca22 100644 (file)
@@ -241,5 +241,53 @@ do_execsql_test 6.3.2 {
   SELECT ifnull(z, '!!!') FROM t3 LEFT JOIN t4 ON (x=y);
 } {!!!}
 
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 7.0 {
+  CREATE TABLE t1(x);
+  INSERT INTO t1 VALUES(1);
+}
+
+do_execsql_test 7.1 {
+  CREATE TABLE t2(x, y, z);
+  CREATE INDEX t2xy ON t2(x, y);
+  WITH s(i) AS (
+    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000
+  )
+  INSERT INTO t2 SELECT i/10, i, NULL FROM s;
+  ANALYZE;
+}
+
+do_eqp_test 7.2 {
+  SELECT * FROM t1 LEFT JOIN t2 ON (
+    t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL))
+  );
+} {
+  0 0 0 {SCAN TABLE t1} 
+  0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)} 
+  0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)}
+}
+
+do_execsql_test 7.3 {
+  CREATE TABLE t3(x);
+
+  CREATE TABLE t4(x, y, z);
+  CREATE INDEX t4xy ON t4(x, y);
+  CREATE INDEX t4xz ON t4(x, z);
+
+  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000)
+  INSERT INTO t4 SELECT i/10, i, i FROM s;
+
+  ANALYZE;
+}
+
+do_eqp_test 7.4 {
+  SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
+} {
+  0 0 0 {SCAN TABLE t3} 
+  0 1 1 {SEARCH TABLE t4 USING INDEX t4xz (x=?)}
+} 
+
 finish_test