Make sure ON clause terms of a LEFT JOIN are not used with an index on the
right table of the join. Ticket #3015. (CVS 4919) FossilOrigin-Name: 3fafa562593b51d38f58e7a691c193d34a812a05
This commit is contained in:
parent
995ae279b3
commit
42165be18c
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
||||
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
|
||||
@ -183,7 +183,7 @@ F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
|
||||
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
|
||||
@ -537,6 +537,7 @@ F test/where2.test 7012c0ad022a54430dd22c98288d3f4d6599dbcf
|
||||
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
|
||||
@ -617,7 +618,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
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
|
||||
|
@ -1 +1 @@
|
||||
72ae456239eb9f75b744f6733c4441b380bd1be1
|
||||
3fafa562593b51d38f58e7a691c193d34a812a05
|
35
src/where.c
35
src/where.c
@ -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.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"
|
||||
|
||||
@ -743,7 +743,10 @@ static void exprAnalyze(
|
||||
}
|
||||
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;
|
||||
@ -2043,14 +2046,36 @@ WhereInfo *sqlite3WhereBegin(
|
||||
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;
|
||||
|
51
test/where6.test
Normal file
51
test/where6.test
Normal file
@ -0,0 +1,51 @@
|
||||
# 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
|
Loading…
Reference in New Issue
Block a user