aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-11-21 21:23:31 +0000
committerdrh <drh@noemail.net>2013-11-21 21:23:31 +0000
commitd673cddad6151cbbbe045e2e805b363b17781071 (patch)
treeb5fd2180e5c96d23d605f7f4d58c05c8728067f9 /src/expr.c
parentd9f158e7b274e1d58661821868412a5c5ee7b53e (diff)
downloadsqlite-d673cddad6151cbbbe045e2e805b363b17781071.tar.gz
sqlite-d673cddad6151cbbbe045e2e805b363b17781071.zip
Do not reuse factored constants that might have had their encodings changed.
FossilOrigin-Name: 487f20366ce77f0c90865d10d5aaedd95af98694
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/expr.c b/src/expr.c
index 2fb26b20f..6c8a8cce7 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2989,13 +2989,22 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
/*
** Factor out the code of the given expression to initialization time.
*/
-void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){
+void sqlite3ExprCodeAtInit(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The expression to code when the VDBE initializes */
+ int regDest, /* Store the value in this register */
+ u8 reusable /* True if this expression is reusable */
+){
ExprList *p;
assert( ConstFactorOk(pParse) );
p = pParse->pConstExpr;
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
p = sqlite3ExprListAppend(pParse, p, pExpr);
- if( p ) p->a[p->nExpr-1].u.iConstExprReg = regDest;
+ if( p ){
+ struct ExprList_item *pItem = &p->a[p->nExpr-1];
+ pItem->u.iConstExprReg = regDest;
+ pItem->reusable = reusable;
+ }
pParse->pConstExpr = p;
}
@@ -3023,14 +3032,15 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
int i;
*pReg = 0;
if( p ){
- for(i=0; i<p->nExpr; i++){
- if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){
- return p->a[i].u.iConstExprReg;
+ struct ExprList_item *pItem;
+ for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+ if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+ return pItem->u.iConstExprReg;
}
}
}
r2 = ++pParse->nMem;
- sqlite3ExprCodeAtInit(pParse, pExpr, r2);
+ sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
}else{
int r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
@@ -3399,7 +3409,7 @@ int sqlite3ExprCodeExprList(
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
- sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+ sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){