aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c25
-rw-r--r--src/resolve.c36
-rw-r--r--src/vdbe.c6
3 files changed, 59 insertions, 8 deletions
diff --git a/src/expr.c b/src/expr.c
index 1b8773492..5079035ca 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3543,6 +3543,14 @@ 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);
+ return target;
+ }
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
@@ -3698,6 +3706,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(v, op, r1, inReg);
break;
}
+ case TK_ISTRUE: {
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+ testcase( regFree1==0 );
+ sqlite3VdbeAddOp2(v, OP_Not, r1, inReg);
+ sqlite3VdbeAddOp2(v, OP_Not, inReg, inReg);
+ break;
+ }
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
@@ -4473,6 +4488,11 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
+ case TK_ISTRUE: {
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
case TK_IS:
case TK_ISNOT:
testcase( op==TK_IS );
@@ -4627,6 +4647,11 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
+ case TK_ISTRUE: {
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
case TK_IS:
case TK_ISNOT:
testcase( pExpr->op==TK_IS );
diff --git a/src/resolve.c b/src/resolve.c
index f735fffa0..fb00788dd 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -431,10 +431,22 @@ static int lookupName(
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
- if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- pExpr->op = TK_STRING;
- pExpr->pTab = 0;
- return WRC_Prune;
+ 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 ){
+ pExpr->op = TK_TRUE;
+ pExpr->pTab = 0;
+ return WRC_Prune;
+ }
+ if( sqlite3StrICmp(zCol, "false")==0 ){
+ pExpr->op = TK_FALSE;
+ pExpr->pTab = 0;
+ return WRC_Prune;
+ }
}
/*
@@ -783,6 +795,21 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
+ case TK_IS:
+ /* Handle special cases of "x IS TRUE" and "x IS FALSE". The first
+ ** is transformed into "+x" and the second into "NOT x". */
+ if( pExpr->pRight->op==TK_ID ){
+ int rc = resolveExprStep(pWalker, pExpr->pRight);
+ if( rc==WRC_Abort ) return WRC_Abort;
+ if( pExpr->pRight->op==TK_TRUE ){
+ pExpr->op = TK_ISTRUE;
+ return WRC_Continue;
+ }else if( pExpr->pRight->op==TK_FALSE ){
+ pExpr->op = TK_NOT;
+ return WRC_Continue;
+ }
+ }
+ /* Fall thru */
case TK_BETWEEN:
case TK_EQ:
case TK_NE:
@@ -790,7 +817,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
case TK_LE:
case TK_GT:
case TK_GE:
- case TK_IS:
case TK_ISNOT: {
int nLeft, nRight;
if( pParse->db->mallocFailed ) break;
diff --git a/src/vdbe.c b/src/vdbe.c
index b4c96b498..61fc55e4d 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2201,10 +2201,10 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
case OP_Not: { /* same as TK_NOT, in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
- sqlite3VdbeMemSetNull(pOut);
if( (pIn1->flags & MEM_Null)==0 ){
- pOut->flags = MEM_Int;
- pOut->u.i = !sqlite3VdbeBooleanValue(pIn1, 0);
+ sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0));
+ }else{
+ sqlite3VdbeMemSetNull(pOut);
}
break;
}