mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Reinstate the mechanism in BETWEEN that avoids evaluating the first expression
more than once, but fix the affinity extractor so that it works with this mechanism. The de-duplication of the first expression still does not work for vector expressions, though. FossilOrigin-Name: 2f39987f21bd6dae8d2be610a1fd5f06f8878e9e
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
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.
|
C Reinstate\sthe\smechanism\sin\sBETWEEN\sthat\savoids\sevaluating\sthe\sfirst\sexpression\nmore\sthan\sonce,\sbut\sfix\sthe\saffinity\sextractor\sso\sthat\sit\sworks\swith\sthis\nmechanism.\s\sThe\sde-duplication\sof\sthe\sfirst\sexpression\sstill\sdoes\snot\swork\nfor\svector\sexpressions,\sthough.
|
||||||
D 2016-08-20T22:49:28.330
|
D 2016-08-22T00:48:58.062
|
||||||
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 157f2aa7e573c8d354ccfea9955dac2842467b0e
|
F src/expr.c 77215e927ab39426e19340b2e109267f62abe398
|
||||||
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 d4562a9e7b1eaff41466210e3a0caaf374ec5a92
|
P e50d264fdc2f08d19202c68f73f18df301cb233d
|
||||||
R 79bb83cf9bac81ae1bf4f01bc53e554b
|
R 333f2c163d1312925e2511fcd28df52d
|
||||||
U drh
|
U drh
|
||||||
Z 762069ce8b935adb1e168884e493813e
|
Z ca2741b6fe90555773b217749c459f72
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
e50d264fdc2f08d19202c68f73f18df301cb233d
|
2f39987f21bd6dae8d2be610a1fd5f06f8878e9e
|
||||||
36
src/expr.c
36
src/expr.c
@@ -39,17 +39,14 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
|||||||
assert( pExpr->flags&EP_xIsSelect );
|
assert( pExpr->flags&EP_xIsSelect );
|
||||||
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
|
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
|
||||||
}
|
}
|
||||||
|
if( op==TK_REGISTER ) op = pExpr->op2;
|
||||||
#ifndef SQLITE_OMIT_CAST
|
#ifndef SQLITE_OMIT_CAST
|
||||||
if( op==TK_CAST ){
|
if( op==TK_CAST ){
|
||||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||||
return sqlite3AffinityType(pExpr->u.zToken, 0);
|
return sqlite3AffinityType(pExpr->u.zToken, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
|
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab!=0 ){
|
||||||
&& pExpr->pTab!=0
|
|
||||||
){
|
|
||||||
/* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
|
|
||||||
** a TK_COLUMN but was previously evaluated and cached in a register */
|
|
||||||
int j = pExpr->iColumn;
|
int j = pExpr->iColumn;
|
||||||
if( j<0 ) return SQLITE_AFF_INTEGER;
|
if( j<0 ) return SQLITE_AFF_INTEGER;
|
||||||
assert( pExpr->pTab && j<pExpr->pTab->nCol );
|
assert( pExpr->pTab && j<pExpr->pTab->nCol );
|
||||||
@@ -4083,34 +4080,45 @@ static void exprCodeBetween(
|
|||||||
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 = pExpr->pLeft;
|
compLeft.pLeft = &exprX;
|
||||||
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 = pExpr->pLeft;
|
compRight.pLeft = &exprX;
|
||||||
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
||||||
|
if( sqlite3ExprIsVector(&exprX)==0 ){
|
||||||
|
exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1));
|
||||||
|
}
|
||||||
if( xJump ){
|
if( xJump ){
|
||||||
xJump(pParse, &exprAnd, dest, jumpIfNull);
|
xJump(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( xJump==sqlite3ExprIfTrue && jumpIfNull==0 );
|
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
|
||||||
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 );
|
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
|
||||||
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 );
|
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
|
||||||
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 );
|
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 );
|
||||||
|
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
|
||||||
|
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
|
||||||
|
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
|
||||||
|
testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
|
||||||
testcase( xJump==0 );
|
testcase( xJump==0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user