diff options
author | drh <> | 2023-05-01 11:24:35 +0000 |
---|---|---|
committer | drh <> | 2023-05-01 11:24:35 +0000 |
commit | 908dec740443f3253ca74a325c17d8fc36c8a046 (patch) | |
tree | 52b122b88065a4eef59bcfce5c28a63620e98d10 /src/expr.c | |
parent | e01e3b5b9491759108c205d2fe6c1b1c1be60120 (diff) | |
download | sqlite-908dec740443f3253ca74a325c17d8fc36c8a046.tar.gz sqlite-908dec740443f3253ca74a325c17d8fc36c8a046.zip |
Do not apply the "AND false" optimization if either operand comes from the
ON clause of a join. Fix for the problem identified by
[forum:/forumpost/96cd4a7e9e|forum post 96cd4a7e9e].
FossilOrigin-Name: d095da0e7a24e3bcab6495d964f76a86d7a5910d2d6edddc6e8092bfa6084fe6
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/expr.c b/src/expr.c index ebaf13af1..9ffc3bade 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1113,9 +1113,9 @@ Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){ ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. ** -** If one side or the other of the AND is known to be false, then instead -** of returning an AND expression, just return a constant expression with -** a value of false. +** If one side or the other of the AND is known to be false, and neither side +** is part of an ON clause, then instead of returning an AND expression, +** just return a constant expression with a value of false. */ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ sqlite3 *db = pParse->db; @@ -1123,14 +1123,17 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ return pRight; }else if( pRight==0 ){ return pLeft; - }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) - && !IN_RENAME_OBJECT - ){ - sqlite3ExprDeferredDelete(pParse, pLeft); - sqlite3ExprDeferredDelete(pParse, pRight); - return sqlite3Expr(db, TK_INTEGER, "0"); }else{ - return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); + u32 f = pLeft->flags | pRight->flags; + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse + && !IN_RENAME_OBJECT + ){ + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3Expr(db, TK_INTEGER, "0"); + }else{ + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); + } } } |