Use macros to determine if an expression is always true or always false.
FossilOrigin-Name: 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc
This commit is contained in:
parent
d5c851c1cb
commit
ad31727fc6
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Streamline\sthe\sprocessing\sof\sthe\sAND\soperator.\s\sSlightly\ssmaller\sand\sfaster.
|
||||
D 2019-04-19T13:38:34.610
|
||||
C Use\smacros\sto\sdetermine\sif\san\sexpression\sis\salways\strue\sor\salways\sfalse.
|
||||
D 2019-04-19T16:21:51.905
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -470,7 +470,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
|
||||
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
|
||||
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
|
||||
F src/expr.c d9b219b2a20f9a99712c24b6c6b21588006260eb3f8bdc96df8262869b58512a
|
||||
F src/expr.c 18f8875c247ef5491826619d7ad1d5a67a7a370d76d92066761bd3c015a2d16b
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33
|
||||
F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee
|
||||
@ -523,7 +523,7 @@ F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901
|
||||
F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
|
||||
F src/sqliteInt.h 3a9497a4d7261e348390a1390d00d50f51ebab2ee97335b287447aa9e12bf543
|
||||
F src/sqliteInt.h b8d576ae658a3529d2bb72f4ce27892937a2f5cc3b63294250c556007ce112de
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@ -1818,7 +1818,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe
|
||||
R 4d121f6250fa4d728fb8a46a98d547d3
|
||||
P 7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403
|
||||
R 8599c4a645fc2e6f1e9b669040f6d312
|
||||
U drh
|
||||
Z 1c6157db33fa1baf603ced1f230aa369
|
||||
Z 635a58ce2bb9d7966c1e1a49c0802a30
|
||||
|
@ -1 +1 @@
|
||||
7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403
|
||||
6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc
|
40
src/expr.c
40
src/expr.c
@ -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, ®Free1);
|
||||
@ -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, ®Free1);
|
||||
|
@ -2530,6 +2530,8 @@ struct Expr {
|
||||
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
|
||||
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
|
||||
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
|
||||
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
|
||||
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
|
||||
|
||||
/*
|
||||
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||
@ -2545,6 +2547,8 @@ struct Expr {
|
||||
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
|
||||
#define ExprSetProperty(E,P) (E)->flags|=(P)
|
||||
#define ExprClearProperty(E,P) (E)->flags&=~(P)
|
||||
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
|
||||
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
|
||||
|
||||
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
|
||||
** and Accreditation only. It works like ExprSetProperty() during VVA
|
||||
|
Loading…
Reference in New Issue
Block a user