mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
And yet, this fix feels uncomfortable. Seeking an alternative... (CVS 5712) FossilOrigin-Name: f8b759f1977915c314be874840ebf18e6bc69b57
This commit is contained in:
16
manifest
16
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)
|
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-16T18:02:47
|
D 2008-09-17T00:13:12
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329
|
F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -107,7 +107,7 @@ F src/callback.c 7a40fd44da3eb89e7f6eff30aa6f940c45d73a97
|
|||||||
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
||||||
F src/date.c 5c092296c03d658e84884121a694150964d6861d
|
F src/date.c 5c092296c03d658e84884121a694150964d6861d
|
||||||
F src/delete.c bae6684aa02e1f7cf6328023157c91d9cf94200b
|
F src/delete.c bae6684aa02e1f7cf6328023157c91d9cf94200b
|
||||||
F src/expr.c e439afc46c5e859c1d6137fb447f8b5a0c05372f
|
F src/expr.c 04822d5c7af85fd195a5f72501ab5e8d99768fae
|
||||||
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
||||||
F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
|
F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
|
||||||
F src/global.c 20a3fe46c8287a01ba3a7442558f0eb70c66b19a
|
F src/global.c 20a3fe46c8287a01ba3a7442558f0eb70c66b19a
|
||||||
@@ -147,7 +147,7 @@ F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
|
|||||||
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
|
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
|
||||||
F src/random.c 11bbdf7def3746a762fbdb56c9d04648135ad6d8
|
F src/random.c 11bbdf7def3746a762fbdb56c9d04648135ad6d8
|
||||||
F src/resolve.c a6abf83125bce0c80ba04acc27c3565155ad305c
|
F src/resolve.c a6abf83125bce0c80ba04acc27c3565155ad305c
|
||||||
F src/select.c 9cf9aac53aae65ce519310fd86ea3d895a654d79
|
F src/select.c 4d25fe8da35abb5b5317a0248bedc3c9570416e9
|
||||||
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
||||||
F src/sqlite.h.in 81dc1e8e50fb5c7cccf0a67a34cb796efc1d2a1e
|
F src/sqlite.h.in 81dc1e8e50fb5c7cccf0a67a34cb796efc1d2a1e
|
||||||
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
|
||||||
@@ -480,7 +480,7 @@ F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
|
|||||||
F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210
|
F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210
|
||||||
F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
|
F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
|
||||||
F test/selectB.test 31e81ac9af7d224850e0706350f070ecb92fcbc7
|
F test/selectB.test 31e81ac9af7d224850e0706350f070ecb92fcbc7
|
||||||
F test/selectC.test afc5b7bb570c59b17aa0719c51ed0ff53588f8bb
|
F test/selectC.test 44f4e1b2c86e40f8135294a826ec4142766e21c3
|
||||||
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
||||||
F test/shared.test b9f3bbd3ba727c5f1f8c815b7d0199262aacf214
|
F test/shared.test b9f3bbd3ba727c5f1f8c815b7d0199262aacf214
|
||||||
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
|
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
|
||||||
@@ -637,7 +637,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P bd58be6ecf0a22f3c8404bd7094ab5e13e19b1c4
|
P a67da9dd2ff6acc163de4ce2b836b03e3f159a88
|
||||||
R 2fc3441b1258e07766f97b640f95644a
|
R 14978e8fa671319bba1736bf8a70ed4f
|
||||||
U drh
|
U drh
|
||||||
Z e70756170cf6143ba60cbd6ecd5882c4
|
Z 020ff8f35c07f9455927e2b1f65bc01f
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
a67da9dd2ff6acc163de4ce2b836b03e3f159a88
|
f8b759f1977915c314be874840ebf18e6bc69b57
|
||||||
13
src/expr.c
13
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** 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 "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -2456,7 +2456,7 @@ int sqlite3ExprCodeExprList(
|
|||||||
Parse *pParse, /* Parsing context */
|
Parse *pParse, /* Parsing context */
|
||||||
ExprList *pList, /* The expression list to be coded */
|
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 */
|
int doHardCopy /* Make a hard copy of every element */
|
||||||
){
|
){
|
||||||
struct ExprList_item *pItem;
|
struct ExprList_item *pItem;
|
||||||
int i, n;
|
int i, n;
|
||||||
@@ -2464,17 +2464,16 @@ int sqlite3ExprCodeExprList(
|
|||||||
assert( target>0 );
|
assert( target>0 );
|
||||||
n = pList->nExpr;
|
n = pList->nExpr;
|
||||||
for(pItem=pList->a, i=0; i<n; i++, pItem++){
|
for(pItem=pList->a, i=0; i<n; i++, pItem++){
|
||||||
#if 0 /* Remove temporarily for tickets #3378 and #3381 */
|
|
||||||
if( pItem->iAlias ){
|
if( pItem->iAlias ){
|
||||||
int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr);
|
int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr);
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
|
||||||
}else
|
}else{
|
||||||
#endif
|
|
||||||
{
|
|
||||||
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
|
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
|
||||||
}
|
}
|
||||||
if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n);
|
if( doHardCopy ){
|
||||||
|
sqlite3ExprHardCopy(pParse, target, n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|||||||
121
src/select.c
121
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -2047,7 +2047,7 @@ static int multiSelectOrderBy(
|
|||||||
int labelEnd; /* Label for the end of the overall SELECT stmt */
|
int labelEnd; /* Label for the end of the overall SELECT stmt */
|
||||||
int j1; /* Jump instructions that get retargetted */
|
int j1; /* Jump instructions that get retargetted */
|
||||||
int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
|
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 */
|
KeyInfo *pKeyMerge; /* Comparison information for merging rows */
|
||||||
sqlite3 *db; /* Database connection */
|
sqlite3 *db; /* Database connection */
|
||||||
ExprList *pOrderBy; /* The ORDER BY clause */
|
ExprList *pOrderBy; /* The ORDER BY clause */
|
||||||
@@ -3650,20 +3650,25 @@ int sqlite3Select(
|
|||||||
** processed */
|
** processed */
|
||||||
int iAbortFlag; /* Mem address which causes query abort if positive */
|
int iAbortFlag; /* Mem address which causes query abort if positive */
|
||||||
int groupBySort; /* Rows come from source in GROUP BY order */
|
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
|
for(i=p->pEList->nExpr, pItem=p->pEList->a; i>0; i--, pItem++){
|
||||||
** virtual machine program we are putting together */
|
pItem->iAlias = 0;
|
||||||
int addrOutputRow; /* Start of subroutine that outputs a result row */
|
}
|
||||||
int regOutputRow; /* Return address register for output subroutine */
|
for(i=pGroupBy->nExpr, pItem=pGroupBy->a; i>0; i--, pItem++){
|
||||||
int addrSetAbort; /* Set the abort flag and return */
|
pItem->iAlias = 0;
|
||||||
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 */
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a label to jump to when we want to abort the query */
|
||||||
addrEnd = sqlite3VdbeMakeLabel(v);
|
addrEnd = sqlite3VdbeMakeLabel(v);
|
||||||
|
|
||||||
/* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
|
/* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
|
||||||
@@ -3692,11 +3697,14 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
if( pGroupBy ){
|
if( pGroupBy ){
|
||||||
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
|
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
|
||||||
int j1;
|
int j1; /* A-vs-B comparision jump */
|
||||||
|
int addrOutputRow; /* Start of subroutine that outputs a result row */
|
||||||
/* Create labels that we will be needing
|
int regOutputRow; /* Return address register for output subroutine */
|
||||||
*/
|
int addrSetAbort; /* Set the abort flag and return */
|
||||||
addrInitializeLoop = sqlite3VdbeMakeLabel(v);
|
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
|
/* 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
|
** implement it. Allocate that sorting index now. If it turns out
|
||||||
@@ -3713,6 +3721,10 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
iUseFlag = ++pParse->nMem;
|
iUseFlag = ++pParse->nMem;
|
||||||
iAbortFlag = ++pParse->nMem;
|
iAbortFlag = ++pParse->nMem;
|
||||||
|
regOutputRow = ++pParse->nMem;
|
||||||
|
addrOutputRow = sqlite3VdbeMakeLabel(v);
|
||||||
|
regReset = ++pParse->nMem;
|
||||||
|
addrReset = sqlite3VdbeMakeLabel(v);
|
||||||
iAMem = pParse->nMem + 1;
|
iAMem = pParse->nMem + 1;
|
||||||
pParse->nMem += pGroupBy->nExpr;
|
pParse->nMem += pGroupBy->nExpr;
|
||||||
iBMem = pParse->nMem + 1;
|
iBMem = pParse->nMem + 1;
|
||||||
@@ -3721,47 +3733,12 @@ int sqlite3Select(
|
|||||||
VdbeComment((v, "clear abort flag"));
|
VdbeComment((v, "clear abort flag"));
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
|
||||||
VdbeComment((v, "indicate accumulator empty"));
|
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.
|
/* 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
|
** 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
|
** it might be a single loop that uses an index to extract information
|
||||||
** in the right order to begin with.
|
** in the right order to begin with.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrInitializeLoop);
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
||||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0);
|
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0);
|
||||||
if( pWInfo==0 ) goto select_end;
|
if( pWInfo==0 ) goto select_end;
|
||||||
@@ -3879,7 +3856,43 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
|
||||||
VdbeComment((v, "output final row"));
|
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 */
|
} /* endif pGroupBy */
|
||||||
else {
|
else {
|
||||||
ExprList *pMinMax = 0;
|
ExprList *pMinMax = 0;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file implements regression tests for SQLite library.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -117,6 +117,12 @@ do_test selectC-1.13 {
|
|||||||
ORDER BY x
|
ORDER BY x
|
||||||
}
|
}
|
||||||
} {AAA CCC}
|
} {AAA CCC}
|
||||||
|
do_test selectC-1.14 {
|
||||||
|
execsql {
|
||||||
|
SELECT upper(b) AS x
|
||||||
|
FROM t1
|
||||||
|
ORDER BY x DESC
|
||||||
|
}
|
||||||
|
} {CCC AAA AAA}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|||||||
Reference in New Issue
Block a user