mirror of https://github.com/sqlite/sqlite
Match ORDER BY terms to columns using names in compound queries. Make sure
this works for subqueries, especially in the right-hand side of an IN operator. Ticket #2296. (CVS 3842) FossilOrigin-Name: cfc6f933dc60ca88ae848f7f0c402e820437c2ff
This commit is contained in:
parent
d215acf1f4
commit
94ccde58d0
16
manifest
16
manifest
|
@ -1,5 +1,5 @@
|
|||
C Fix\sa\sbug\sin\sautovacuum\sintroduced\sby\s(3839).\s(CVS\s3841)
|
||||
D 2007-04-13T04:01:59
|
||||
C Match\sORDER\sBY\sterms\sto\scolumns\susing\snames\sin\scompound\squeries.\s\sMake\ssure\nthis\sworks\sfor\ssubqueries,\sespecially\sin\sthe\sright-hand\sside\sof\san\sIN\noperator.\sTicket\s#2296.\s(CVS\s3842)
|
||||
D 2007-04-13T16:06:33
|
||||
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
|
@ -66,7 +66,7 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
|
|||
F src/date.c 74b76691bddf58b634f6bf4a77c8c58234268c6e
|
||||
F src/delete.c 151d08386bf9c9e7f92f6b9106c71efec2def184
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c a8740c24af3f39f2d502be1a1c640c96435eaac0
|
||||
F src/expr.c 2c32c546006627d70a7b941b318489980fd1912e
|
||||
F src/func.c 007d957c057bb42b0d37aa6ad4be0e1c67a8871b
|
||||
F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5
|
||||
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
|
||||
|
@ -93,7 +93,7 @@ F src/pragma.c 3b992b5b2640d6ae25cef05aa6a42cd1d6c43234
|
|||
F src/prepare.c 37207b2b2ccb41d379b01dd62231686bcc48ef1f
|
||||
F src/printf.c 0c6f40648770831341ac45ab32423a80b4c87f05
|
||||
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
|
||||
F src/select.c bd1742051f3418c2f035371e0dcea741c1907842
|
||||
F src/select.c 4fa2b45a9c19988f295ea118d95ce68a56a00eb4
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 3ae4654560e91220a95738a73d135d91d937cda1
|
||||
F src/sqlite.h.in e429f66f9245c7f8675db24b230c950b8672ad1c
|
||||
|
@ -302,7 +302,7 @@ F test/rowid.test 040a3bef06f970c45f5fcd14b2355f7f4d62f0cf
|
|||
F test/safety.test 4a06934e45d03b8b50ebcd8d174eb0367d2fd851
|
||||
F test/schema.test 8a2ae440fb15f5798a68059e8746402f3137be46
|
||||
F test/schema2.test d815923e57e90b8c60ddf5e0d8fd65075e94f57f
|
||||
F test/select1.test 1287b040f912b979ccc8d4b50ea585eeeacf1835
|
||||
F test/select1.test 1a35bf8201c8a42a44d65acc3e6c9796a9c43dfb
|
||||
F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3
|
||||
F test/select3.test 2d473f45c57c0526833e045fca0537badec0dd04
|
||||
F test/select4.test 305ba0a6e97efc5544def5e5cb49b54e1bf87fd9
|
||||
|
@ -458,7 +458,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 764e7262b93a7a5073128ecd4db265b0c728a701
|
||||
R 31c090858c1e13005c3e16c77f0df139
|
||||
P e39efa195a28f1cd7431b0811bd908dc7af3c8b1
|
||||
R b434a64adc5cd5e0bdd07ca7975fa65b
|
||||
U drh
|
||||
Z 533934c267007014330b5ce7d6a0b1a1
|
||||
Z 8bca189cccc6e2802e95c88c94744665
|
||||
|
|
|
@ -1 +1 @@
|
|||
e39efa195a28f1cd7431b0811bd908dc7af3c8b1
|
||||
cfc6f933dc60ca88ae848f7f0c402e820437c2ff
|
10
src/expr.c
10
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.283 2007/03/27 13:36:37 drh Exp $
|
||||
** $Id: expr.c,v 1.284 2007/04/13 16:06:33 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
|
@ -1420,7 +1420,9 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
int iParm = pExpr->iTable + (((int)affinity)<<16);
|
||||
ExprList *pEList;
|
||||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||
sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
|
||||
if( sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0) ){
|
||||
return;
|
||||
}
|
||||
pEList = pExpr->pSelect->pEList;
|
||||
if( pEList && pEList->nExpr>0 ){
|
||||
keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||
|
@ -1491,7 +1493,9 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
}
|
||||
sqlite3ExprDelete(pSel->pLimit);
|
||||
pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
|
||||
sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
|
||||
if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
33
src/select.c
33
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.335 2007/04/12 21:25:02 drh Exp $
|
||||
** $Id: select.c,v 1.336 2007/04/13 16:06:33 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
@ -1401,8 +1401,11 @@ static int matchOrderbyToColumn(
|
|||
}
|
||||
pEList = pSelect->pEList;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
struct ExprList_item *pItem;
|
||||
Expr *pE = pOrderBy->a[i].pExpr;
|
||||
int iCol = -1;
|
||||
char *zLabel;
|
||||
|
||||
if( pOrderBy->a[i].done ) continue;
|
||||
if( sqlite3ExprIsInteger(pE, &iCol) ){
|
||||
if( iCol<=0 || iCol>pEList->nExpr ){
|
||||
|
@ -1415,20 +1418,21 @@ static int matchOrderbyToColumn(
|
|||
if( !mustComplete ) continue;
|
||||
iCol--;
|
||||
}
|
||||
for(j=0; iCol<0 && j<pEList->nExpr; j++){
|
||||
if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
|
||||
char *zName, *zLabel;
|
||||
zName = pEList->a[j].zName;
|
||||
zLabel = sqlite3NameFromToken(&pE->token);
|
||||
assert( zLabel!=0 );
|
||||
if( sqlite3StrICmp(zName, zLabel)==0 ){
|
||||
iCol = j;
|
||||
if( iCol<0 && (zLabel = sqlite3NameFromToken(&pE->token))!=0 ){
|
||||
for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){
|
||||
char *zName;
|
||||
if( pItem->zName ){
|
||||
zName = sqlite3StrDup(pItem->zName);
|
||||
}else{
|
||||
zName = sqlite3NameFromToken(&pItem->pExpr->token);
|
||||
}
|
||||
sqliteFree(zLabel);
|
||||
}
|
||||
if( iCol<0 && sqlite3ExprCompare(pE, pEList->a[j].pExpr) ){
|
||||
iCol = j;
|
||||
if( zName && sqlite3StrICmp(zName, zLabel)==0 ){
|
||||
iCol = j;
|
||||
break;
|
||||
}
|
||||
sqliteFree(zName);
|
||||
}
|
||||
sqliteFree(zLabel);
|
||||
}
|
||||
if( iCol>=0 ){
|
||||
pE->op = TK_COLUMN;
|
||||
|
@ -1436,8 +1440,7 @@ static int matchOrderbyToColumn(
|
|||
pE->iTable = iTable;
|
||||
pE->iAgg = -1;
|
||||
pOrderBy->a[i].done = 1;
|
||||
}
|
||||
if( iCol<0 && mustComplete ){
|
||||
}else if( mustComplete ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"ORDER BY term number %d does not match any result column", i+1);
|
||||
nErr++;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the SELECT statement.
|
||||
#
|
||||
# $Id: select1.test,v 1.52 2007/04/06 15:02:14 drh Exp $
|
||||
# $Id: select1.test,v 1.53 2007/04/13 16:06:34 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -495,7 +495,45 @@ do_test select1-6.11 {
|
|||
ORDER BY f2+100;
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {0 {f1 11 f1 33 f1 122 f1 144}}
|
||||
} {1 {ORDER BY term number 1 does not match any result column}}
|
||||
|
||||
# Ticket #2296
|
||||
do_test select1-6.20 {
|
||||
execsql {
|
||||
CREATE TABLE t6(a TEXT, b TEXT);
|
||||
INSERT INTO t6 VALUES('a','0');
|
||||
INSERT INTO t6 VALUES('b','1');
|
||||
INSERT INTO t6 VALUES('c','2');
|
||||
INSERT INTO t6 VALUES('d','3');
|
||||
SELECT a FROM t6 WHERE b IN
|
||||
(SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
|
||||
ORDER BY 1 LIMIT 1)
|
||||
}
|
||||
} {a}
|
||||
do_test select1-6.21 {
|
||||
execsql {
|
||||
SELECT a FROM t6 WHERE b IN
|
||||
(SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
|
||||
ORDER BY 1 DESC LIMIT 1)
|
||||
}
|
||||
} {d}
|
||||
do_test select1-6.22 {
|
||||
execsql {
|
||||
SELECT a FROM t6 WHERE b IN
|
||||
(SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
|
||||
ORDER BY b LIMIT 2)
|
||||
ORDER BY a;
|
||||
}
|
||||
} {a b}
|
||||
do_test select1-6.23 {
|
||||
execsql {
|
||||
SELECT a FROM t6 WHERE b IN
|
||||
(SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
|
||||
ORDER BY x DESC LIMIT 2)
|
||||
ORDER BY a;
|
||||
}
|
||||
} {b d}
|
||||
|
||||
} ;#ifcapable compound
|
||||
|
||||
do_test select1-7.1 {
|
||||
|
|
Loading…
Reference in New Issue