-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
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
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
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
-d861489e1f7dffd1105c271fe8597f73e5b1703c
\ No newline at end of file
+8b6574cfa86daaae910f8f3ee3c4723a21fb9e53
\ No newline at end of file
** 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"
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{
}
}
+/*
+** 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.
** and AND operator.
*/
if( pTerm->pOn ){
+ setJoinExpr(pTerm->pOn);
if( p->pWhere==0 ){
p->pWhere = pTerm->pOn;
}else{
*************************************************************************
** 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"
** 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)" */
** 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"
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);
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;