]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a code generator bug caused by the new CSE optimization. Add test cases
authordrh <drh@noemail.net>
Tue, 15 Apr 2008 12:14:21 +0000 (12:14 +0000)
committerdrh <drh@noemail.net>
Tue, 15 Apr 2008 12:14:21 +0000 (12:14 +0000)
to prevent a recurrence. (CVS 5011)

FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b

manifest
manifest.uuid
src/expr.c
src/select.c
src/sqliteInt.h
src/test_func.c
src/vdbe.c
test/capi3c.test
test/func.test

index 2b8053dd66992f09d0ee97ed0d4a8b5dbcacfb64..88b791ee169f803d2e67260734971cb493c23837 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbug\sin\sthe\sRTRIM\scollating\ssequence\sdiscovered\swhile\sworking\non\scondition/decision\sbranch\scoverage.\s\sIncrease\stest\scoverage\sof\nthe\sdate/time\sfunctions.\s(CVS\s5010)
-D 2008-04-15T04:02:41
+C Fix\sa\scode\sgenerator\sbug\scaused\sby\sthe\snew\sCSE\soptimization.\s\sAdd\stest\scases\nto\sprevent\sa\srecurrence.\s(CVS\s5011)
+D 2008-04-15T12:14:22
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -95,7 +95,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
 F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
 F src/delete.c 555cedf9e59db9ead1c2f8db0c4344201ea7caaa
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 4b6cc2496999bda069a9e00db9c2d7ccdf01a129
+F src/expr.c 7aecda0fb4f078718281a9b56993677c1f45a399
 F src/fault.c 83057e86815d473e526f7df0b0108dfdd022ff23
 F src/func.c c9e8c7ff4c45027edee89bde7adbf86a3a3b2afe
 F src/hash.c 522a8f5a23cf18fe5845afee7263c5be76c25ca2
@@ -135,12 +135,12 @@ F src/pragma.c e659c9e443d11854cff2fd250012365ae0ca81ba
 F src/prepare.c adc7e1fc08dfbab63cd213d4c0aff8f3fa70d477
 F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
 F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
-F src/select.c 1abe53c844f536a79cc11b19127c8e6d47a87b20
+F src/select.c 5b8824a326a923876827fa8771c5e4e9e3a7faa1
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
 F src/sqlite.h.in 824f823b341e9c979f82edebf710c87b74d1b7f5
 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
-F src/sqliteInt.h 6e6e847b7315e9609ab79dba6d68748b7ad3e214
+F src/sqliteInt.h ef381f6a169d824e8ba54a389187836c4cd48420
 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
 F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
 F src/tclsqlite.c c4892f48927cb3db19faeb448ea8abddfd4846a8
@@ -158,7 +158,7 @@ F src/test_autoext.c 5e892ab84aece3f0428920bf46923f16ac83962a
 F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
 F src/test_config.c b910754c5ba311abf149457cdbfd66144e715b35
 F src/test_devsym.c cee1aecaa90c895030399ca4ae38f84a08038f8a
-F src/test_func.c ef4ef3230b6346031bca2762bbc8b95ec7e0451a
+F src/test_func.c f4aafa10f17d52c43a64b47717265802e6e552b3
 F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
 F src/test_malloc.c c92a65e8f9b31bb2b332448d92d2016c000a963d
@@ -175,7 +175,7 @@ F src/update.c d6f214aad7eab5aaec5f966058b0828b3f7d6706
 F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b
 F src/util.c 8b17ea7ad27914c6e2c4a377ca7db743fb7e29a8
 F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
-F src/vdbe.c 444ab9ecc91f3c04b2b29ae604458426aa674fa6
+F src/vdbe.c e4a3df1221a8ee8025c7132cf8ab6bc88eae4e02
 F src/vdbe.h bfd84bda447f39cb599302c7ec85067dae20453c
 F src/vdbeInt.h 0b96efdeecb0803e504bf1c16b198f87c91d6019
 F src/vdbeapi.c 0e1b5a808bb0e556f2a975eb7d11fd3153e922bf
@@ -221,7 +221,7 @@ F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
 F test/capi2.test cc64df7560a96f848f919ea2926c60acf639684b
 F test/capi3.test 8113010cd06a94b7ac72524858968069b7cac8e3
 F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
-F test/capi3c.test d704c1b9dff6a2749c758845d1a0358155642484
+F test/capi3c.test c024e42d2341026ddffd79a7dd864c3555d06ccd
 F test/cast.test ce8f14fc80f70b30ed984480cc0d8914a459e8f9
 F test/check.test 024ed399600b799160378cf9d9f436bdf5dfd184
 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
@@ -322,7 +322,7 @@ F test/fts3ao.test 0aa29dd4fc1c8d46b1f7cfe5926f7ac97551bea9
 F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
 F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a
 F test/fts3near.test 2d4dadcaac5025ab65bb87e66c45f39e92966194
