1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-08 03:22:21 +03:00

Fix a code generator bug caused by the new CSE optimization. Add test cases

to prevent a recurrence. (CVS 5011)

FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b
This commit is contained in:
drh
2008-04-15 12:14:21 +00:00
parent 5f3a367bf3
commit 191b54cb5d
9 changed files with 117 additions and 32 deletions

View File

@@ -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>
@@ -2103,6 +2103,24 @@ int sqlite3ExprWritableRegister(Parse *pParse, int iCurrent, int iTarget){
return 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".
@@ -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;
}