-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
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
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
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
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
** 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"
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 */
** 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
*/
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
*/
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;
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;
*/
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;