/ Check-in [6de980a0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use macros to determine if an expression is always true or always false.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc
User & Date: drh 2019-04-19 16:21:51
Context
2019-04-19
16:34
Fix a problem with renaming a table that starts with "sqlite". Fix for ticket [f00d7b65]. check-in: a2ead8aa user: dan tags: trunk
16:21
Use macros to determine if an expression is always true or always false. check-in: 6de980a0 user: drh tags: trunk
13:38
Streamline the processing of the AND operator. Slightly smaller and faster. check-in: 7713996a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

   769    769     pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
   770    770     if( pNew ){
   771    771       memset(pNew, 0, sizeof(Expr));
   772    772       pNew->op = (u8)op;
   773    773       pNew->iAgg = -1;
   774    774       if( pToken ){
   775    775         if( nExtra==0 ){
   776         -        pNew->flags |= EP_IntValue|EP_Leaf;
          776  +        pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
   777    777           pNew->u.iValue = iValue;
   778    778         }else{
   779    779           pNew->u.zToken = (char*)&pNew[1];
   780    780           assert( pToken->z!=0 || pToken->n==0 );
   781    781           if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
   782    782           pNew->u.zToken[pToken->n] = 0;
   783    783           if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
................................................................................
   876    876     }else{
   877    877       assert( pParse->db->mallocFailed );
   878    878       sqlite3SelectDelete(pParse->db, pSelect);
   879    879     }
   880    880   }
   881    881   
   882    882   
   883         -/*
   884         -** If the expression is always either TRUE or FALSE (respectively),
   885         -** then return 1.  If one cannot determine the truth value of the
   886         -** expression at compile-time return 0.
   887         -**
   888         -** This is an optimization.  If is OK to return 0 here even if
   889         -** the expression really is always false or false (a false negative).
   890         -** But it is a bug to return 1 if the expression might have different
   891         -** boolean values in different circumstances (a false positive.)
   892         -**
   893         -** Note that if the expression is part of conditional for a
   894         -** LEFT JOIN, then we cannot determine at compile-time whether or not
   895         -** is it true or false, so always return 0.
   896         -*/
   897         -static int exprAlwaysTrue(Expr *p){
   898         -  int v = 0;
   899         -  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
   900         -  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
   901         -  return v!=0;
   902         -}
   903         -static int exprAlwaysFalse(Expr *p){
   904         -  int v = 0;
   905         -  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
   906         -  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
   907         -  return v==0;
   908         -}
   909         -
   910    883   /*
   911    884   ** Join two expressions using an AND operator.  If either expression is
   912    885   ** NULL, then just return the other expression.
   913    886   **
   914    887   ** If one side or the other of the AND is known to be false, then instead
   915    888   ** of returning an AND expression, just return a constant expression with
   916    889   ** a value of false.
................................................................................
   919    892     sqlite3 *db = pParse->db;
   920    893     if( pLeft==0  ){
   921    894       return pRight;
   922    895     }else if( pRight==0 ){
   923    896       return pLeft;
   924    897     }else if( pParse->nErr || IN_RENAME_OBJECT ){
   925    898       return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
   926         -  }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
          899  +  }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
   927    900       sqlite3ExprDelete(db, pLeft);
   928    901       sqlite3ExprDelete(db, pRight);
   929    902       return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
   930    903     }else{
   931    904       return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
   932    905     }
   933    906   }
................................................................................
  1814   1787   int sqlite3ExprIdToTrueFalse(Expr *pExpr){
  1815   1788     assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
  1816   1789     if( !ExprHasProperty(pExpr, EP_Quoted)
  1817   1790      && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
  1818   1791          || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
  1819   1792     ){
  1820   1793       pExpr->op = TK_TRUEFALSE;
         1794  +    ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
  1821   1795       return 1;
  1822   1796     }
  1823   1797     return 0;
  1824   1798   }
  1825   1799   
  1826   1800   /*
  1827   1801   ** The argument must be a TK_TRUEFALSE Expr node.  Return 1 if it is TRUE
................................................................................
  4518   4492         sqlite3VdbeGoto(v, dest);
  4519   4493         sqlite3VdbeResolveLabel(v, destIfFalse);
  4520   4494         break;
  4521   4495       }
  4522   4496   #endif
  4523   4497       default: {
  4524   4498       default_expr:
  4525         -      if( exprAlwaysTrue(pExpr) ){
         4499  +      if( ExprAlwaysTrue(pExpr) ){
  4526   4500           sqlite3VdbeGoto(v, dest);
  4527         -      }else if( exprAlwaysFalse(pExpr) ){
         4501  +      }else if( ExprAlwaysFalse(pExpr) ){
  4528   4502           /* No-op */
  4529   4503         }else{
  4530   4504           r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
  4531   4505           sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
  4532   4506           VdbeCoverage(v);
  4533   4507           testcase( regFree1==0 );
  4534   4508           testcase( jumpIfNull==0 );
................................................................................
  4688   4662           sqlite3VdbeResolveLabel(v, destIfNull);
  4689   4663         }
  4690   4664         break;
  4691   4665       }
  4692   4666   #endif
  4693   4667       default: {
  4694   4668       default_expr: 
  4695         -      if( exprAlwaysFalse(pExpr) ){
         4669  +      if( ExprAlwaysFalse(pExpr) ){
  4696   4670           sqlite3VdbeGoto(v, dest);
  4697         -      }else if( exprAlwaysTrue(pExpr) ){
         4671  +      }else if( ExprAlwaysTrue(pExpr) ){
  4698   4672           /* no-op */
  4699   4673         }else{
  4700   4674           r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
  4701   4675           sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
  4702   4676           VdbeCoverage(v);
  4703   4677           testcase( regFree1==0 );
  4704   4678           testcase( jumpIfNull==0 );

Changes to src/sqliteInt.h.

  2526   2526   #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
  2527   2527   #define EP_Alias     0x400000 /* Is an alias for a result set column */
  2528   2528   #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
  2529   2529   #define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
  2530   2530   #define EP_Subrtn   0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
  2531   2531   #define EP_Quoted   0x4000000 /* TK_ID was originally quoted */
  2532   2532   #define EP_Static   0x8000000 /* Held in memory not obtained from malloc() */
         2533  +#define EP_IsTrue  0x10000000 /* Always has boolean value of TRUE */
         2534  +#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
  2533   2535   
  2534   2536   /*
  2535   2537   ** The EP_Propagate mask is a set of properties that automatically propagate
  2536   2538   ** upwards into parent nodes.
  2537   2539   */
  2538   2540   #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
  2539   2541   
................................................................................
  2541   2543   ** These macros can be used to test, set, or clear bits in the
  2542   2544   ** Expr.flags field.
  2543   2545   */
  2544   2546   #define ExprHasProperty(E,P)     (((E)->flags&(P))!=0)
  2545   2547   #define ExprHasAllProperty(E,P)  (((E)->flags&(P))==(P))
  2546   2548   #define ExprSetProperty(E,P)     (E)->flags|=(P)
  2547   2549   #define ExprClearProperty(E,P)   (E)->flags&=~(P)
         2550  +#define ExprAlwaysTrue(E)   (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
         2551  +#define ExprAlwaysFalse(E)  (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
  2548   2552   
  2549   2553   /* The ExprSetVVAProperty() macro is used for Verification, Validation,
  2550   2554   ** and Accreditation only.  It works like ExprSetProperty() during VVA
  2551   2555   ** processes but is a no-op for delivery.
  2552   2556   */
  2553   2557   #ifdef SQLITE_DEBUG
  2554   2558   # define ExprSetVVAProperty(E,P)  (E)->flags|=(P)