diff options
author | drh <drh@noemail.net> | 2016-08-20 22:49:28 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-08-20 22:49:28 +0000 |
commit | 84b19a3da16ebfd784fea1a42ea90c3473444ddb (patch) | |
tree | 8d25d1a95361f8eb3517ace340ff00a39de8a0a7 /src/expr.c | |
parent | d832da7f40207b77fe2d313b2f7a5b8e6cb0ef78 (diff) | |
download | sqlite-84b19a3da16ebfd784fea1a42ea90c3473444ddb.tar.gz sqlite-84b19a3da16ebfd784fea1a42ea90c3473444ddb.zip |
The docs promise the in "x BETWEEN y AND z" the x expression is only evaluated
once. That is no longer true, and so some tests are failing. This needs to
be fixed before merging to trunk.
FossilOrigin-Name: e50d264fdc2f08d19202c68f73f18df301cb233d
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/src/expr.c b/src/expr.c index c92179d5e..ea8ca32fd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4064,55 +4064,54 @@ int sqlite3ExprCodeExprList( ** ** Code it as such, taking care to do the common subexpression ** elimination of x. +** +** The xJumpIf parameter determines details: +** +** NULL: Store the boolean result in reg[dest] +** sqlite3ExprIfTrue: Jump to dest if true +** sqlite3ExprIfFalse: Jump to dest if false +** +** The jumpIfNull parameter is ignored if xJumpIf is NULL. */ static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ - int dest, /* Jump here if the jump is taken */ - void (*xJumpIf)(Parse*,Expr*,int,int), + int dest, /* Jump destination or storage location */ + void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr compLeft; /* The x>=y term */ Expr compRight; /* The x<=z term */ - Expr exprX; /* The x subexpression */ - int regFree1 = 0; /* Temporary use register */ + + assert( xJump==0 || xJump==sqlite3ExprIfTrue || xJump==sqlite3ExprIfFalse ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - exprX = *pExpr->pLeft; exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; compLeft.op = TK_GE; - compLeft.pLeft = &exprX; + compLeft.pLeft = pExpr->pLeft; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; - compRight.pLeft = &exprX; + compRight.pLeft = pExpr->pLeft; compRight.pRight = pExpr->x.pList->a[1].pExpr; - if( sqlite3ExprIsVector(&exprX)==0 ){ - exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); - } - if( xJumpIf ){ - xJumpIf(pParse, &exprAnd, dest, jumpIfNull); + if( xJump ){ + xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ - exprX.flags |= EP_FromJoin; + /*exprX.flags |= EP_FromJoin;*/ sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } - sqlite3ReleaseTempReg(pParse, regFree1); /* Ensure adequate test coverage */ - testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); - testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); - testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); - testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); - testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); - testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 ); - testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 ); - testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 ); + testcase( xJump==0 ); } /* |