-C Fix\sa\smacro\sin\sfunc.c\sthat\scauses\sproblems\sfor\sthe\samalgamation.\s(CVS\s4605)
-D 2007-12-10T18:07:21
+C Further\smodifications\sto\sdo\swith\sORDER\sBY\sand\scompound\sSELECT\squeries.\sRelated\sto\sticket\s#2822.\s(CVS\s4606)
+D 2007-12-10T18:51:48
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/prepare.c f811fdb6fd4a82cca673a6e1d5b041d6caf567f1
F src/printf.c c94a2571a828b927c64f5e3ed3584da8a91fcaec
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c 2c08239b55cf93c03a79cbdedf1ac89967fd6acb
+F src/select.c b7408624b55f58e5aa8521edb177b26ad72f968b
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c c97be281cfc3dcb14902f45e4b16f20038eb83ff
F src/sqlite.h.in 544587c10005dde0ad8f132dd9b7816b132b2bea
F test/select1.test 79784038f0e7df66bb420e149c6fb91e61e11fb7
F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3
F test/select3.test 47439f28862489626b483b0c718cfb0562e6f6d5
-F test/select4.test 4192e6c712194d53b4b77f094eb9d880b8d5ac0e
+F test/select4.test 2dd28cfea6f50281fb29cf136cf50df8ead6a5d2
F test/select5.test 0b47058d3e916c1fc9fe81f44b438e02bade21ce
F test/select6.test 399f14b9ba37b768afe5d2cd8c12e4f340a69db8
F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f
F test/tkt2767.test 6b02308d553d194f329a469bf5c157fe724738d4
F test/tkt2817.test 709a2201a5590bf56cb97f6fb168a62282203fd1
F test/tkt2820.test 017fdee33aaef7abc092beab6088816f1942304b
+F test/tkt2822.test 782d6041b9ec10c74e28768f477cba722c43d88e
F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc
F test/trigger1.test 7c13f39ca36f529bf856e05c7d004fc0531d48b4
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P d384810a95c97b868a87d090f8dcb903cc82cbf7
-R 02ccd20331c3a0f99f895b6e82412309
-U drh
-Z f800f34be093e13e0ebe3d12e796a99d
+P 6adbe91efffc6b3f53dae87494430ede61d40ecc
+R c5664694f29e5838b66b78cd136777a8
+U danielk1977
+Z 0cfc5f38f552087a6f749e4e8561ad47
-6adbe91efffc6b3f53dae87494430ede61d40ecc
\ No newline at end of file
+0d9b0e6e3a8f8a66956878084085842e94c3cb2f
\ No newline at end of file
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.364 2007/12/08 21:10:20 drh Exp $
+** $Id: select.c,v 1.365 2007/12/10 18:51:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
return rc;
}
-/*
-** During the process of matching ORDER BY terms to columns of the
-** result set, the Exprlist.a[].done flag can be set to one of the
-** following values:
-*/
-#define ORDERBY_MATCH_NONE 0 /* No match found */
-#define ORDERBY_MATCH_PARTIAL 1 /* A good match, but not perfect */
-#define ORDERBY_MATCH_EXACT 2 /* An exact match seen */
-
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine associates entries in an ORDER BY expression list with
** the top-level node is filled in with column number and the iTable
** value of the top-level node is filled with iTable parameter.
**
-** If there are prior SELECT clauses, they are processed first. A match
-** in an earlier SELECT takes precedence over a later SELECT.
-**
** Any entry that does not match is flagged as an error. The number
** of errors is returned.
*/
Parse *pParse, /* A place to leave error messages */
Select *pSelect, /* Match to result columns of this SELECT */
ExprList *pOrderBy, /* The ORDER BY values to match against columns */
- int iTable, /* Insert this value in iTable */
- int rightMost /* TRUE for outermost recursive invocation */
+ int iTable /* Insert this value in iTable */
){
int nErr = 0;
int i, j;
- ExprList *pEList;
sqlite3 *db = pParse->db;
- NameContext nc;
+ int nExpr;
if( pSelect==0 || pOrderBy==0 ) return 1;
- if( rightMost ){
- assert( pSelect->pOrderBy==pOrderBy );
- for(i=0; i<pOrderBy->nExpr; i++){
- pOrderBy->a[i].done = ORDERBY_MATCH_NONE;
- }
- }
- if( pSelect->pPrior
- && matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
- return 1;
- }
if( sqlite3SelectResolve(pParse, pSelect, 0) ){
return 1;
}
- memset(&nc, 0, sizeof(nc));
- nc.pParse = pParse;
- nc.pSrcList = pSelect->pSrc;
- nc.pEList = pEList = pSelect->pEList;
- nc.allowAgg = 1;
+
+ nExpr = pSelect->pEList->nExpr;
for(i=0; nErr==0 && i<pOrderBy->nExpr; i++){
- struct ExprList_item *pItem;
Expr *pE = pOrderBy->a[i].pExpr;
int iCol = -1;
- int match = ORDERBY_MATCH_NONE;
- Expr *pDup;
- if( pOrderBy->a[i].done==ORDERBY_MATCH_EXACT ){
- continue;
- }
if( sqlite3ExprIsInteger(pE, &iCol) ){
- if( iCol<=0 || iCol>pEList->nExpr ){
+ if( iCol<=0 || iCol>nExpr ){
sqlite3ErrorMsg(pParse,
"ORDER BY position %d should be between 1 and %d",
- iCol, pEList->nExpr);
+ iCol, nExpr);
nErr++;
break;
}
- if( !rightMost ) continue;
iCol--;
- match = ORDERBY_MATCH_EXACT;
- }
- if( !match && pParse->nErr==0 && (pDup = sqlite3ExprDup(db, pE))!=0 ){
- nc.nErr = 0;
- assert( pParse->zErrMsg==0 );
- if( sqlite3ExprResolveNames(&nc, pDup) ){
- sqlite3ErrorClear(pParse);
- }else{
- for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){
- if( sqlite3ExprCompare(pItem->pExpr, pDup) ){
- iCol = j;
- match = ORDERBY_MATCH_PARTIAL;
- break;
+ }else{
+ Select *p;
+ for(p=pSelect; p; p=p->pPrior){
+ ExprList *pEList = p->pEList;
+ Expr *pDup = sqlite3ExprDup(db, pE);
+
+ NameContext nc;
+
+ memset(&nc, 0, sizeof(nc));
+ nc.pParse = pParse;
+ nc.pSrcList = p->pSrc;
+ nc.pEList = pEList;
+ nc.allowAgg = 1;
+ nc.nErr = 0;
+ if( sqlite3ExprResolveNames(&nc, pDup) ){
+ sqlite3ErrorClear(pParse);
+ }else{
+ struct ExprList_item *pItem;
+ for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){
+ if( sqlite3ExprCompare(pItem->pExpr, pDup) ){
+ if( iCol>=0 && iCol!=j ){
+ sqlite3ErrorMsg(
+ pParse, "ORDER BY term number %d is ambiguous", i+1
+ );
+ }else{
+ iCol = j;
+ }
+ }
}
}
+ sqlite3ExprDelete(pDup);
}
- sqlite3ExprDelete(pDup);
}
- if( match ){
+
+ if( iCol<0 ){
+ sqlite3ErrorMsg(pParse,
+ "ORDER BY term number %d does not match any result column", i+1);
+ }else{
pE->op = TK_COLUMN;
pE->iTable = iTable;
pE->iAgg = -1;
- if( pOrderBy->a[i].done!=ORDERBY_MATCH_NONE && pE->iColumn!=iCol ){
- sqlite3ErrorMsg(pParse,
- "ORDER BY term number %d is ambiguous", i+1);
- nErr++;
- }
pE->iColumn = iCol;
- pOrderBy->a[i].done = match;
- }else if( rightMost && pOrderBy->a[i].done==ORDERBY_MATCH_NONE ){
- sqlite3ErrorMsg(pParse,
- "ORDER BY term number %d does not match any result column", i+1);
- nErr++;
- break;
+ pOrderBy->a[i].done = 1;
+ }
+
+ if( pParse->nErr ){
+ return pParse->nErr;
}
}
- return nErr;
+
+ return SQLITE_OK;
}
#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */
** intermediate results.
*/
unionTab = pParse->nTab++;
- if( pOrderBy && matchOrderbyToColumn(pParse, p, pOrderBy, unionTab,1) ){
+ if( pOrderBy && matchOrderbyToColumn(pParse, p, pOrderBy, unionTab) ){
rc = 1;
goto multi_select_end;
}
*/
tab1 = pParse->nTab++;
tab2 = pParse->nTab++;
- if( pOrderBy && matchOrderbyToColumn(pParse,p,pOrderBy,tab1,1) ){
+ if( pOrderBy && matchOrderbyToColumn(pParse,p,pOrderBy,tab1) ){
rc = 1;
goto multi_select_end;
}
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
# in SELECT statements.
#
-# $Id: select4.test,v 1.21 2007/12/08 21:10:20 drh Exp $
+# $Id: select4.test,v 1.22 2007/12/10 18:51:48 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
} ;# ifcapable subquery
do_test select4-9.8 {
- execsql2 {
+ catchsql {
SELECT 0 AS x, 1 AS y
UNION
SELECT 2 AS y, -3 AS x
ORDER BY x LIMIT 1;
}
-} {x 0 y 1}
+} {1 {ORDER BY term number 1 is ambiguous}}
+
do_test select4-9.9.1 {
execsql2 {
SELECT 1 AS a, 2 AS b UNION ALL SELECT 3 AS b, 4 AS a
--- /dev/null
+# 2007 Dec 4
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file is to test that the issues surrounding expressions in
+# ORDER BY clauses on compound SELECT statements raised by ticket
+# #2822 have been dealt with.
+#
+# $Id: tkt2822.test,v 1.1 2007/12/10 18:51:48 danielk1977 Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Test plan:
+#
+# tkt2820-1.* - Simple identifier as ORDER BY expression.
+# tkt2820-2.* - More complex ORDER BY expressions.
+
+do_test tkt2820-1.1 {
+ execsql {
+ CREATE TABLE t1(a, b, c);
+ CREATE TABLE t2(c, b, a);
+
+ INSERT INTO t1 VALUES(1, 2, 3);
+ INSERT INTO t2 VALUES(3, 2, 1);
+ }
+} {}
+
+# If an ORDER BY expression matches two different columns, it is an error.
+#
+do_test tkt2820-1.2 {
+ catchsql {
+ SELECT a, b FROM t1 UNION ALL SELECT b, a FROM t2 ORDER BY a;
+ }
+} {1 {ORDER BY term number 1 is ambiguous}}
+do_test tkt2820-1.3 {
+ catchsql {
+ SELECT a, b, c FROM t2 UNION ALL SELECT c, b, a FROM t1 ORDER BY a;
+ }
+} {1 {ORDER BY term number 1 is ambiguous}}
+
+# But not if it matches the same column in two or more of the
+# compounded SELECT statements.
+#
+do_test tkt2820-1.4 {
+ execsql {
+ SELECT a, b, c FROM t2 UNION ALL SELECT a, b, c FROM t1 ORDER BY a;
+ }
+} {1 2 3 1 2 3}
+
+do_test tkt2820-1.5 {
+ execsql {
+ SELECT a, b FROM t2 UNION ALL SELECT c, b FROM t1 ORDER BY c;
+ }
+} {1 2 3 2}
+
+# If a match cannot be found in any SELECT, return an error.
+#
+do_test tkt2820-1.6 {
+ catchsql {
+ SELECT * FROM t2 UNION ALL SELECT * FROM t1 ORDER BY d;
+ }
+} {1 {ORDER BY term number 1 does not match any result column}}
+
+
+do_test tkt2820-2.1 {
+ execsql {
+ SELECT a+1, b+1 FROM t1 UNION ALL SELECT a, c FROM t2 ORDER BY a+1;
+ }
+} {1 3 2 3}
+do_test tkt2820-2.2 {
+ catchsql {
+ SELECT a+1, b+1 FROM t1 UNION ALL SELECT a, c FROM t2 ORDER BY a+2;
+ }
+} {1 {ORDER BY term number 1 does not match any result column}}
+do_test tkt2820-2.3 {
+ catchsql {
+ SELECT a+1, b+1 FROM t1 UNION ALL SELECT c, a+1 FROM t2 ORDER BY a+1;
+ }
+} {1 {ORDER BY term number 1 is ambiguous}}
+
+do_test tkt2820-2.4 {
+ execsql {
+ SELECT t1.a, b+1 FROM t1 UNION ALL SELECT c, a+1 FROM t2 ORDER BY a;
+ }
+} {1 3 3 2}
+do_test tkt2820-2.5 {
+ execsql {
+ SELECT t1.a, b+1 FROM t1 UNION ALL SELECT c, a+1 FROM t2 ORDER BY t1.a;
+ }
+} {1 3 3 2}
+
+finish_test
+