From: drh Date: Mon, 19 Jul 2004 19:30:50 +0000 (+0000) Subject: Fix for ticket #813. (CVS 1820) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8734da09bfb47e8f8f27e6ce745f98fb192a18f;p=thirdparty%2Fsqlite.git Fix for ticket #813. (CVS 1820) FossilOrigin-Name: 0cc612f8aa458034d3dc246861c529c57ac5b2b1 --- diff --git a/manifest b/manifest index 499020edbb..35251f5b46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\shandle\sjoins\sof\smove\sthan\s32\stables.\s\sTicket\s#806.\s(CVS\s1813) -D 2004-07-19T02:24:03 +C Fix\sfor\sticket\s#813.\s(CVS\s1820) +D 2004-07-19T19:30:50 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -61,11 +61,11 @@ F src/trigger.c a9927b57c865b6f3df3fb5e40c9824d722660ded F src/update.c bd391079138e67d09c9af34528ca4137c29242d1 F src/util.c 48f1e99803e924433477a7ccbdab35663acb621d F src/vacuum.c 36a19aa877c696c4ec8b78300c19f4059d2617a7 -F src/vdbe.c 0853ab9983b7adbba8c012bb8b152d8453bf8a97 +F src/vdbe.c 4b35f2c1a5b3500ac8969ce8655ec2b806284d29 F src/vdbe.h ac987945e4dd6f987bca534c6005899f089fc270 F src/vdbeInt.h b40ff02ce39fd076e6ff3369e19c1bbfe1986682 F src/vdbeaux.c 14ff0eb6ed9d5998f927433c91b0a3d13d81f4f6 -F src/where.c 3a85d88ec1447bda08d6a7a90d763dd6a0ceddcf +F src/where.c ce4968e37382808ec76a47385384ee21ad9e979e F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test ba8261d38da6b6a7d4f78ec543c548c4418582ef F test/attach2.test ce61e6185b3cd891cc0e9a4c868fcc65eb92fc55 @@ -131,7 +131,7 @@ F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4 F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1 -F test/tclsqlite.test a684fc191b81e6cded8a81263663d5a130fbb013 +F test/tclsqlite.test 109ed5fbfe23e24f49eff6984dfa8a6bed8b5281 F test/temptable.test a770ba6308d7f7332fce985086b8e06bed6430c2 F test/tester.tcl 2f1d43df1311c9dc06acaa7a82e87bfea85dea5f F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6 @@ -189,7 +189,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P f9b2aa8f8a6c0a7f74af2844a80fe14b85d05a45 -R 7602201687962f870e55ba293d7c4589 +P 5ba0acd6c788b6ec07b29dc40c17265f8fb8a337 +R 04b738396073cd6e3f5def26476223ed U drh -Z 66fa816cf92b236bf8ebf0582e88ba0f +Z e025b922d80b327cd770a3f0a861e529 diff --git a/manifest.uuid b/manifest.uuid index a07fa6b7e7..2d705777d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ba0acd6c788b6ec07b29dc40c17265f8fb8a337 \ No newline at end of file +0cc612f8aa458034d3dc246861c529c57ac5b2b1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 28761d3009..d2cf7a585f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.268.2.2 2004/05/10 20:27:41 drh Exp $ +** $Id: vdbe.c,v 1.268.2.3 2004/07/19 19:30:50 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -4695,8 +4695,9 @@ case OP_SetNext: { break; } }else{ - assert( pSet->prev ); - pSet->prev = sqliteHashNext(pSet->prev); + if( pSet->prev ){ + pSet->prev = sqliteHashNext(pSet->prev); + } if( pSet->prev==0 ){ break; }else{ diff --git a/src/where.c b/src/where.c index 5db5f90169..52761d0820 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.89.2.1 2004/07/19 02:24:03 drh Exp $ +** $Id: where.c,v 1.89.2.2 2004/07/19 19:30:50 drh Exp $ */ #include "sqliteInt.h" @@ -271,6 +271,35 @@ static Index *findSortingIndex( return pMatch; } +/* +** Disable a term in the WHERE clause. Except, do not disable the term +** if it controls a LEFT OUTER JOIN and it did not originate in the ON +** or USING clause of that join. +** +** Consider the term t2.z='ok' in the following queries: +** +** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' +** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' +** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' +** +** The t2.z='ok' is disabled in the in (2) because it did not originate +** in the ON clause. The term is disabled in (3) because it is not part +** of a LEFT OUTER JOIN. In (1), the term is not disabled. +** +** Disabling a term causes that term to not be tested in the inner loop +** of the join. Disabling is an optimization. We would get the correct +** results if nothing were ever disabled, but joins might run a little +** slower. The trick is to disable as much as we can without disabling +** too much. If we disabled in (1), we'd get the wrong answer. +** See ticket #813. +*/ +static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){ + Expr *pExpr = *ppExpr; + if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){ + *ppExpr = 0; + } +} + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an (opaque) structure that contains @@ -738,7 +767,7 @@ WhereInfo *sqliteWhereBegin( }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); cont = pLevel->cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); haveKey = 0; @@ -762,7 +791,7 @@ WhereInfo *sqliteWhereBegin( ){ if( pX->op==TK_EQ ){ sqliteExprCode(pParse, pX->pRight); - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } if( pX->op==TK_IN && nColumn==1 ){ @@ -779,7 +808,7 @@ WhereInfo *sqliteWhereBegin( pLevel->inOp = OP_Next; pLevel->inP1 = pX->iTable; } - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } } @@ -789,7 +818,7 @@ WhereInfo *sqliteWhereBegin( && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] ){ sqliteExprCode(pParse, aExpr[k].p->pLeft); - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } } @@ -856,7 +885,7 @@ WhereInfo *sqliteWhereBegin( sqliteVdbeAddOp(v, OP_ForceInt, aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk); sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk); - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); }else{ sqliteVdbeAddOp(v, OP_Rewind, iCur, brk); } @@ -878,7 +907,7 @@ WhereInfo *sqliteWhereBegin( }else{ testOp = OP_Gt; } - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); } start = sqliteVdbeCurrentAddr(v); pLevel->op = OP_Next; @@ -933,7 +962,7 @@ WhereInfo *sqliteWhereBegin( && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j] ){ sqliteExprCode(pParse, aExpr[k].p->pRight); - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } if( aExpr[k].idxRight==iCur @@ -942,7 +971,7 @@ WhereInfo *sqliteWhereBegin( && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j] ){ sqliteExprCode(pParse, aExpr[k].p->pLeft); - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } } @@ -979,7 +1008,7 @@ WhereInfo *sqliteWhereBegin( ){ sqliteExprCode(pParse, pExpr->pRight); leFlag = pExpr->op==TK_LE; - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } if( aExpr[k].idxRight==iCur @@ -989,7 +1018,7 @@ WhereInfo *sqliteWhereBegin( ){ sqliteExprCode(pParse, pExpr->pLeft); leFlag = pExpr->op==TK_GE; - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } } @@ -1038,7 +1067,7 @@ WhereInfo *sqliteWhereBegin( ){ sqliteExprCode(pParse, pExpr->pRight); geFlag = pExpr->op==TK_GE; - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } if( aExpr[k].idxRight==iCur @@ -1048,7 +1077,7 @@ WhereInfo *sqliteWhereBegin( ){ sqliteExprCode(pParse, pExpr->pLeft); geFlag = pExpr->op==TK_LE; - aExpr[k].p = 0; + disableTerm(pLevel, &aExpr[k].p); break; } } diff --git a/test/tclsqlite.test b/test/tclsqlite.test index ecaf2a921f..661b45877c 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -15,7 +15,7 @@ # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # -# $Id: tclsqlite.test,v 1.20 2004/02/25 22:51:06 rdc Exp $ +# $Id: tclsqlite.test,v 1.20.2.1 2004/07/19 19:30:50 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -72,6 +72,7 @@ do_test tcl-1.6 { } {1 {syntax error in expression "x*"}} if {[sqlite -encoding]=="UTF-8" && [sqlite -tcl-uses-utf]} { + catch {unset ::result} do_test tcl-2.1 { execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)" execsql "PRAGMA table_info(t\u0123x)"