/ Check-in [8002f87d]
Login

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

Overview
Comment:Get the "DEFAULT true" and "DEFAULT false" phrases working correctly in CREATE TABLE.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | is-true-operator
Files: files | file ages | folders
SHA3-256: 8002f87d96b3f885cd208e7d204907a33ba60c4057ce2338b71e2de41215b0e5
User & Date: drh 2018-02-26 20:15:54
Context
2018-02-26
21:26
Code simplifications. New test cases. check-in: 57508518 user: drh tags: is-true-operator
20:15
Get the "DEFAULT true" and "DEFAULT false" phrases working correctly in CREATE TABLE. check-in: 8002f87d user: drh tags: is-true-operator
19:03
Enhance TreeView so that it can display the new IS TRUE expression trees. check-in: 7e38305e user: drh tags: is-true-operator
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1119   1119   ** to enforce this constraint.
  1120   1120   */
  1121   1121   static int dupedExprStructSize(Expr *p, int flags){
  1122   1122     int nSize;
  1123   1123     assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  1124   1124     assert( EXPR_FULLSIZE<=0xfff );
  1125   1125     assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  1126         -  if( 0==flags || p->op==TK_SELECT_COLUMN ){
         1126  +  if( 0==flags || p->op==TK_SELECT_COLUMN || p->op==TK_TRUEFALSE ){
  1127   1127       nSize = EXPR_FULLSIZE;
  1128   1128     }else{
  1129   1129       assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
  1130   1130       assert( !ExprHasProperty(p, EP_FromJoin) ); 
  1131   1131       assert( !ExprHasProperty(p, EP_MemToken) );
  1132   1132       assert( !ExprHasProperty(p, EP_NoReduce) );
  1133   1133       if( p->pLeft || p->x.pList ){
................................................................................
  1727   1727   ** This callback is used by multiple expression walkers.
  1728   1728   */
  1729   1729   int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
  1730   1730     UNUSED_PARAMETER(NotUsed);
  1731   1731     pWalker->eCode = 0;
  1732   1732     return WRC_Abort;
  1733   1733   }
         1734  +
         1735  +/*
         1736  +** If the input expression is an ID with the name "true" or "false"
         1737  +** then convert it into an appropriate TK_TRUEFALSE term.  Return true
         1738  +** if a conversion occurred, and false if the expression is unaltered.
         1739  +*/
         1740  +int sqlite3ExprIdToTrueFalse(Expr *pExpr){
         1741  +  assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
         1742  +  if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
         1743  +   || sqlite3StrICmp(pExpr->u.zToken, "false")==0
         1744  +  ){
         1745  +    pExpr->op = TK_TRUEFALSE;
         1746  +    pExpr->iTable = pExpr->u.zToken[4]==0;
         1747  +    pExpr->pTab = 0;
         1748  +    ExprSetProperty(pExpr, EP_NoReduce);
         1749  +    return 1;
         1750  +  }
         1751  +  return 0;
         1752  +}
         1753  +
  1734   1754   
  1735   1755   /*
  1736   1756   ** These routines are Walker callbacks used to check expressions to
  1737   1757   ** see if they are "constant" for some definition of constant.  The
  1738   1758   ** Walker.eCode value determines the type of "constant" we are looking
  1739   1759   ** for.
  1740   1760   **
................................................................................
  1775   1795         if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
  1776   1796           return WRC_Continue;
  1777   1797         }else{
  1778   1798           pWalker->eCode = 0;
  1779   1799           return WRC_Abort;
  1780   1800         }
  1781   1801       case TK_ID:
         1802  +      /* Convert "true" or "false" in a DEFAULT clause into the
         1803  +      ** appropriate TK_TRUEFALSE operator */
         1804  +      if( pWalker->eCode>=4 && sqlite3ExprIdToTrueFalse(pExpr) ){
         1805  +        return WRC_Prune;
         1806  +      }
         1807  +      /* Fall thru */
  1782   1808       case TK_COLUMN:
  1783   1809       case TK_AGG_FUNCTION:
  1784   1810       case TK_AGG_COLUMN:
  1785   1811         testcase( pExpr->op==TK_ID );
  1786   1812         testcase( pExpr->op==TK_COLUMN );
  1787   1813         testcase( pExpr->op==TK_AGG_FUNCTION );
  1788   1814         testcase( pExpr->op==TK_AGG_COLUMN );

Changes to src/parse.y.

   309    309                               {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
   310    310   ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z).      {
   311    311     Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
   312    312     sqlite3AddDefaultValue(pParse,p,A.z,Z);
   313    313   }
   314    314   ccons ::= DEFAULT scanpt id(X).       {
   315    315     Expr *p = tokenExpr(pParse, TK_STRING, X);
          316  +  sqlite3ExprIdToTrueFalse(p);
          317  +  testcase( p->op==TK_TRUEFALSE && p->iTable==0 );
   316    318     sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
   317    319   }
   318    320   
   319    321   // In addition to the type name, we also care about the primary key and
   320    322   // UNIQUE constraints.
   321    323   //
   322    324   ccons ::= NULL onconf.

Changes to src/resolve.c.

   428    428     ** case, we need to return right away and not make any changes to
   429    429     ** pExpr.
   430    430     **
   431    431     ** Because no reference was made to outer contexts, the pNC->nRef
   432    432     ** fields are not changed in any context.
   433    433     */
   434    434     if( cnt==0 && zTab==0 ){
          435  +    assert( pExpr->op==TK_ID );
   435    436       if( ExprHasProperty(pExpr,EP_DblQuoted) ){
   436    437         pExpr->op = TK_STRING;
   437    438         pExpr->pTab = 0;
   438    439         return WRC_Prune;
   439    440       }
   440         -    if( sqlite3StrICmp(zCol, "true")==0 || sqlite3StrICmp(zCol, "false")==0 ){
   441         -      pExpr->op = TK_TRUEFALSE;
   442         -      pExpr->iTable = zCol[4]==0;
   443         -      pExpr->pTab = 0;
          441  +    if( sqlite3ExprIdToTrueFalse(pExpr) ){
   444    442         return WRC_Prune;
   445    443       }
   446    444     }
   447    445   
   448    446     /*
   449    447     ** cnt==0 means there was not match.  cnt>1 means there were two or
   450    448     ** more matches.  Either way, we have an error.

Changes to src/sqliteInt.h.

  3836   3836   void sqlite3CodeVerifySchema(Parse*, int);
  3837   3837   void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
  3838   3838   void sqlite3BeginTransaction(Parse*, int);
  3839   3839   void sqlite3EndTransaction(Parse*,int);
  3840   3840   void sqlite3Savepoint(Parse*, int, Token*);
  3841   3841   void sqlite3CloseSavepoints(sqlite3 *);
  3842   3842   void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
         3843  +int sqlite3ExprIdToTrueFalse(Expr*);
  3843   3844   int sqlite3ExprIsConstant(Expr*);
  3844   3845   int sqlite3ExprIsConstantNotJoin(Expr*);
  3845   3846   int sqlite3ExprIsConstantOrFunction(Expr*, u8);
  3846   3847   int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
  3847   3848   int sqlite3ExprIsTableConstant(Expr*,int);
  3848   3849   #ifdef SQLITE_ENABLE_CURSOR_HINTS
  3849   3850   int sqlite3ExprContainsSubquery(Expr*);

Changes to test/istrue.test.

    73     73   do_execsql_test istrue-400 {
    74     74     SELECT x FROM t1 WHERE true;
    75     75   } {1 2 3}
    76     76   do_execsql_test istrue-410 {
    77     77     SELECT x FROM t1 WHERE false;
    78     78   } {}
    79     79   
           80  +do_execsql_test istrue-500 {
           81  +  CREATE TABLE t2(
           82  +     a INTEGER PRIMARY KEY,
           83  +     b BOOLEAN DEFAULT true,
           84  +     c BOOLEAN DEFAULT(true),
           85  +     d BOOLEAN DEFAULT false,
           86  +     e BOOLEAN DEFAULT(false)
           87  +  );
           88  +  INSERT INTO t2 DEFAULT VALUES;
           89  +  SELECT * FROM t2;
           90  +} {1 1 1 0 0}
    80     91   
    81     92   finish_test