diff options
author | drh <drh@noemail.net> | 2018-02-26 18:49:05 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-02-26 18:49:05 +0000 |
commit | 8abed7b90769a6f63ef2681cfd4ae92d617b883f (patch) | |
tree | 753870862176408c8f5871fe7e7558939c9395ae /src/expr.c | |
parent | bc8f68a3a05ab6e37127685177d2ca182688f60f (diff) | |
download | sqlite-8abed7b90769a6f63ef2681cfd4ae92d617b883f.tar.gz sqlite-8abed7b90769a6f63ef2681cfd4ae92d617b883f.zip |
Refactor for correct NULL handling in the IS TRUE, IS FALSE, IS NOT TRUE,
and IS NOT FALSE operators.
FossilOrigin-Name: cf2abd59be9971a55bd3d6c5df374c6aaa23bf81819482b42f01ee2484dcd739
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/src/expr.c b/src/expr.c index 5079035ca..f32a03a6d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3543,12 +3543,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ codeInteger(pParse, pExpr, 0, target); return target; } - case TK_TRUE: { - sqlite3VdbeAddOp2(v, OP_Integer, 1, target); - return target; - } - case TK_FALSE: { - sqlite3VdbeAddOp2(v, OP_Integer, 0, target); + case TK_TRUEFALSE: { + sqlite3VdbeAddOp2(v, OP_Integer, pExpr->iTable, target); return target; } #ifndef SQLITE_OMIT_FLOATING_POINT @@ -3706,11 +3702,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(v, op, r1, inReg); break; } - case TK_ISTRUE: { + case TK_TRUTH: { + assert( pExpr->pRight->op==TK_TRUEFALSE ); + assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 ); + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - sqlite3VdbeAddOp2(v, OP_Not, r1, inReg); - sqlite3VdbeAddOp2(v, OP_Not, inReg, inReg); + sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !pExpr->pRight->iTable, + pExpr->pRight->iTable ^ (pExpr->op2==TK_IS)); break; } case TK_ISNULL: @@ -4488,9 +4487,21 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } - case TK_ISTRUE: { + case TK_TRUTH: { + int isNot; testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + assert( pExpr->pRight->op==TK_TRUEFALSE ); + assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 ); + testcase( pExpr->pRight->iTable==0 ); + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); + isNot = pExpr->op2==TK_ISNOT; + if( pExpr->pRight->iTable ^ isNot ){ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + }else{ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + } break; } case TK_IS: @@ -4647,9 +4658,25 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } - case TK_ISTRUE: { + case TK_TRUTH: { testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + int isNot; + testcase( jumpIfNull==0 ); + assert( pExpr->pRight->op==TK_TRUEFALSE ); + assert( pExpr->pRight->iTable==0 || pExpr->pRight->iTable==1 ); + testcase( pExpr->pRight->iTable==0 ); + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); + isNot = pExpr->op2==TK_ISNOT; + if( pExpr->pRight->iTable ^ 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, + isNot ? 0: SQLITE_JUMPIFNULL); + } break; } case TK_IS: |