SQLite

Check-in [8002f87d96]
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
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.167
Context
2018-02-26
21:26
Code simplifications. New test cases. (check-in: 57508518ef user: drh tags: is-true-operator)
20:15
Get the "DEFAULT true" and "DEFAULT false" phrases working correctly in CREATE TABLE. (check-in: 8002f87d96 user: drh tags: is-true-operator)
19:03
Enhance TreeView so that it can display the new IS TRUE expression trees. (check-in: 7e38305e6f user: drh tags: is-true-operator)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN ){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){







|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN || p->op==TK_TRUEFALSE ){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){
1727
1728
1729
1730
1731
1732
1733




















1734
1735
1736
1737
1738
1739
1740
** This callback is used by multiple expression walkers.
*/
int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  pWalker->eCode = 0;
  return WRC_Abort;
}





















/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant.  The
** Walker.eCode value determines the type of "constant" we are looking
** for.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
** This callback is used by multiple expression walkers.
*/
int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  pWalker->eCode = 0;
  return WRC_Abort;
}

/*
** If the input expression is an ID with the name "true" or "false"
** then convert it into an appropriate TK_TRUEFALSE term.  Return true
** if a conversion occurred, and false if the expression is unaltered.
*/
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
  assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
  if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
   || sqlite3StrICmp(pExpr->u.zToken, "false")==0
  ){
    pExpr->op = TK_TRUEFALSE;
    pExpr->iTable = pExpr->u.zToken[4]==0;
    pExpr->pTab = 0;
    ExprSetProperty(pExpr, EP_NoReduce);
    return 1;
  }
  return 0;
}


/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant.  The
** Walker.eCode value determines the type of "constant" we are looking
** for.
**
1775
1776
1777
1778
1779
1780
1781






1782
1783
1784
1785
1786
1787
1788
      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
        return WRC_Continue;
      }else{
        pWalker->eCode = 0;
        return WRC_Abort;
      }
    case TK_ID:






    case TK_COLUMN:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );







>
>
>
>
>
>







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
        return WRC_Continue;
      }else{
        pWalker->eCode = 0;
        return WRC_Abort;
      }
    case TK_ID:
      /* Convert "true" or "false" in a DEFAULT clause into the
      ** appropriate TK_TRUEFALSE operator */
      if( pWalker->eCode>=4 && sqlite3ExprIdToTrueFalse(pExpr) ){
        return WRC_Prune;
      }
      /* Fall thru */
    case TK_COLUMN:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
      testcase( pExpr->op==TK_ID );
      testcase( pExpr->op==TK_COLUMN );
      testcase( pExpr->op==TK_AGG_FUNCTION );
      testcase( pExpr->op==TK_AGG_COLUMN );
Changes to src/parse.y.
309
310
311
312
313
314
315


316
317
318
319
320
321
322
                            {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z).      {
  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
  sqlite3AddDefaultValue(pParse,p,A.z,Z);
}
ccons ::= DEFAULT scanpt id(X).       {
  Expr *p = tokenExpr(pParse, TK_STRING, X);


  sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.







>
>







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
                            {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z).      {
  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
  sqlite3AddDefaultValue(pParse,p,A.z,Z);
}
ccons ::= DEFAULT scanpt id(X).       {
  Expr *p = tokenExpr(pParse, TK_STRING, X);
  sqlite3ExprIdToTrueFalse(p);
  testcase( p->op==TK_TRUEFALSE && p->iTable==0 );
  sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.
Changes to src/resolve.c.
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  ** case, we need to return right away and not make any changes to
  ** pExpr.
  **
  ** Because no reference was made to outer contexts, the pNC->nRef
  ** fields are not changed in any context.
  */
  if( cnt==0 && zTab==0 ){

    if( ExprHasProperty(pExpr,EP_DblQuoted) ){
      pExpr->op = TK_STRING;
      pExpr->pTab = 0;
      return WRC_Prune;
    }
    if( sqlite3StrICmp(zCol, "true")==0 || sqlite3StrICmp(zCol, "false")==0 ){
      pExpr->op = TK_TRUEFALSE;
      pExpr->iTable = zCol[4]==0;
      pExpr->pTab = 0;
      return WRC_Prune;
    }
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.







>





|
<
<
<







428
429
430
431
432
433
434
435
436
437
438
439
440
441



442
443
444
445
446
447
448
  ** case, we need to return right away and not make any changes to
  ** pExpr.
  **
  ** Because no reference was made to outer contexts, the pNC->nRef
  ** fields are not changed in any context.
  */
  if( cnt==0 && zTab==0 ){
    assert( pExpr->op==TK_ID );
    if( ExprHasProperty(pExpr,EP_DblQuoted) ){
      pExpr->op = TK_STRING;
      pExpr->pTab = 0;
      return WRC_Prune;
    }
    if( sqlite3ExprIdToTrueFalse(pExpr) ){



      return WRC_Prune;
    }
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
Changes to src/sqliteInt.h.
3836
3837
3838
3839
3840
3841
3842

3843
3844
3845
3846
3847
3848
3849
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3EndTransaction(Parse*,int);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);

int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);







>







3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3EndTransaction(Parse*,int);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIdToTrueFalse(Expr*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
Changes to test/istrue.test.
73
74
75
76
77
78
79











80
81
do_execsql_test istrue-400 {
  SELECT x FROM t1 WHERE true;
} {1 2 3}
do_execsql_test istrue-410 {
  SELECT x FROM t1 WHERE false;
} {}













finish_test







>
>
>
>
>
>
>
>
>
>
>


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
do_execsql_test istrue-400 {
  SELECT x FROM t1 WHERE true;
} {1 2 3}
do_execsql_test istrue-410 {
  SELECT x FROM t1 WHERE false;
} {}

do_execsql_test istrue-500 {
  CREATE TABLE t2(
     a INTEGER PRIMARY KEY,
     b BOOLEAN DEFAULT true,
     c BOOLEAN DEFAULT(true),
     d BOOLEAN DEFAULT false,
     e BOOLEAN DEFAULT(false)
  );
  INSERT INTO t2 DEFAULT VALUES;
  SELECT * FROM t2;
} {1 1 1 0 0}

finish_test