ORDER BY in a compound SELECT will first match against the left-most SELECT.
If there is no match there, it begins working its way to the right. (CVS 4621) FossilOrigin-Name: 56063ec84b130bcdb0e90bc76fabca394d0d867f
This commit is contained in:
parent
9a99334d54
commit
1e281291fb
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Towards\sgetting\sORDER\sBY\sto\smatch\sagainst\sthe\scorrectin\scolumns.\nThis\sversion\sonly\slooks\sat\sthe\sleft-most\scolumn\sin\sa\scompound\sSELECT.\nThat\sis\sthe\scorrect\sthing\sto\sdo,\sbut\snot\swhat\sSQLite\shas\shistorically\sdone.\s(CVS\s4620)
|
||||
D 2007-12-13T02:45:31
|
||||
C ORDER\sBY\sin\sa\scompound\sSELECT\swill\sfirst\smatch\sagainst\sthe\sleft-most\sSELECT.\nIf\sthere\sis\sno\smatch\sthere,\sit\sbegins\sworking\sits\sway\sto\sthe\sright.\s(CVS\s4621)
|
||||
D 2007-12-13T03:45:08
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in 0590398f62fc2c456ff4c45e9741f5a718b7e2ac
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -131,12 +131,12 @@ F src/pragma.c 0246032dbe681dded8710ac43eaf654eead1434e
|
||||
F src/prepare.c f811fdb6fd4a82cca673a6e1d5b041d6caf567f1
|
||||
F src/printf.c 5732e393c45be7c09bfca9a786daef017e0066ef
|
||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||
F src/select.c 63cc67c9a9cc3f32ec2205d2c769d94cd2fc6f60
|
||||
F src/select.c c2de6d7ba6f98d83e03dabc405e46f439cb37f20
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c c97be281cfc3dcb14902f45e4b16f20038eb83ff
|
||||
F src/sqlite.h.in b16a7127dad4a3e5b1b26b3d64241f3373aa12ea
|
||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||
F src/sqliteInt.h 5c390e902c88648035110d0fe156a279dcace271
|
||||
F src/sqliteInt.h 445530263725d19d6315f137f234aea08ad59303
|
||||
F src/sqliteLimit.h 3657c8eb75addce54a46354a29050a9673845a85
|
||||
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
||||
@ -389,7 +389,7 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test 3fbd0a9e3dd03331d9d76acd47bc179e1a97e15e
|
||||
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||
F test/null.test 93e48033673841240f137fd621317cc73b69eeb8
|
||||
F test/null.test 6adcb4efd433e02c60499f96328014de87cff8b1
|
||||
F test/onefile.test b9cce375fd2a41ee3afa79a0a808954046b74458
|
||||
F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df
|
||||
F test/pager.test 60303481b22b240c18d6dd1b64edcecc2f4b5a97
|
||||
@ -414,7 +414,7 @@ F test/schema2.test 35e1c9696443d6694c8980c411497c2b5190d32e
|
||||
F test/select1.test 79784038f0e7df66bb420e149c6fb91e61e11fb7
|
||||
F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3
|
||||
F test/select3.test 47439f28862489626b483b0c718cfb0562e6f6d5
|
||||
F test/select4.test 2dd28cfea6f50281fb29cf136cf50df8ead6a5d2
|
||||
F test/select4.test 566b4ca1152e16d7090d76f98d93c80b9a1f6c53
|
||||
F test/select5.test 0b47058d3e916c1fc9fe81f44b438e02bade21ce
|
||||
F test/select6.test 399f14b9ba37b768afe5d2cd8c12e4f340a69db8
|
||||
F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f
|
||||
@ -600,7 +600,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P c0689409320de1532be0c0cae12b4b716f6bffb9
|
||||
R 1ec374c4daffe98452f78ad79abdb48f
|
||||
P bbddf16ac9539c7d48adfc73c5a90eecb8df6865
|
||||
R 377fa996f832a29c87d12a5f182c500b
|
||||
U drh
|
||||
Z 92df68b2adbb4d9afb7d6635a4dfe3d8
|
||||
Z f7fa31d1f83b3a0d837ffef0df0c17c3
|
||||
|
@ -1 +1 @@
|
||||
bbddf16ac9539c7d48adfc73c5a90eecb8df6865
|
||||
56063ec84b130bcdb0e90bc76fabca394d0d867f
|
84
src/select.c
84
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.366 2007/12/13 02:45:31 drh Exp $
|
||||
** $Id: select.c,v 1.367 2007/12/13 03:45:08 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -1486,7 +1486,12 @@ static int matchOrderByTermToExprList(
|
||||
nc.allowAgg = 1;
|
||||
nc.nErr = 0;
|
||||
if( sqlite3ExprResolveNames(&nc, pE) ){
|
||||
return -1;
|
||||
if( isCompound ){
|
||||
sqlite3ErrorClear(pParse);
|
||||
return 0;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if( nc.hasAgg && pHasAgg ){
|
||||
*pHasAgg = 1;
|
||||
@ -1501,12 +1506,8 @@ static int matchOrderByTermToExprList(
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
|
||||
"column in the result set of the left-most SELECT", idx);
|
||||
return -1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1593,6 +1594,8 @@ static int processCompoundOrderBy(
|
||||
int i;
|
||||
ExprList *pOrderBy;
|
||||
ExprList *pEList;
|
||||
sqlite3 *db;
|
||||
int moreToDo = 1;
|
||||
|
||||
pOrderBy = pSelect->pOrderBy;
|
||||
if( pOrderBy==0 ) return 0;
|
||||
@ -1600,31 +1603,58 @@ static int processCompoundOrderBy(
|
||||
sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
|
||||
return 1;
|
||||
}
|
||||
db = pParse->db;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
pOrderBy->a[i].done = 0;
|
||||
}
|
||||
while( pSelect->pPrior ){
|
||||
pSelect = pSelect->pPrior;
|
||||
}
|
||||
pEList = pSelect->pEList;
|
||||
if( pEList==0 ){
|
||||
return 1;
|
||||
while( pSelect && moreToDo ){
|
||||
moreToDo = 0;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
int iCol;
|
||||
Expr *pE;
|
||||
if( pOrderBy->a[i].done ) continue;
|
||||
pE = pOrderBy->a[i].pExpr;
|
||||
Expr *pDup = sqlite3ExprDup(db, pE);
|
||||
if( pDup==0 ){
|
||||
return 1;
|
||||
}
|
||||
iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
|
||||
sqlite3ExprDelete(pDup);
|
||||
if( iCol<0 ){
|
||||
return 1;
|
||||
}
|
||||
pEList = pSelect->pEList;
|
||||
if( pEList==0 ){
|
||||
return 1;
|
||||
}
|
||||
if( iCol>pEList->nExpr ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%r ORDER BY term out of range - should be "
|
||||
"between 1 and %d", i+1, pEList->nExpr);
|
||||
return 1;
|
||||
}
|
||||
if( iCol>0 ){
|
||||
pE->op = TK_COLUMN;
|
||||
pE->iTable = iTable;
|
||||
pE->iAgg = -1;
|
||||
pE->iColumn = iCol-1;
|
||||
pE->pTab = 0;
|
||||
pOrderBy->a[i].done = 1;
|
||||
}else{
|
||||
moreToDo = 1;
|
||||
}
|
||||
}
|
||||
pSelect = pSelect->pNext;
|
||||
}
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
int iCol;
|
||||
Expr *pE = pOrderBy->a[i].pExpr;
|
||||
iCol = matchOrderByTermToExprList(pParse, pSelect, pE, i+1, 1, 0);
|
||||
if( iCol<0 ){
|
||||
if( pOrderBy->a[i].done==0 ){
|
||||
sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
|
||||
"column in the result set", i+1);
|
||||
return 1;
|
||||
}
|
||||
if( iCol>pEList->nExpr ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%r ORDER BY term out of range - should be "
|
||||
"between 1 and %d", i+1, pEList->nExpr);
|
||||
return 1;
|
||||
}
|
||||
pE->op = TK_COLUMN;
|
||||
pE->iTable = iTable;
|
||||
pE->iAgg = -1;
|
||||
pE->iColumn = iCol-1;
|
||||
pE->pTab = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -3033,10 +3063,12 @@ int sqlite3Select(
|
||||
*/
|
||||
if( p->pPrior ){
|
||||
if( p->pRightmost==0 ){
|
||||
Select *pLoop;
|
||||
Select *pLoop, *pRight = 0;
|
||||
int cnt = 0;
|
||||
for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
|
||||
pLoop->pRightmost = p;
|
||||
pLoop->pNext = pRight;
|
||||
pRight = pLoop;
|
||||
}
|
||||
if( SQLITE_MAX_COMPOUND_SELECT>0 && cnt>SQLITE_MAX_COMPOUND_SELECT ){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.625 2007/12/11 19:34:45 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.626 2007/12/13 03:45:08 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -1317,6 +1317,7 @@ struct Select {
|
||||
Expr *pHaving; /* The HAVING clause */
|
||||
ExprList *pOrderBy; /* The ORDER BY clause */
|
||||
Select *pPrior; /* Prior select in a compound select statement */
|
||||
Select *pNext; /* Next select to the left in a compound */
|
||||
Select *pRightmost; /* Right-most select in a compound select statement */
|
||||
Expr *pLimit; /* LIMIT expression. NULL means not used. */
|
||||
Expr *pOffset; /* OFFSET expression. NULL means not used. */
|
||||
|
@ -150,7 +150,13 @@ do_test null-5.1 {
|
||||
} {{} 0 1}
|
||||
|
||||
# A UNION to two queries should treat NULL values
|
||||
# as distinct
|
||||
# as distinct.
|
||||
#
|
||||
# (Later:) We also take this opportunity to test the ability
|
||||
# of an ORDER BY clause to bind to either SELECT of a UNION.
|
||||
# The left-most SELECT is preferred. In standard SQL, only
|
||||
# the left SELECT can be used. The ability to match an ORDER
|
||||
# BY term to the right SELECT is an SQLite extension.
|
||||
#
|
||||
ifcapable compound {
|
||||
do_test null-6.1 {
|
||||
@ -173,6 +179,16 @@ ifcapable compound {
|
||||
select b from t1 union select c from t1 order by main.t1.b;
|
||||
}
|
||||
} {{} 0 1}
|
||||
do_test null-6.5 {
|
||||
execsql {
|
||||
select b from t1 union select c from t1 order by t1.a;
|
||||
}
|
||||
} {{} 0 1}
|
||||
do_test null-6.6 {
|
||||
execsql {
|
||||
select b from t1 union select c from t1 order by main.t1.a;
|
||||
}
|
||||
} {{} 0 1}
|
||||
} ;# ifcapable compound
|
||||
|
||||
# The UNIQUE constraint only applies to non-null values
|
||||
|
@ -12,7 +12,7 @@
|
||||
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
|
||||
# in SELECT statements.
|
||||
#
|
||||
# $Id: select4.test,v 1.22 2007/12/10 18:51:48 danielk1977 Exp $
|
||||
# $Id: select4.test,v 1.23 2007/12/13 03:45:08 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -210,12 +210,15 @@ do_test select4-4.1.1 {
|
||||
|
||||
do_test select4-4.1.2 {
|
||||
execsql {
|
||||
SELECT DISTINCT log FROM t1 UNION ALL SELECT 6
|
||||
SELECT DISTINCT log FROM t1
|
||||
UNION ALL
|
||||
SELECT 6
|
||||
INTERSECT
|
||||
SELECT n FROM t1 WHERE log=3
|
||||
ORDER BY log;
|
||||
ORDER BY t1.log;
|
||||
}
|
||||
} {5 6}
|
||||
|
||||
do_test select4-4.1.3 {
|
||||
execsql {
|
||||
CREATE TABLE t2 AS
|
||||
|
Loading…
x
Reference in New Issue
Block a user