]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix for tickets #3378 and #3381 that preserves the aliasing optimization.
authordrh <drh@noemail.net>
Wed, 17 Sep 2008 00:13:12 +0000 (00:13 +0000)
committerdrh <drh@noemail.net>
Wed, 17 Sep 2008 00:13:12 +0000 (00:13 +0000)
And yet, this fix feels uncomfortable.  Seeking an alternative... (CVS 5712)

FossilOrigin-Name: f8b759f1977915c314be874840ebf18e6bc69b57

manifest
manifest.uuid
src/expr.c
src/select.c
test/selectC.test

index 40f4d772e0804bfe8953ba04d53818cd543db616..b53f3717cf88d5112a2773b20d81044db651874e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stest\scases\sfor\sticket\s#3378\sand\s#3381.\s\sAdd\sa\stemporary\shack\sto\sget\sthose\nto\sproblems\sfixed.\s\sThe\shack\scauses\sfailures\sin\salias.test,\sbut\sthose\sare\smuch\nless\sserious\sthan\sthe\saforementioned\stickets.\s\sThis\sis\sa\sstop-gap\suntil\swe\scan\nfigure\sout\sa\sproper\sfix.\s(CVS\s5711)
-D 2008-09-16T18:02:47
+C Fix\sfor\stickets\s#3378\sand\s#3381\sthat\spreserves\sthe\saliasing\soptimization.\nAnd\syet,\sthis\sfix\sfeels\suncomfortable.\s\sSeeking\san\salternative...\s(CVS\s5712)
+D 2008-09-17T00:13:12
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -107,7 +107,7 @@ F src/callback.c 7a40fd44da3eb89e7f6eff30aa6f940c45d73a97
 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
 F src/date.c 5c092296c03d658e84884121a694150964d6861d
 F src/delete.c bae6684aa02e1f7cf6328023157c91d9cf94200b
-F src/expr.c e439afc46c5e859c1d6137fb447f8b5a0c05372f
+F src/expr.c 04822d5c7af85fd195a5f72501ab5e8d99768fae
 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
 F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
 F src/global.c 20a3fe46c8287a01ba3a7442558f0eb70c66b19a
@@ -147,7 +147,7 @@ F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
 F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
 F src/random.c 11bbdf7def3746a762fbdb56c9d04648135ad6d8
 F src/resolve.c a6abf83125bce0c80ba04acc27c3565155ad305c
-F src/select.c 9cf9aac53aae65ce519310fd86ea3d895a654d79
+F src/select.c 4d25fe8da35abb5b5317a0248bedc3c9570416e9
 F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
 F src/sqlite.h.in 81dc1e8e50fb5c7cccf0a67a34cb796efc1d2a1e
 F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
@@ -480,7 +480,7 @@ F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
 F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210
 F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
 F test/selectB.test 31e81ac9af7d224850e0706350f070ecb92fcbc7
-F test/selectC.test afc5b7bb570c59b17aa0719c51ed0ff53588f8bb
+F test/selectC.test 44f4e1b2c86e40f8135294a826ec4142766e21c3
 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
 F test/shared.test b9f3bbd3ba727c5f1f8c815b7d0199262aacf214
 F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
@@ -637,7 +637,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P bd58be6ecf0a22f3c8404bd7094ab5e13e19b1c4
-R 2fc3441b1258e07766f97b640f95644a
+P a67da9dd2ff6acc163de4ce2b836b03e3f159a88
+R 14978e8fa671319bba1736bf8a70ed4f
 U drh
-Z e70756170cf6143ba60cbd6ecd5882c4
+Z 020ff8f35c07f9455927e2b1f65bc01f
index 17587d03ee3c64a573ba27666cdf24b7cbe6cb06..31500ab308ff3b3b6e601bd3808fed7e0b881242 100644 (file)
@@ -1 +1 @@
-a67da9dd2ff6acc163de4ce2b836b03e3f159a88
\ No newline at end of file
+f8b759f1977915c314be874840ebf18e6bc69b57
\ No newline at end of file
index 3d742cd9c87545be3579a2d5cb26a575b2cb7d7d..ab0cf1e3183d4da0dffcd41d244f481fcd3ba7d3 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.393 2008/09/16 18:02:47 drh Exp $
+** $Id: expr.c,v 1.394 2008/09/17 00:13:12 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2456,7 +2456,7 @@ int sqlite3ExprCodeExprList(
   Parse *pParse,     /* Parsing context */
   ExprList *pList,   /* The expression list to be coded */
   int target,        /* Where to write results */
-  int doHardCopy     /* Call sqlite3ExprHardCopy on each element if true */
+  int doHardCopy     /* Make a hard copy of every element */
 ){
   struct ExprList_item *pItem;
   int i, n;
@@ -2464,17 +2464,16 @@ int sqlite3ExprCodeExprList(
   assert( target>0 );
   n = pList->nExpr;
   for(pItem=pList->a, i=0; i<n; i++, pItem++){
-#if 0  /* Remove temporarily for tickets #3378 and #3381 */
     if( pItem->iAlias ){
       int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr);
       Vdbe *v = sqlite3GetVdbe(pParse);
       sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
-    }else
-#endif
-    {
+    }else{
       sqlite3ExprCode(pParse, pItem->pExpr, target+i);
     }
-    if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n);
+    if( doHardCopy ){
+      sqlite3ExprHardCopy(pParse, target, n);
+    }
   }
   return n;
 }
