Partial fix for a problem with LEFT OUTER JOIN. It used to be that the test
for the right-hand table not matching the left table occurred after all ON, USING, WHERE clause processing. The test should occur after ON and USING clauses are checked but before the WHERE clause is check. This fix works as long as the total number of "AND" separated terms in the ON, USING, and WHERE clause does not exceed 32. To do: make this work for any number of terms and add test cases. that (CVS 639) FossilOrigin-Name: 8b6574cfa86daaae910f8f3ee3c4723a21fb9e53
This commit is contained in:
parent
bf5cd97ed7
commit
1cc093c2b5
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sVDBE\sstack\sleak\sin\sLEFT\sOUTER\sJOIN.\s\sFix\sa\sbug\sin\sthe\scode\sgenerator\nfor\sJOIN\s...\sUSING(...).\s(CVS\s638)
|
||||
D 2002-06-24T12:20:23
|
||||
C Partial\sfix\sfor\sa\sproblem\swith\sLEFT\sOUTER\sJOIN.\s\sIt\sused\sto\sbe\sthat\sthe\stest\nfor\sthe\sright-hand\stable\snot\smatching\sthe\sleft\stable\soccurred\safter\sall\nON,\sUSING,\sWHERE\sclause\sprocessing.\s\sThe\stest\sshould\soccur\safter\sON\sand\nUSING\sclauses\sare\schecked\sbut\sbefore\sthe\sWHERE\sclause\sis\scheck.\s\sThis\sfix\nworks\sas\slong\sas\sthe\stotal\snumber\sof\s"AND"\sseparated\sterms\sin\sthe\sON,\sUSING,\nand\sWHERE\sclause\sdoes\snot\sexceed\s32.\s\sTo\sdo:\smake\sthis\swork\sfor\sany\snumber\nof\sterms\sand\sadd\stest\scases.\nthat\s(CVS\s639)
|
||||
D 2002-06-24T22:01:58
|
||||
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
|
||||
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
|
||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||
@ -37,11 +37,11 @@ F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
|
||||
F src/parse.y 2285d8967d7334d52a2188089e5a881d73ba56f6
|
||||
F src/printf.c 236ed7a79386feed4456fa728fff8be793f1547c
|
||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||
F src/select.c 3e83a18baeeb5c89936ca84bde0bb0d18709b6b5
|
||||
F src/select.c f7d74f20f5ecc335fbccba367eda727b9d6fb299
|
||||
F src/shell.c 1d22fe870ee852cfb975fd000dbe3973713d0a15
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in 7c8882e352cb70818cfaf9bdb5b1b3bee81ef144
|
||||
F src/sqliteInt.h 2f7b1f4d5062a17dfd75caa5639360c76881d5b2
|
||||
F src/sqliteInt.h d3c1448890ba65e6be381b50b7e7ce7fca142322
|
||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||
F src/tclsqlite.c 9300c9606a38bc0c75d6c0bc8a6197ab979353d1
|
||||
F src/test1.c 5cc4f0bbf38237e04e1b2077e285b41bfb4c4cbf
|
||||
@ -54,7 +54,7 @@ F src/update.c 6f6a4dcd71cd9ff730b7f12c83de5498cde4924f
|
||||
F src/util.c 876b259f9186e84b944b72e793dd3dad50e63e95
|
||||
F src/vdbe.c 774f79483ce809b27c3bdb02afd7295cc3c7acd4
|
||||
F src/vdbe.h a9292f2b5fcecef924fa255fb74609e9cbc776c2
|
||||
F src/where.c 5ff862869a8ab704070df2ef75a3424c782422cf
|
||||
F src/where.c 259d7fb77191b13718c271926b7c14afbbe7346b
|
||||
F test/all.test e4d3821eeba751829b419cd47814bd20af4286d1
|
||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||
F test/btree.test bf326f546a666617367a7033fa2c07451bd4f8e1
|
||||
@ -137,7 +137,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
|
||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P 8aa73ce61268a50d353d9a5c878461290195525f
|
||||
R 2b416ef8a3e6fcbc67f7c234a7a7ee0f
|
||||
P d861489e1f7dffd1105c271fe8597f73e5b1703c
|
||||
R d718b83d86c9331bc69c93f673a44be9
|
||||
U drh
|
||||
Z f4ef2a81bcc41a1ff76332fb25825e47
|
||||
Z b9b5d0f63e47642b79ff89410dec8a4b
|
||||
|
@ -1 +1 @@
|
||||
d861489e1f7dffd1105c271fe8597f73e5b1703c
|
||||
8b6574cfa86daaae910f8f3ee3c4723a21fb9e53
|
19
src/select.c
19
src/select.c
@ -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.98 2002/06/24 12:20:23 drh Exp $
|
||||
** $Id: select.c,v 1.99 2002/06/24 22:01:58 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -167,6 +167,7 @@ static void addWhereTerm(
|
||||
pE1c = sqliteExpr(TK_DOT, pE1b, pE1a, 0);
|
||||
pE2c = sqliteExpr(TK_DOT, pE2b, pE2a, 0);
|
||||
pE = sqliteExpr(TK_EQ, pE1c, pE2c, 0);
|
||||
pE->isJoinExpr = 1;
|
||||
if( *ppExpr ){
|
||||
*ppExpr = sqliteExpr(TK_AND, *ppExpr, pE, 0);
|
||||
}else{
|
||||
@ -174,6 +175,21 @@ static void addWhereTerm(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the Expr.isJoinExpr flag on all terms of the given expression.
|
||||
**
|
||||
** The Expr.isJoinExpr flag is used at on terms of an expression to tell
|
||||
** the LEFT OUTER JOIN processing logic that this term is part of the
|
||||
** join restriction and not a part of the more general WHERE clause.
|
||||
*/
|
||||
static void setJoinExpr(Expr *p){
|
||||
while( p ){
|
||||
p->isJoinExpr = 1;
|
||||
setJoinExpr(p->pLeft);
|
||||
p = p->pRight;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine processes the join information for a SELECT statement.
|
||||
** ON and USING clauses are converted into extra terms of the WHERE clause.
|
||||
@ -223,6 +239,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
|
||||
** and AND operator.
|
||||
*/
|
||||
if( pTerm->pOn ){
|
||||
setJoinExpr(pTerm->pOn);
|
||||
if( p->pWhere==0 ){
|
||||
p->pWhere = pTerm->pOn;
|
||||
}else{
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.129 2002/06/22 02:33:39 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.130 2002/06/24 22:01:58 drh Exp $
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include "hash.h"
|
||||
@ -436,8 +436,9 @@ struct Token {
|
||||
** operand.
|
||||
*/
|
||||
struct Expr {
|
||||
u16 op; /* Operation performed by this node */
|
||||
u8 op; /* Operation performed by this node */
|
||||
u8 dataType; /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */
|
||||
u8 isJoinExpr; /* Origina is the ON or USING phrase of a join */
|
||||
Expr *pLeft, *pRight; /* Left and right subnodes */
|
||||
ExprList *pList; /* A list of expressions used as function arguments
|
||||
** or in "<expr> IN (<expr-list)" */
|
||||
|
13
src/where.c
13
src/where.c
@ -13,7 +13,7 @@
|
||||
** the WHERE clause of SQL statements. Also found here are subroutines
|
||||
** to generate VDBE code to evaluate expressions.
|
||||
**
|
||||
** $Id: where.c,v 1.54 2002/06/24 12:20:23 drh Exp $
|
||||
** $Id: where.c,v 1.55 2002/06/24 22:01:59 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -1007,6 +1007,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
for(j=0; j<nExpr; j++){
|
||||
if( aExpr[j].p==0 ) continue;
|
||||
if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
|
||||
if( pLevel->iLeftJoin && aExpr[j].p->isJoinExpr==0 ) continue;
|
||||
if( haveKey ){
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||
@ -1023,6 +1024,16 @@ WhereInfo *sqliteWhereBegin(
|
||||
pLevel->top = sqliteVdbeCurrentAddr(v);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||
for(j=0; j<nExpr; j++){
|
||||
if( aExpr[j].p==0 ) continue;
|
||||
if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
|
||||
if( haveKey ){
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||
}
|
||||
sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
|
||||
aExpr[j].p = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pWInfo->iContinue = cont;
|
||||
|
Loading…
Reference in New Issue
Block a user