]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Additional work on ticket #3015. The previous fix (check-in (4919)) did
authordrh <drh@noemail.net>
Thu, 17 Apr 2008 19:14:02 +0000 (19:14 +0000)
committerdrh <drh@noemail.net>
Thu, 17 Apr 2008 19:14:02 +0000 (19:14 +0000)
not appear to work in all cases and it disabled indexing in some places
where it should not have.  New test cases added to help insure that the
current fix is better. (CVS 5026)

FossilOrigin-Name: 0d2e258e1a3276e55903ba2ded987f8d8a18cacd

manifest
manifest.uuid
src/select.c
src/where.c
test/tester.tcl
test/where3.test
test/where6.test

index ba561dd31dfa97f6ad7a53df6923173567e1ed18..4da70cf220b5cfdbc44ed77f4f0a0daf6fb8f469 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\ssqlite3_bind_text.\s\sTicket\s#3056.\s(CVS\s5025)
-D 2008-04-17T17:03:26
+C Additional\swork\son\sticket\s#3015.\s\sThe\sprevious\sfix\s(check-in\s(4919))\sdid\nnot\sappear\sto\swork\sin\sall\scases\sand\sit\sdisabled\sindexing\sin\ssome\splaces\nwhere\sit\sshould\snot\shave.\s\sNew\stest\scases\sadded\sto\shelp\sinsure\sthat\sthe\ncurrent\sfix\sis\sbetter.\s(CVS\s5026)
+D 2008-04-17T19:14:02
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -134,7 +134,7 @@ F src/pragma.c 113f14da852b4f94edcf4af718702287b15641e8
 F src/prepare.c adc7e1fc08dfbab63cd213d4c0aff8f3fa70d477
 F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
 F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
-F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1
+F src/select.c b02ee16591f0194739e7deb12099d3e98e60b7f3
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c be22ec05c8c4a43a95a6ad3b8068542200451e07
 F src/sqlite.h.in 0fdf9ac32584cb4b361feb81bfabfe794f95e467
@@ -183,7 +183,7 @@ F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
 F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
 F src/vdbemem.c 237e61216381998ff71c6431e5e7bd03386f6225
 F src/vtab.c f5e78bf73df3b0c1b53861109c1b2e0800b108cc
-F src/where.c a686f1e04f1ce5515a801fb3f3a358ef2cbb6ed2
+F src/where.c 4835f36ba01f663794b96131b81a1ca43ac239fa
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test d56a3ca8acdf761204aff0a2e7aa5eb8e11b31e6
@@ -458,7 +458,7 @@ F test/tableapi.test 791f7e3891d9b70bdb43b311694bf5e9befcbc34
 F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
 F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
 F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
-F test/tester.tcl 93b57b686ad5a9d9cafaa86c7c231f773e52931b
+F test/tester.tcl 72e180cc91fae17fd6ea43d1cd84558421105b72
 F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
 F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
@@ -544,10 +544,10 @@ F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
 F test/vtab_shared.test c19b2555b807ef2ee014c882cdda5bc8d84fcf48
 F test/where.test 5ff4a1bda6352b73354faf1a97706bbfa0d47dfe
 F test/where2.test 7012c0ad022a54430dd22c98288d3f4d6599dbcf
-F test/where3.test 0a30fe9808b0fa01c46d0fcf4fac0bf6cf75bb30
+F test/where3.test 97d3936e6a443b968f1a61cdcc0f673252000e94
 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
-F test/where6.test 81e93cc92f08379f4ade484956c0be622b72bda3
+F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf
 F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
@@ -631,7 +631,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 8eaa0c71023ac428f6f9f8091341584caa773ab9
-R 1dd42524c80ac311255ad8c1673ca3df
+P 79571e2c74fa365b7f471428c48e1678375b8c9d
+R 520ded2b9978aef5a40facaf74c1da68
 U drh
-Z d55eeb25ddd3a6c6f8140d6c3c307d8a
+Z 73173026efe001e86c69d0ed8d1aa811
index 9d17f704be2c929693d3dacec3d0522c70fe19e3..ebcdda239484d042648c7c3a482e39e4458681c1 100644 (file)
@@ -1 +1 @@
-79571e2c74fa365b7f471428c48e1678375b8c9d
\ No newline at end of file
+0d2e258e1a3276e55903ba2ded987f8d8a18cacd
\ No newline at end of file
index 4b9f1dfd9657a9a5c94df9a0b98ee4f801937269..4c9a01ea894467db0cafa4b8d3e8cc84cf91dfa7 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.427 2008/04/15 12:14:22 drh Exp $
+** $Id: select.c,v 1.428 2008/04/17 19:14:02 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -3653,7 +3653,7 @@ select_end:
 ** code base.  Then are intended to be called from within the debugger
 ** or from temporary "printf" statements inserted for debugging.
 */