index c3442a2cd2efa482d28cdd68942d6b60d6cc8161..5871491c44d8c1de9590fad009a78738be7bdf18 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.474 2008/09/16 15:55:56 danielk1977 Exp $
+** $Id: select.c,v 1.475 2008/09/17 00:13:12 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -2047,7 +2047,7 @@ static int multiSelectOrderBy(
   int labelEnd;         /* Label for the end of the overall SELECT stmt */
   int j1;               /* Jump instructions that get retargetted */
   int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
-  KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
+  KeyInfo *pKeyDup;     /* Comparison information for duplicate removal */
   KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
   sqlite3 *db;          /* Database connection */
   ExprList *pOrderBy;   /* The ORDER BY clause */
@@ -3650,20 +3650,25 @@ int sqlite3Select(
                         ** processed */
     int iAbortFlag;     /* Mem address which causes query abort if positive */
     int groupBySort;    /* Rows come from source in GROUP BY order */
+    int addrEnd;        /* End of processing for this SELECT */
 
+    /* Remove any and all aliases between the result set and the
+    ** GROUP BY clause.
+    */
+    if( pGroupBy ){
+      int i;                        /* Loop counter */
+      struct ExprList_item *pItem;  /* For looping over expression in a list */
 
-    /* The following variables hold addresses or labels for parts of the
-    ** virtual machine program we are putting together */
-    int addrOutputRow;      /* Start of subroutine that outputs a result row */
-    int regOutputRow;       /* Return address register for output subroutine */
-    int addrSetAbort;       /* Set the abort flag and return */
-    int addrInitializeLoop; /* Start of code that initializes the input loop */
-    int addrTopOfLoop;      /* Top of the input loop */
-    int addrEnd;            /* End of all processing */
-    int addrSortingIdx;     /* The OP_OpenEphemeral for the sorting index */
-    int addrReset;          /* Subroutine for resetting the accumulator */
-    int regReset;           /* Return address register for reset subroutine */
+      for(i=p->pEList->nExpr, pItem=p->pEList->a; i>0; i--, pItem++){
+        pItem->iAlias = 0;
+      }
+      for(i=pGroupBy->nExpr, pItem=pGroupBy->a; i>0; i--, pItem++){
+        pItem->iAlias = 0;
+      }
+    }
 
+    /* Create a label to jump to when we want to abort the query */
     addrEnd = sqlite3VdbeMakeLabel(v);
 
     /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
@@ -3692,11 +3697,14 @@ int sqlite3Select(
     */
     if( pGroupBy ){
       KeyInfo *pKeyInfo;  /* Keying information for the group by clause */
-      int j1;
-
-      /* Create labels that we will be needing
-      */
-      addrInitializeLoop = sqlite3VdbeMakeLabel(v);
+      int j1;             /* A-vs-B comparision jump */
+      int addrOutputRow;  /* Start of subroutine that outputs a result row */
+      int regOutputRow;   /* Return address register for output subroutine */
+      int addrSetAbort;   /* Set the abort flag and return */
+      int addrTopOfLoop;  /* Top of the input loop */
+      int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
+      int addrReset;      /* Subroutine for resetting the accumulator */
+      int regReset;       /* Return address register for reset subroutine */
 
       /* If there is a GROUP BY clause we might need a sorting index to
       ** implement it.  Allocate that sorting index now.  If it turns out
@@ -3713,6 +3721,10 @@ int sqlite3Select(
       */
       iUseFlag = ++pParse->nMem;
       iAbortFlag = ++pParse->nMem;
+      regOutputRow = ++pParse->nMem;
+      addrOutputRow = sqlite3VdbeMakeLabel(v);
+      regReset = ++pParse->nMem;
+      addrReset = sqlite3VdbeMakeLabel(v);
       iAMem = pParse->nMem + 1;
       pParse->nMem += pGroupBy->nExpr;
       iBMem = pParse->nMem + 1;
@@ -3721,47 +3733,12 @@ int sqlite3Select(
       VdbeComment((v, "clear abort flag"));
       sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
       VdbeComment((v, "indicate accumulator empty"));
-      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInitializeLoop);
-
-      /* Generate a subroutine that outputs a single row of the result
-      ** set.  This subroutine first looks at the iUseFlag.  If iUseFlag
-      ** is less than or equal to zero, the subroutine is a no-op.  If
-      ** the processing calls for the query to abort, this subroutine
-      ** increments the iAbortFlag memory location before returning in
-      ** order to signal the caller to abort.
-      */
-      addrSetAbort = sqlite3VdbeCurrentAddr(v);
-      sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
-      VdbeComment((v, "set abort flag"));
-      regOutputRow = ++pParse->nMem;
-      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
-      addrOutputRow = sqlite3VdbeCurrentAddr(v);
-      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
-      VdbeComment((v, "Groupby result generator entry point"));
-      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
-      finalizeAggFunctions(pParse, &sAggInfo);
-      if( pHaving ){
-        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
-      }
-      selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
-                      distinct, pDest,
-                      addrOutputRow+1, addrSetAbort);
-      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
-      VdbeComment((v, "end groupby result generator"));
-
-      /* Generate a subroutine that will reset the group-by accumulator
-      */
-      addrReset = sqlite3VdbeCurrentAddr(v);
-      regReset = ++pParse->nMem;
-      resetAccumulator(pParse, &sAggInfo);
-      sqlite3VdbeAddOp1(v, OP_Return, regReset);
 
       /* Begin a loop that will extract all source rows in GROUP BY order.
       ** This might involve two separate loops with an OP_Sort in between, or
       ** it might be a single loop that uses an index to extract information
       ** in the right order to begin with.
       */
-      sqlite3VdbeResolveLabel(v, addrInitializeLoop);
       sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0);
       if( pWInfo==0 ) goto select_end;
@@ -3879,7 +3856,43 @@ int sqlite3Select(
       */
       sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
       VdbeComment((v, "output final row"));
-      
+
+      /* Jump over the subroutines
+      */
+      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
+
+      /* Generate a subroutine that outputs a single row of the result
+      ** set.  This subroutine first looks at the iUseFlag.  If iUseFlag
+      ** is less than or equal to zero, the subroutine is a no-op.  If
+      ** the processing calls for the query to abort, this subroutine
+      ** increments the iAbortFlag memory location before returning in
+      ** order to signal the caller to abort.
+      */
+      addrSetAbort = sqlite3VdbeCurrentAddr(v);
+      sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
+      VdbeComment((v, "set abort flag"));
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+      sqlite3VdbeResolveLabel(v, addrOutputRow);
+      addrOutputRow = sqlite3VdbeCurrentAddr(v);
+      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
+      VdbeComment((v, "Groupby result generator entry point"));
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+      finalizeAggFunctions(pParse, &sAggInfo);
+      if( pHaving ){
+        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
+      }
+      selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
+                      distinct, pDest,
+                      addrOutputRow+1, addrSetAbort);
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+      VdbeComment((v, "end groupby result generator"));
+
+      /* Generate a subroutine that will reset the group-by accumulator
+      */
+      sqlite3VdbeResolveLabel(v, addrReset);
+      resetAccumulator(pParse, &sAggInfo);
+      sqlite3VdbeAddOp1(v, OP_Return, regReset);
+     
     } /* endif pGroupBy */
     else {
       ExprList *pMinMax = 0;
index cc3e83218b20f8b247cf5c0e77ec106e187a4cef..d35ca569e0b72d879039d7db160512c396c17326 100644 (file)
@@ -10,7 +10,7 @@
 #***********************************************************************
 # This file implements regression tests for SQLite library. 
 #
-# $Id: selectC.test,v 1.2 2008/09/16 18:02:47 drh Exp $
+# $Id: selectC.test,v 1.3 2008/09/17 00:13:12 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -117,6 +117,12 @@ do_test selectC-1.13 {
      ORDER BY x
   }
 } {AAA CCC}
-
+do_test selectC-1.14 {
+  execsql {
+    SELECT upper(b) AS x
+      FROM t1
+     ORDER BY x DESC
+  }
+} {CCC AAA AAA}
 
 finish_test