-F test/func.test 4ae1fb477bb6dbeba9ae8d09f258663c29d2f4aa
+F test/func.test 5227e6e6e9df33f5e771ef164f634b7d4f6d6a55
 F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a
 F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb
 F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731
@@ -629,7 +629,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P b7ffc6f0f33b14430ab84a6c60110bc07514f056
-R 39eb77e983bc30708ab7dd070f56763f
+P c5435f71efa0b34c759bac4a15fdf43abf39ddfc
+R 6394eb4f4998e17e7d31653fe6234a16
 U drh
-Z c185fe19fbf753e76e5d68ad2182c5d1
+Z de8ad5aae1cda6ab722570506572bc31
index 1897bf45fa5f6470e5b33572121219456a028440..2cd40deeccb2407764322eb4059c60cec6144313 100644 (file)
@@ -1 +1 @@
-c5435f71efa0b34c759bac4a15fdf43abf39ddfc
\ No newline at end of file
+d04246a46399e839e70b1bd57e209f80143f0d5b
\ No newline at end of file
index 3002ef7b184426a55c11a0c4dec864afde1599e7..f58743bc9857ad3dea2e764b6968d1ab98e5f61d 100644 (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;
 }
index 89fe2e13e976b2d4b9b65aa7e6d3736d0b383376..4b9f1dfd9657a9a5c94df9a0b98ee4f801937269 100644 (file)
@@ -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 @@ static void pushOntoSorter(
   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 @@ static void selectInnerLoop(
     /* 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 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
     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 @@ int sqlite3Select(
           }
         }
         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++){
index b6f5b1ef66cef6abd79265c41f9f5886821878c3..6ff5b1f4bdedeb929bc49c8efaae5a1f525127fe 100644 (file)
@@ -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 sqlite3ExprCodeMove(Parse*, int, int);
 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*);
index 478474cbe16b3ac7181466b977b24681086cc29d..50d7bd60cec6de8a4791a20f4e7d2ddd140776f4 100644 (file)
@@ -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 @@ static void test_error(
   }
 }
 
+/*
+** 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 @@ static int registerTestFunctions(sqlite3 *db){
     { "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*);
index 7a45f6416340241e80c05d2a74e3df44d1df799c..07bd6b99fcc293f87327079e9a00ac86a116f548 100644 (file)
@@ -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 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */
     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);
     }
index 5cb9ad3c9209dafc7bc0ddcb02e331f2b3de5374..c22fb68d3be3539d02aadf19a2b3060d38808a71 100644 (file)
@@ -13,7 +13,7 @@
 # This is a copy of the capi3.test file that has been adapted to
 # test the new sqlite3_prepare_v2 interface.
 #
-# $Id: capi3c.test,v 1.17 2008/04/10 17:14:07 drh Exp $
+# $Id: capi3c.test,v 1.18 2008/04/15 12:14:22 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -1266,5 +1266,36 @@ do_test capi3c-22.3 {
 } {SQLITE_EMPTY}
 sqlite3_finalize $STMT
 
+# For a multi-column result set where the same table column is repeated
+# in multiple columns of the output, verify that doing a UTF-8 to UTF-16
+# conversion (or vice versa) on one column does not change the value of
+# the second.
+#
+do_test capi3c-23.1 {
+  set STMT [sqlite3_prepare_v2 db {SELECT b,b,b,b FROM t1} -1 TAIL]
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3c-23.2 {
+  sqlite3_column_text16 $STMT 0
+  sqlite3_column_text $STMT 1
+} {one}
+do_test capi3c-23.3 {
+  sqlite3_column_text16 $STMT 2
+  sqlite3_column_text $STMT 3
+} {one}
+sqlite3_finalize $STMT
+do_test capi3c-23.4 {
+  set STMT [sqlite3_prepare_v2 db {SELECT b||'x',b,b,b FROM t1} -1 TAIL]
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3c-23.5 {
+  sqlite3_column_text16 $STMT 0
+  sqlite3_column_text $STMT 1
+} {one}
+do_test capi3c-23.6 {
+  sqlite3_column_text16 $STMT 2
+  sqlite3_column_text $STMT 3
+} {one}
+sqlite3_finalize $STMT
 
 finish_test
index 1690e814a9e40e59a021640a719edecf27b97c72..806ee8fd1bb82259dc48494fadfb4a5e7943b5a4 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing built-in functions.
 #
-# $Id: func.test,v 1.76 2008/04/10 17:14:07 drh Exp $
+# $Id: func.test,v 1.77 2008/04/15 12:14:22 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -930,4 +930,11 @@ do_test func-24.6 {
   }
 } {BEGIN-this,program,is,free,software}
 
+# Use the test_isolation function to make sure that type conversions
+# on function arguments do not effect subsequent arguments.
+#
+do_test func-25.1 {
+  execsql {SELECT test_isolation(t1,t1) FROM tbl1}
+} {this program is free software}
+
 finish_test