diff options
author | drh <drh@noemail.net> | 2008-04-15 12:14:21 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2008-04-15 12:14:21 +0000 |
commit | 191b54cb5d463359dcc9ce14320ecd72de7cf264 (patch) | |
tree | c8914708e377b4784f1948c968f0a13a9b0205b6 /src/expr.c | |
parent | 5f3a367bf399767fe151becf2eaca42c036b1372 (diff) | |
download | sqlite-191b54cb5d463359dcc9ce14320ecd72de7cf264.tar.gz sqlite-191b54cb5d463359dcc9ce14320ecd72de7cf264.zip |
Fix a code generator bug caused by the new CSE optimization. Add test cases
to prevent a recurrence. (CVS 5011)
FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/expr.c b/src/expr.c index 3002ef7b1..f58743bc9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.366 2008/04/11 15:36:03 drh Exp $ +** $Id: expr.c,v 1.367 2008/04/15 12:14:22 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -2104,6 +2104,24 @@ int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){ } /* +** If the last instruction coded is an ephemeral copy of any of +** the registers in the nReg registers beginning with iReg, then +** convert the last instruction from OP_SCopy to OP_Copy. +*/ +void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){ + int addr; + VdbeOp *pOp; + Vdbe *v; + + v = pParse->pVdbe; + addr = sqlite3VdbeCurrentAddr(v); + pOp = sqlite3VdbeGetOp(v, addr-1); + if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){ + pOp->opcode = OP_Copy; + } +} + +/* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. @@ -2374,7 +2392,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pList ){ nExpr = pList->nExpr; r1 = sqlite3GetTempRange(pParse, nExpr); - sqlite3ExprCodeExprList(pParse, pList, r1); + sqlite3ExprCodeExprList(pParse, pList, r1, 1); }else{ nExpr = r1 = 0; } @@ -2804,7 +2822,8 @@ void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ - int target /* Where to write results */ + int target, /* Where to write results */ + int doHardCopy /* Call sqlite3ExprHardCopy on each element if true */ ){ struct ExprList_item *pItem; int i, n; @@ -2814,9 +2833,9 @@ int sqlite3ExprCodeExprList( } assert( target>0 ); n = pList->nExpr; - for(pItem=pList->a, i=n; i>0; i--, pItem++){ - sqlite3ExprCode(pParse, pItem->pExpr, target); - target++; + for(pItem=pList->a, i=0; i<n; i++, pItem++){ + sqlite3ExprCode(pParse, pItem->pExpr, target+i); + if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n); } return n; } |