aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2023-05-01 11:24:35 +0000
committerdrh <>2023-05-01 11:24:35 +0000
commit908dec740443f3253ca74a325c17d8fc36c8a046 (patch)
tree52b122b88065a4eef59bcfce5c28a63620e98d10 /src/expr.c
parente01e3b5b9491759108c205d2fe6c1b1c1be60120 (diff)
downloadsqlite-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.c23
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);
+ }
}
}