diff options
author | drh <drh@noemail.net> | 2007-06-08 00:20:47 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2007-06-08 00:20:47 +0000 |
commit | 0a168377ada98befc52a3dfedadc803804b50450 (patch) | |
tree | 6bb6b34a0d957e5ecdd7bae413072e4649a928a6 /src/expr.c | |
parent | 98640a3fa16a0501fe4251b144f46ad01651be89 (diff) | |
download | sqlite-0a168377ada98befc52a3dfedadc803804b50450.tar.gz sqlite-0a168377ada98befc52a3dfedadc803804b50450.zip |
Fix the query optimizer so that it correctly handles constant expressions
in the ON clause of a LEFT JOIN. Ticket #2403. (CVS 4049)
FossilOrigin-Name: 46fdd195483787eef209a9b8ad108eba147be6fa
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c index a6c53ee21..5c48c0b5e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.296 2007/05/30 10:36:47 danielk1977 Exp $ +** $Id: expr.c,v 1.297 2007/06/08 00:20:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -831,11 +831,21 @@ static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ ** is constant. See sqlite3ExprIsConstant() for additional information. */ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ + int *pN = (int*)pArg; + + /* If *pArg is 3 then any term of the expression that comes from + ** the ON or USING clauses of a join disqualifies the expression + ** from being considered constant. */ + if( (*pN)==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){ + *pN = 0; + return 2; + } + switch( pExpr->op ){ /* Consider functions to be constant if all their arguments are constant ** and *pArg==2 */ case TK_FUNCTION: - if( *((int*)pArg)==2 ) return 0; + if( (*pN)==2 ) return 0; /* Fall through */ case TK_ID: case TK_COLUMN: @@ -846,11 +856,11 @@ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ case TK_SELECT: case TK_EXISTS: #endif - *((int*)pArg) = 0; + *pN = 0; return 2; case TK_IN: if( pExpr->pSelect ){ - *((int*)pArg) = 0; + *pN = 0; return 2; } default: @@ -874,6 +884,18 @@ int sqlite3ExprIsConstant(Expr *p){ /* ** Walk an expression tree. Return 1 if the expression is constant +** that does no originate from the ON or USING clauses of a join. +** Return 0 if it involves variables or function calls or terms from +** an ON or USING clause. +*/ +int sqlite3ExprIsConstantNotJoin(Expr *p){ + int isConst = 3; + walkExprTree(p, exprNodeIsConstant, &isConst); + return isConst!=0; +} + +/* +** Walk an expression tree. Return 1 if the expression is constant ** or a function call with constant arguments. Return and 0 if there ** are any variables. ** |