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
This commit is contained in:
drh 2016-08-20 22:49:28 +00:00
parent d832da7f40
commit 84b19a3da1
3 changed files with 30 additions and 31 deletions

View File

@ -1,5 +1,5 @@
C Further\scomment\senhancements.\s\sNo\schanges\sto\scode. C The\sdocs\spromise\sthe\sin\s"x\sBETWEEN\sy\sAND\sz"\sthe\sx\sexpression\sis\sonly\sevaluated\nonce.\s\sThat\sis\sno\slonger\strue,\sand\sso\ssome\stests\sare\sfailing.\s\sThis\sneeds\sto\nbe\sfixed\sbefore\smerging\sto\strunk.
D 2016-08-20T21:11:25.815 D 2016-08-20T22:49:28.330
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05
F src/expr.c b6f0592292944a1700b503d00f588932f5683d67 F src/expr.c 157f2aa7e573c8d354ccfea9955dac2842467b0e
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8
F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771
@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 4fb66d6592b141a4a71359250dbd1ac454569cb9 P d4562a9e7b1eaff41466210e3a0caaf374ec5a92
R 560b79caaccb19afcc4a2c629096a4bc R 79bb83cf9bac81ae1bf4f01bc53e554b
U drh U drh
Z f5ddde0143384b43283a729a6b1d1670 Z 762069ce8b935adb1e168884e493813e

View File

@ -1 +1 @@
d4562a9e7b1eaff41466210e3a0caaf374ec5a92 e50d264fdc2f08d19202c68f73f18df301cb233d

View File

@ -4064,55 +4064,54 @@ int sqlite3ExprCodeExprList(
** **
** Code it as such, taking care to do the common subexpression ** Code it as such, taking care to do the common subexpression
** elimination of x. ** 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( static void exprCodeBetween(
Parse *pParse, /* Parsing and code generating context */ Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* The BETWEEN expression */ Expr *pExpr, /* The BETWEEN expression */
int dest, /* Jump here if the jump is taken */ int dest, /* Jump destination or storage location */
void (*xJumpIf)(Parse*,Expr*,int,int), void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
int jumpIfNull /* Take the jump if the BETWEEN is NULL */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */
){ ){
Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr exprAnd; /* The AND operator in x>=y AND x<=z */
Expr compLeft; /* The x>=y term */ Expr compLeft; /* The x>=y term */
Expr compRight; /* The x<=z 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(&compLeft, 0, sizeof(Expr));
memset(&compRight, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND; exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft; exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight; exprAnd.pRight = &compRight;
compLeft.op = TK_GE; compLeft.op = TK_GE;
compLeft.pLeft = &exprX; compLeft.pLeft = pExpr->pLeft;
compLeft.pRight = pExpr->x.pList->a[0].pExpr; compLeft.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE; compRight.op = TK_LE;
compRight.pLeft = &exprX; compRight.pLeft = pExpr->pLeft;
compRight.pRight = pExpr->x.pList->a[1].pExpr; compRight.pRight = pExpr->x.pList->a[1].pExpr;
if( sqlite3ExprIsVector(&exprX)==0 ){ if( xJump ){
exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, &regFree1)); xJump(pParse, &exprAnd, dest, jumpIfNull);
}
if( xJumpIf ){
xJumpIf(pParse, &exprAnd, dest, jumpIfNull);
}else{ }else{
exprX.flags |= EP_FromJoin; /*exprX.flags |= EP_FromJoin;*/
sqlite3ExprCodeTarget(pParse, &exprAnd, dest); sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
} }
sqlite3ReleaseTempReg(pParse, regFree1);
/* Ensure adequate test coverage */ /* Ensure adequate test coverage */
testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 );
testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 );
testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 );
testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 );
testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); testcase( xJump==0 );
testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 );
testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 );
testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 );
} }
/* /*