-C Comment\schange\son\sthe\sprevious\scheck-in.\s\sNo\schanges\sto\scode.\s(CVS\s4918)
-D 2008-03-26T12:50:15
+C Make\ssure\sON\sclause\sterms\sof\sa\sLEFT\sJOIN\sare\snot\sused\swith\san\sindex\son\sthe\nright\stable\sof\sthe\sjoin.\s\sTicket\s#3015.\s(CVS\s4919)
+D 2008-03-26T14:56:35
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
F src/vdbemem.c d48a71d66a7afd564b6537ab7e7442f7729fa5af
F src/vtab.c 00cd16317b29495c185ff40e4b227917d5a371b2
-F src/where.c f18bac2f87c965811727be1be05deeaf5229fcd0
+F src/where.c 7aeeec6731dc2f423e6a77ff2964bc3c38985625
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/all.test d12210212bada2bde6d5aeb90969b86c1aa977d2
F test/where3.test 0a30fe9808b0fa01c46d0fcf4fac0bf6cf75bb30
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
+F test/where6.test 81e93cc92f08379f4ade484956c0be622b72bda3
F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 50de87dc808820a70d3a99277f532e418a2f97e2
-R a9214388e1bd4f84433e05f4820411e2
+P 72ae456239eb9f75b744f6733c4441b380bd1be1
+R 9d9078dbdb76203a989a8fc288298d2a
U drh
-Z 2631d714b3b1ed6116e6910f891b739c
+Z 23ccaa57eab8690967dced96f6c90551
-72ae456239eb9f75b744f6733c4441b380bd1be1
\ No newline at end of file
+3fafa562593b51d38f58e7a691c193d34a812a05
\ No newline at end of file
** 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.291 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: where.c,v 1.292 2008/03/26 14:56:35 drh Exp $
*/
#include "sqliteInt.h"
}
prereqAll = exprTableUsage(pMaskSet, pExpr);
if( ExprHasProperty(pExpr, EP_FromJoin) ){
- prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable);
+ 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 */
}
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
pWhere = 0;
}
+ /* Assign a bit from the bitmask to every term in the FROM clause.
+ **
+ ** When assigning bitmask values to FROM clause cursors, it must be
+ ** the case that if X is the bitmask for the N-th FROM clause term then
+ ** the bitmask for all FROM clause terms to the left of the N-th term
+ ** is (X-1). An expression from the ON clause of a LEFT JOIN can use
+ ** its Expr.iRightJoinTable value to find the bitmask of the right table
+ ** of the join. Subtracting one from the right table bitmask gives a
+ ** bitmask for all tables to the left of the join. Knowing the bitmask
+ ** for all tables to the left of a left join is important. Ticket #3015.
+ */
+ for(i=0; i<pTabList->nSrc; i++){
+ createMask(&maskSet, pTabList->a[i].iCursor);
+ }
+#ifndef NDEBUG
+ {
+ Bitmask toTheLeft = 0;
+ for(i=0; i<pTabList->nSrc; i++){
+ Bitmask m = getMask(&maskSet, pTabList->a[i].iCursor);
+ assert( (m-1)==toTheLeft );
+ toTheLeft |= m;
+ }
+ }
+#endif
+
/* Analyze all of the subexpressions. Note that exprAnalyze() might
** add new virtual terms onto the end of the WHERE clause. We do not
** want to analyze these virtual terms, so start analyzing at the end
** and work forward so that the added virtual terms are never processed.
*/
- for(i=0; i<pTabList->nSrc; i++){
- createMask(&maskSet, pTabList->a[i].iCursor);
- }
exprAnalyzeAll(pTabList, &wc);
if( db->mallocFailed ){
goto whereBeginNoMem;
--- /dev/null
+# 2007 June 8
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# 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 $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Build some test data
+#
+do_test where6-1.0 {
+ execsql {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c);
+ INSERT INTO t1 VALUES(1,3,1);
+ INSERT INTO t1 VALUES(2,4,2);
+ CREATE TABLE t2(x INTEGER PRIMARY KEY);
+ INSERT INTO t2 VALUES(3);
+
+ SELECT * FROM t1 LEFT JOIN t2 ON b=x AND c=1;
+ }
+} {1 3 1 3 2 4 2 {}}
+do_test where6-1.1 {
+ execsql {
+ SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1;
+ }
+} {1 3 1 3}
+do_test where6-1.2 {
+ 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 {
+ execsql {
+ SELECT * FROM t1 LEFT JOIN t2 ON b=x WHERE c=1;
+ }
+} {1 3 1 3}
+
+finish_test