1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Use macros to determine if an expression is always true or always false.

FossilOrigin-Name: 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc
This commit is contained in:
drh
2019-04-19 16:21:51 +00:00
parent d5c851c1cb
commit ad31727fc6
4 changed files with 19 additions and 41 deletions

View File

@@ -773,7 +773,7 @@ Expr *sqlite3ExprAlloc(
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue|EP_Leaf;
pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
@@ -880,33 +880,6 @@ void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
}
/*
** If the expression is always either TRUE or FALSE (respectively),
** then return 1. If one cannot determine the truth value of the
** expression at compile-time return 0.
**
** This is an optimization. If is OK to return 0 here even if
** the expression really is always false or false (a false negative).
** But it is a bug to return 1 if the expression might have different
** boolean values in different circumstances (a false positive.)
**
** Note that if the expression is part of conditional for a
** LEFT JOIN, then we cannot determine at compile-time whether or not
** is it true or false, so always return 0.
*/
static int exprAlwaysTrue(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
if( !sqlite3ExprIsInteger(p, &v) ) return 0;
return v!=0;
}
static int exprAlwaysFalse(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
if( !sqlite3ExprIsInteger(p, &v) ) return 0;
return v==0;
}
/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
@@ -923,7 +896,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
return pLeft;
}else if( pParse->nErr || IN_RENAME_OBJECT ){
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
}else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
sqlite3ExprDelete(db, pLeft);
sqlite3ExprDelete(db, pRight);
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
@@ -1818,6 +1791,7 @@ int sqlite3ExprIdToTrueFalse(Expr *pExpr){
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
return 1;
}
return 0;
@@ -4522,9 +4496,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
#endif
default: {
default_expr:
if( exprAlwaysTrue(pExpr) ){
if( ExprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysFalse(pExpr) ){
}else if( ExprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -4692,9 +4666,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
#endif
default: {
default_expr:
if( exprAlwaysFalse(pExpr) ){
if( ExprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysTrue(pExpr) ){
}else if( ExprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);