Disable the result-set alias cache when on conditional code branches.
Ticket #3461. The column cache and result set alias cache mechanisms are
prone to this kind of error and need to be refactored. This check-in should
be considered a temporary fix in advance of a more general redesign of the
whole mechanism. (CVS 5841)
FossilOrigin-Name: 1fa3bbd8220ce073e91935ea362b6f5d5d6d2859
diff --git a/src/expr.c b/src/expr.c
index 52f7cdb..10393e0 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.399 2008/10/11 16:47:36 drh Exp $
+** $Id: expr.c,v 1.400 2008/10/25 15:03:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1718,7 +1718,7 @@
** of the iAlias-th alias is stored. If zero, that means that the
** alias has not yet been computed.
*/
-static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr){
+static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){
sqlite3 *db = pParse->db;
int iReg;
if( pParse->aAlias==0 ){
@@ -1729,9 +1729,13 @@
assert( iAlias>0 && iAlias<=pParse->nAlias );
iReg = pParse->aAlias[iAlias-1];
if( iReg==0 ){
- iReg = ++pParse->nMem;
- sqlite3ExprCode(pParse, pExpr, iReg);
- pParse->aAlias[iAlias-1] = iReg;
+ if( pParse->disableColCache ){
+ iReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
+ }else{
+ iReg = ++pParse->nMem;
+ sqlite3ExprCode(pParse, pExpr, iReg);
+ pParse->aAlias[iAlias-1] = iReg;
+ }
}
return iReg;
}
@@ -1840,7 +1844,7 @@
break;
}
case TK_AS: {
- inReg = codeAlias(pParse, pExpr->iTable, pExpr->pLeft);
+ inReg = codeAlias(pParse, pExpr->iTable, pExpr->pLeft, target);
break;
}
#ifndef SQLITE_OMIT_CAST
@@ -2500,9 +2504,11 @@
n = pList->nExpr;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
if( pItem->iAlias ){
- int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr);
+ int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr, target+i);
Vdbe *v = sqlite3GetVdbe(pParse);
- sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
+ if( iReg!=target+i ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
+ }
}else{
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
}