Fix a code generator bug caused by the new CSE optimization.  Add test cases
to prevent a recurrence. (CVS 5011)

FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b
diff --git a/src/expr.c b/src/expr.c
index 3002ef7..f58743b 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 @@
 }
 
 /*
+** 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 @@
       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 @@
 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 @@
   }
   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;
 }
diff --git a/src/select.c b/src/select.c
index 89fe2e1..4b9f1df 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.426 2008/04/10 13:33:18 drh Exp $
+** $Id: select.c,v 1.427 2008/04/15 12:14:22 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -422,7 +422,7 @@
   int nExpr = pOrderBy->nExpr;
   int regBase = sqlite3GetTempRange(pParse, nExpr+2);
   int regRecord = sqlite3GetTempReg(pParse);
-  sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
+  sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
   sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
   sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1);
   sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
@@ -580,9 +580,7 @@
     /* If the destination is an EXISTS(...) expression, the actual
     ** values returned by the SELECT are not required.
     */
-    for(i=0; i<nResultCol; i++){
-      sqlite3ExprCode(pParse, pEList->a[i].pExpr, regResult+i);
-    }
+    sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Callback);
   }
   nColumn = nResultCol;
 
@@ -2902,7 +2900,7 @@
     if( pList ){
       nArg = pList->nExpr;
       regAgg = sqlite3GetTempRange(pParse, nArg);
-      sqlite3ExprCodeExprList(pParse, pList, regAgg);
+      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0);
     }else{
       nArg = 0;
       regAgg = 0;
@@ -3432,7 +3430,7 @@
           }
         }
         regBase = sqlite3GetTempRange(pParse, nCol);
-        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase);
+        sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
         sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
         j = nGroupBy+1;
         for(i=0; i<sAggInfo.nColumn; i++){
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b6f5b1e..6ff5b1f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.691 2008/04/10 16:47:42 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.692 2008/04/15 12:14:22 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1872,12 +1872,13 @@
 void sqlite3ExprClearColumnCache(Parse*, int);
 void sqlite3ExprCacheAffinityChange(Parse*, int, int);
 int sqlite3ExprWritableRegister(Parse*,int,int);
+void sqlite3ExprHardCopy(Parse*,int,int);
 int sqlite3ExprCode(Parse*, Expr*, int);
 int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
 int sqlite3ExprCodeTarget(Parse*, Expr*, int);
 int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
 void sqlite3ExprCodeConstants(Parse*, Expr*);
-int sqlite3ExprCodeExprList(Parse*, ExprList*, int);
+int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
 void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
 void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
 Table *sqlite3FindTable(sqlite3*,const char*, const char*);
diff --git a/src/test_func.c b/src/test_func.c
index 478474c..50d7bd6 100644
--- a/src/test_func.c
+++ b/src/test_func.c
@@ -12,7 +12,7 @@
 ** Code for testing all sorts of SQLite interfaces.  This code
 ** implements new SQL functions used by the test scripts.
 **
-** $Id: test_func.c,v 1.4 2008/04/10 17:14:07 drh Exp $
+** $Id: test_func.c,v 1.5 2008/04/15 12:14:22 drh Exp $
 */
 #include "sqlite3.h"
 #include "tcl.h"
@@ -204,6 +204,33 @@
   }
 }
 
+/*
+** This function takes two arguments.  It performance UTF-8/16 type
+** conversions on the first argument then returns a copy of the second
+** argument.
+**
+** This function is used in cases such as the following:
+**
+**      SELECT test_isolation(x,x) FROM t1;
+**
+** We want to verify that the type conversions that occur on the
+** first argument do not invalidate the second argument.
+*/
+static void test_isolation(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **argv
+){
+#ifndef SQLITE_OMIT_UTF16
+  sqlite3_value_text16(argv[0]);
+  sqlite3_value_text(argv[0]);
+  sqlite3_value_text16(argv[0]);
+  sqlite3_value_text(argv[0]);
+#endif
+  sqlite3_result_value(pCtx, argv[1]);
+}
+
+
 static int registerTestFunctions(sqlite3 *db){
   static const struct {
      char *zName;
@@ -218,6 +245,7 @@
     { "test_auxdata",         -1, SQLITE_UTF8, test_auxdata},
     { "test_error",            1, SQLITE_UTF8, test_error},
     { "test_error",            2, SQLITE_UTF8, test_error},
+    { "test_isolation",        2, SQLITE_UTF8, test_isolation},
   };
   int i;
   extern int Md5_Register(sqlite3*);
diff --git a/src/vdbe.c b/src/vdbe.c
index 7a45f64..07bd6b9 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.729 2008/04/10 14:00:10 drh Exp $
+** $Id: vdbe.c,v 1.730 2008/04/15 12:14:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -880,6 +880,7 @@
     if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
     pOut->zMalloc = 0;
     pOut->flags |= MEM_Static;
+    pOut->flags &= ~MEM_Dyn;
     if( pOp->p4type==P4_DYNAMIC ){
       sqlite3_free(pOp->p4.z);
     }