Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Code simplifications. New test cases. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | is-true-operator |
Files: | files | file ages | folders |
SHA3-256: |
57508518ef9d003d259ba98dcc32e510 |
User & Date: | drh 2018-02-26 21:26:27.326 |
Context
2018-02-27
| ||
00:58 | Remove an unnecessary decision. (check-in: adcb466549 user: drh tags: is-true-operator) | |
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) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
1119 1120 1121 1122 1123 1124 1125 | ** 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 ); | | | 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 ){ |
︙ | ︙ | |||
1739 1740 1741 1742 1743 1744 1745 | */ 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; | < < < > > > > > > > > > > > | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 | */ 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; return 1; } return 0; } /* ** The argument is one of a TK_TRUEFALSE term. Return 1 if it is TRUE ** and 0 if it is FALSE. */ int sqlite3ExprTruthOperand(const Expr *pExpr){ assert( pExpr->op==TK_TRUEFALSE ); assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); return pExpr->u.zToken[4]==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. |
︙ | ︙ | |||
3566 3567 3568 3569 3570 3571 3572 | pExpr->op2); } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); return target; } case TK_TRUEFALSE: { | | | 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 | pExpr->op2); } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); return target; } case TK_TRUEFALSE: { sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthOperand(pExpr), target); return target; } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); codeReal(v, pExpr->u.zToken, 0, target); return target; |
︙ | ︙ | |||
3725 3726 3727 3728 3729 3730 3731 | assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); sqlite3VdbeAddOp2(v, op, r1, inReg); break; } case TK_TRUTH: { | | < < > | | | 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 | assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); sqlite3VdbeAddOp2(v, op, r1, inReg); break; } case TK_TRUTH: { int isTrue; r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); isTrue = sqlite3ExprTruthOperand(pExpr->pRight); sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ (pExpr->op2==TK_IS)); break; } case TK_ISNULL: case TK_NOTNULL: { int addr; assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); |
︙ | ︙ | |||
4511 4512 4513 4514 4515 4516 4517 4518 | case TK_NOT: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { int isNot; testcase( jumpIfNull==0 ); | > < < < < > > > | | 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 | case TK_NOT: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { int isNot; int isTrue; testcase( jumpIfNull==0 ); isNot = pExpr->op2==TK_ISNOT; isTrue = sqlite3ExprTruthOperand(pExpr->pRight); testcase( isTrue && isNot ); testcase( isTrue && !isNot ); if( isTrue ^ isNot ){ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, isNot ? SQLITE_JUMPIFNULL : 0); }else{ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, isNot ? SQLITE_JUMPIFNULL : 0); } break; |
︙ | ︙ | |||
4681 4682 4683 4684 4685 4686 4687 | } case TK_NOT: { testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { | < > < < < > > > | | 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 | } case TK_NOT: { testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { int isNot; int isTrue; testcase( jumpIfNull==0 ); assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); isNot = pExpr->op2==TK_ISNOT; isTrue = sqlite3ExprTruthOperand(pExpr->pRight); testcase( isTrue && isNot ); testcase( isTrue && !isNot ); if( isTrue ^ isNot ){ /* IS TRUE and IS NOT FALSE */ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, isNot ? 0 : SQLITE_JUMPIFNULL); }else{ /* IS FALSE and IS NOT TRUE */ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
310 311 312 313 314 315 316 | 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); | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | 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 && sqlite3ExprTruthOperand(p) ); 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.
︙ | ︙ | |||
795 796 797 798 799 800 801 | assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ if( (pRight = pExpr->pRight)->op==TK_ID ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ | < | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 | assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ if( (pRight = pExpr->pRight)->op==TK_ID ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ pExpr->op2 = pExpr->op; pExpr->op = TK_TRUTH; return WRC_Continue; } } /* Fall thru */ } |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2383 2384 2385 2386 2387 2388 2389 | #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood | | < | 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 | #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 op2; /* TK_REGISTER: original value of Expr.op ** TK_COLUMN: the value of p5 for OP_Column |
︙ | ︙ | |||
3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 | 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*); | > | 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 | 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 sqlite3ExprTruthOperand(const 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 src/treeview.c.
︙ | ︙ | |||
289 290 291 292 293 294 295 | break; } case TK_NULL: { sqlite3TreeViewLine(pView,"NULL"); break; } case TK_TRUEFALSE: { | | > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | break; } case TK_NULL: { sqlite3TreeViewLine(pView,"NULL"); break; } case TK_TRUEFALSE: { sqlite3TreeViewLine(pView, sqlite3ExprTruthOperand(pExpr) ? "TRUE" : "FALSE"); break; } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); break; } |
︙ | ︙ | |||
349 350 351 352 353 354 355 356 357 358 | case TK_UPLUS: zUniOp = "UPLUS"; break; case TK_BITNOT: zUniOp = "BITNOT"; break; case TK_NOT: zUniOp = "NOT"; break; case TK_ISNULL: zUniOp = "ISNULL"; break; case TK_NOTNULL: zUniOp = "NOTNULL"; break; case TK_TRUTH: { assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); assert( pExpr->pRight ); assert( pExpr->pRight->op==TK_TRUEFALSE ); | > > > > < | | < < < < | 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | case TK_UPLUS: zUniOp = "UPLUS"; break; case TK_BITNOT: zUniOp = "BITNOT"; break; case TK_NOT: zUniOp = "NOT"; break; case TK_ISNULL: zUniOp = "ISNULL"; break; case TK_NOTNULL: zUniOp = "NOTNULL"; break; case TK_TRUTH: { int x; const char *azOp[] = { "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE" }; assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); assert( pExpr->pRight ); assert( pExpr->pRight->op==TK_TRUEFALSE ); x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthOperand(pExpr->pRight); zUniOp = azOp[x]; break; } case TK_SPAN: { sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; |
︙ | ︙ |
Changes to test/istrue.test.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 | 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 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 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} do_execsql_test istrue-510 { DROP TABLE t2; CREATE TABLE t2( a INTEGER PRIMARY KEY, b BOOLEAN DEFAULT(not true), c BOOLEAN DEFAULT(not false) ); INSERT INTO t2(a) VALUES(99); SELECT * FROM t2; } {99 0 1} do_execsql_test istrue-520 { DROP TABLE t2; CREATE TABLE t2( a INTEGER PRIMARY KEY, b BOOLEAN CHECK(b IS TRUE), c BOOLEAN CHECK(c IS FALSE), d BOOLEAN CHECK(d IS NOT TRUE), e BOOLEAN CHECK(e IS NOT FALSE) ); INSERT INTO t2 VALUES(1,true,false,null,null); SELECT * FROM t2; } {1 1 0 {} {}} do_catchsql_test istrue-521 { INSERT INTO t2 VALUES(2,false,false,null,null); } {1 {CHECK constraint failed: t2}} do_catchsql_test istrue-522 { INSERT INTO t2 VALUES(2,true,true,null,null); } {1 {CHECK constraint failed: t2}} do_catchsql_test istrue-523 { INSERT INTO t2 VALUES(2,true,false,true,null); } {1 {CHECK constraint failed: t2}} do_catchsql_test istrue-524 { INSERT INTO t2 VALUES(2,true,false,null,false); } {1 {CHECK constraint failed: t2}} finish_test |