-static void sqlite3PrintExpr(Expr *p){
+void sqlite3PrintExpr(Expr *p){
   if( p->token.z && p->token.n>0 ){
     sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
   }else{
@@ -3669,7 +3669,7 @@ static void sqlite3PrintExpr(Expr *p){
   }
   sqlite3DebugPrintf(")");
 }
-static void sqlite3PrintExprList(ExprList *pList){
+void sqlite3PrintExprList(ExprList *pList){
   int i;
   for(i=0; i<pList->nExpr; i++){
     sqlite3PrintExpr(pList->a[i].pExpr);
@@ -3678,7 +3678,7 @@ static void sqlite3PrintExprList(ExprList *pList){
     }
   }
 }
-static void sqlite3PrintSelect(Select *p, int indent){
+void sqlite3PrintSelect(Select *p, int indent){
   sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
   sqlite3PrintExprList(p->pEList);
   sqlite3DebugPrintf("\n");
index 4bdb26929501936f8841bd070cffa239efbd38d7..3b7df014e409f8f00a0d28d0628d75d7a6627701 100644 (file)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.298 2008/04/10 13:33:18 drh Exp $
+** $Id: where.c,v 1.299 2008/04/17 19:14:02 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -718,6 +718,7 @@ static void exprAnalyze(
   Expr *pExpr;
   Bitmask prereqLeft;
   Bitmask prereqAll;
+  Bitmask extraRight = 0;
   int nPattern;
   int isComplete;
   int noCase;
@@ -746,8 +747,8 @@ static void exprAnalyze(
   if( ExprHasProperty(pExpr, EP_FromJoin) ){
     Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable);
     prereqAll |= x;
-    pTerm->prereqRight |= x-1; /* ON clause terms may not be used with an index
-                               ** on left table of a LEFT JOIN.  Ticket #3015 */
+    extraRight = x-1;  /* ON clause terms may not be used with an index
+                       ** on left table of a LEFT JOIN.  Ticket #3015 */
   }
   pTerm->prereqAll = prereqAll;
   pTerm->leftCursor = -1;
@@ -976,6 +977,11 @@ or_not_possible:
     }
   }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
+  ** an index for tables to the left of the join.
+  */
+  pTerm->prereqRight |= extraRight;
 }
 
 /*
index 5fd9d3578210614bdc56daae9827b9c375b0f951..47cb1a77e4d3844979a027f0458f71e70f18cf9e 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.115 2008/04/15 02:36:34 drh Exp $
+# $Id: tester.tcl,v 1.116 2008/04/17 19:14:02 drh Exp $
 
 #
 # What for user input before continuing.  This gives an opportunity
@@ -369,6 +369,15 @@ proc explain {sql {db db}} {
   }
 }
 
+# Show the VDBE program for an SQL statement but omit the Trace
+# opcode at the beginning.  This procedure can be used to prove
+# that different SQL statements generate exactly the same VDBE code.
+#
+proc explain_no_trace {sql} {
+  set tr [db eval "EXPLAIN $sql"]
+  return [lrange $tr 7 end]
+}
+
 # Another procedure to execute SQL.  This one includes the field
 # names in the returned list.
 #
index 30e0976e807bb70cdc58accd645c97f5ca53e3ce..c395d0ac151716de37045fc57ce6d97fd2a3f9e8 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing the join reordering optimization
 # in cases that include a LEFT JOIN.
 #
-# $Id: where3.test,v 1.3 2006/12/16 16:25:17 drh Exp $
+# $Id: where3.test,v 1.4 2008/04/17 19:14:02 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -45,6 +45,14 @@ do_test where3-1.1 {
   }
 } {222 two 2 222 {} {}}
 
+ifcapable explain {
+  do_test where3-1.1.1 {
+     explain_no_trace {SELECT * FROM t1, t2 LEFT JOIN t3 ON q=x
+                        WHERE p=2 AND a=q}
+  } [explain_no_trace {SELECT * FROM t1, t2 LEFT JOIN t3 ON x=q
+                        WHERE p=2 AND a=q}]
+}
+
 # Ticket #1830
 #
 # This is similar to the above but with the LEFT JOIN on the
@@ -78,6 +86,22 @@ do_test where3-1.2 {
   }
 } {1 {Value for C1.1} {Value for C2.1} 2 {} {Value for C2.2} 3 {Value for C1.3} {Value for C2.3}}
 
+ifcapable explain {
+  do_test where3-1.2.1 {
+     explain_no_trace {
+       SELECT parent1.parent1key, child1.value, child2.value
+       FROM parent1
+       LEFT OUTER JOIN child1 ON child1.child1key = parent1.child1key
+       INNER JOIN child2 ON child2.child2key = parent1.child2key;
+     }
+  } [explain_no_trace {
+       SELECT parent1.parent1key, child1.value, child2.value
+       FROM parent1
+       LEFT OUTER JOIN child1 ON parent1.child1key = child1.child1key 
+       INNER JOIN child2 ON child2.child2key = parent1.child2key;
+     }]
+}
+
 # This procedure executes the SQL.  Then it appends 
 # the ::sqlite_query_plan variable.
 #
@@ -121,6 +145,36 @@ do_test where3-2.1 {
      WHERE cpk=bx AND bpk=ax
   }
 } {tA {} tB * tC * tD *}
+do_test where3-2.1.1 {
+  queryplan {
+    SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
+     WHERE cpk=bx AND bpk=ax
+  }
+} {tA {} tB * tC * tD *}
+do_test where3-2.1.2 {
+  queryplan {
+    SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
+     WHERE bx=cpk AND bpk=ax
+  }
+} {tA {} tB * tC * tD *}
+do_test where3-2.1.3 {
+  queryplan {
+    SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
+     WHERE bx=cpk AND ax=bpk
+  }
+} {tA {} tB * tC * tD *}
+do_test where3-2.1.4 {
+  queryplan {
+    SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
+     WHERE bx=cpk AND ax=bpk
+  }
+} {tA {} tB * tC * tD *}
+do_test where3-2.1.5 {
+  queryplan {
+    SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
+     WHERE cpk=bx AND ax=bpk
+  }
+} {tA {} tB * tC * tD *}
 do_test where3-2.2 {
   queryplan {
     SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
index 2e803b17aa0dd028357104396094c1700b121eb6..bcea6540a5f4f3fd8082dd3f9d9fc9c5e25e1444 100644 (file)
 # focus of this file is testing that terms in the ON clause of
 # a LEFT OUTER JOIN are not used with indices.  See ticket #3015.
 #
-# $Id: where6.test,v 1.1 2008/03/26 14:56:35 drh Exp $
+# $Id: where6.test,v 1.2 2008/04/17 19:14:02 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
 # Build some test data
 #
-do_test where6-1.0 {
+do_test where6-1.1 {
   execsql {
     CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c);
     INSERT INTO t1 VALUES(1,3,1);
@@ -30,22 +30,101 @@ do_test where6-1.0 {
     SELECT * FROM t1 LEFT JOIN t2 ON b=x AND c=1;
   }
 } {1 3 1 3 2 4 2 {}}
-do_test where6-1.1 {
+do_test where6-1.2 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b AND c=1;
+  }
+} {1 3 1 3 2 4 2 {}}
+do_test where6-1.3 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b AND 1=c;
+  }
+} {1 3 1 3 2 4 2 {}}
+do_test where6-1.4 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON b=x AND 1=c;
+  }
+} {1 3 1 3 2 4 2 {}}
+
+ifcapable explain {
+  do_test where6-1.5 {
+     explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON x=b AND 1=c}
+  } [explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON b=x AND c=1}]
+  do_test where6-1.6 {
+     explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON x=b WHERE 1=c}
+  } [explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1}]
+}
+
+do_test where6-1.11 {
   execsql {
     SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1;
   }
 } {1 3 1 3}
-do_test where6-1.2 {
+do_test where6-1.12 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b WHERE c=1;
+  }
+} {1 3 1 3}
+do_test where6-1.13 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE 1=c;
+  }
+} {1 3 1 3}
+
+
+
+do_test where6-2.1 {
   execsql {
     CREATE INDEX i1 ON t1(c);
 
     SELECT * FROM t1 LEFT JOIN t2 ON b=x AND c=1;
   }
 } {1 3 1 3 2 4 2 {}}
-do_test where6-1.3 {
+do_test where6-2.2 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b AND c=1;
+  }
+} {1 3 1 3 2 4 2 {}}
+do_test where6-2.3 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b AND 1=c;
+  }
+} {1 3 1 3 2 4 2 {}}
+do_test where6-2.4 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON b=x AND 1=c;
+  }
+} {1 3 1 3 2 4 2 {}}
+
+ifcapable explain {
+  do_test where6-2.5 {
+     explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON x=b AND 1=c}
+  } [explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON b=x AND c=1}]
+  do_test where6-2.6 {
+     explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON x=b WHERE 1=c}
+  } [explain_no_trace {SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1}]
+}
+
+
+do_test where6-2.11 {
   execsql {
     SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1;
   }
 } {1 3 1 3}
+do_test where6-2.12 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b WHERE c=1;
+  }
+} {1 3 1 3}
+do_test where6-2.13 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON x=b WHERE 1=c;
+  }
+} {1 3 1 3}
+do_test where6-2.14 {
+  execsql {
+    SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE 1=c;
+  }
+} {1 3 1 3}
 
 finish_test