The attached sqlite 3.5.3 patch addresses several different compound
query column naming and resolving issues in ORDER BY and the SELECT
expression list mentioned in this ticket:
http://www.sqlite.org/cvstrac/tktview?tn=2822
(The exception being it does not support expressions in the ORDER BY
clause of compound SELECT statements. That functionality remains the
same as in version 3.5.3.)
I believe it makes compound query behavior more compatible with other
popular databases. It is mostly backwards compatible with the previous
syntax and only 2 tests performed by "make test" had to be altered.
It seems to work, although it's quite possible that I missed something.
At least this patch serves as a basis of syntax discussion.
If you want to test it, just put sqlite-3.5.3.tar.gz and the patch
file in the same directory and run these commands:
tar xzvf sqlite-3.5.3.tar.gz
cd sqlite-3.5.3
patch -p0 < ../union-alias-20071207.patch.txt
./configure
make
./sqlite3
Please report any issues to the mailing list.
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now.
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Index: src/select.c
===================================================================
RCS file: /sqlite/sqlite/src/select.c,v
retrieving revision 1.363
diff -u -3 -p -r1.363 select.c
--- src/select.c 23 Nov 2007 13:42:52 -0000 1.363
+++ src/select.c 8 Dec 2007 03:49:30 -0000
@@ -1118,8 +1118,19 @@ Table *sqlite3ResultSetOfSelect(Parse *p
/* For columns of the from A.B use B as the name */
zName = sqlite3MPrintf(db, "%T", &pR->token);
}else if( p->span.z && p->span.z[0] ){
- /* Use the original text of the column expression as its name */
- zName = sqlite3MPrintf(db, "%T", &p->span);
+ Token t = p->span;
+ if( p->op==TK_COLUMN ){
+ /* Get rid of all dotted prefixes, if any */
+ int n;
+ for(n = t.n-1; n>=0; n--){
+ if( t.z[n]=='.' ){
+ t.n -= n+1;
+ t.z += n+1;
+ break;
+ }
+ }
+ }
+ zName = sqlite3MPrintf(db, "%T", &t);
}else{
/* If all else fails, make up a name */
zName = sqlite3MPrintf(db, "column%d", i+1);
@@ -1469,12 +1480,23 @@ static int matchOrderbyToColumn(
if( !mustComplete ) continue;
iCol--;
}
- if( iCol<0 && (zLabel = sqlite3NameFromToken(db, &pE->token))!=0 ){
+ if( iCol<0 && (
+ (zLabel = sqlite3NameFromToken(db, &pE->token))!=0
+ || ((pE->op==TK_STRING || pE->op==TK_DOT || pE->op==TK_ID)
+ && (zLabel = sqlite3NameFromToken(db, &pE->span))!=0) )){
for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){
char *zName;
int isMatch;
if( pItem->zName ){
zName = sqlite3DbStrDup(db, pItem->zName);
+ }else if( pItem->pExpr->op==TK_DOT && pE->op==TK_ID ){
+ Expr *pRight = pItem->pExpr->pRight;
+ if( pRight->op==TK_DOT ){
+ pRight = pRight->pRight;
+ }
+ zName = sqlite3NameFromToken(db, &pRight->token);
+ }else if( pItem->pExpr->op==TK_DOT && pE->op==TK_DOT ){
+ zName = sqlite3NameFromToken(db, &pItem->pExpr->span);
}else{
zName = sqlite3NameFromToken(db, &pItem->pExpr->token);
}
@@ -1829,7 +1851,7 @@ static int multiSelect(
if( eDest==SRT_Callback ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -1907,7 +1929,7 @@ static int multiSelect(
if( eDest==SRT_Callback ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
Index: test/select1.test
===================================================================
RCS file: /sqlite/sqlite/test/select1.test,v
retrieving revision 1.54
diff -u -3 -p -r1.54 select1.test
--- test/select1.test 23 Jul 2007 22:51:15 -0000 1.54
+++ test/select1.test 8 Dec 2007 03:49:31 -0000
@@ -559,6 +559,66 @@ do_test select1-6.23 {
}
} {b d}
+# Ticket #2822
+do_test select1-6.30 {
+ execsql {
+ CREATE TABLE x1(a, b, c);
+ INSERT INTO x1 VALUES(6, 4, 2);
+ CREATE TABLE x2(a, b, c);
+ INSERT INTO x2 VALUES(7, 1, 3);
+ CREATE VIEW v1 AS
+ SELECT x1.b, x1.a FROM x1 UNION SELECT a, b FROM x2 ORDER BY b, a;
+ CREATE VIEW v2 AS
+ SELECT b, a FROM x1 UNION SELECT a, b FROM x2 ORDER BY b, a;
+ SELECT x1.b, a FROM x1 UNION SELECT a, b FROM x2 ORDER BY b, a;
+ }
+} {4 6 7 1}
+do_test select1-6.31 {
+ execsql {
+ SELECT b, a FROM x1 UNION SELECT a, b FROM x2 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.32 {
+ execsql {
+ SELECT b, a FROM v1 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.33 {
+ execsql {
+ SELECT b, a FROM v2 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.34 {
+ execsql {
+ SELECT v2.b, a FROM v2 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.35 {
+ execsql {
+ SELECT v1.b, a FROM v1 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.36 {
+ execsql {
+ SELECT x1.b, x1.a FROM x1 UNION SELECT a, b FROM x2 ORDER BY b;
+ }
+} {4 6 7 1}
+do_test select1-6.37 {
+ execsql {
+ SELECT v2.b, a FROM v2 ORDER BY v2.b;
+ }
+} {4 6 7 1}
+do_test select1-6.38 {
+ execsql {
+ SELECT v1.b, a FROM v1 ORDER BY v1.b;
+ }
+} {4 6 7 1}
+do_test select1-6.39 {
+ execsql {
+ SELECT x1.b, x1.a FROM x1 UNION SELECT a, b FROM x2 ORDER BY x1.b;
+ }
+} {4 6 7 1}
+
} ;#ifcapable compound
do_test select1-7.1 {
Index: test/subquery.test
===================================================================
RCS file: /sqlite/sqlite/test/subquery.test,v
retrieving revision 1.15
diff -u -3 -p -r1.15 subquery.test
--- test/subquery.test 18 Sep 2007 16:53:53 -0000 1.15
+++ test/subquery.test 8 Dec 2007 03:49:31 -0000
@@ -129,7 +129,7 @@ do_test subquery-1.10.4 {
SELECT "a.period", vsum
FROM (SELECT
- a.period,
+ a.period as "a.period",
(select sum(val) from t5 where period between a.period and '2002-4') vsum
FROM t5 a where a.period between '2002-1' and '2002-4')
WHERE vsum < 45 ;
@@ -137,7 +137,7 @@ do_test subquery-1.10.4 {
} {2002-2 30 2002-3 25 2002-4 15}
do_test subquery-1.10.5 {
execsql {
- SELECT "a.period", vsum from
+ SELECT period, vsum from
(select a.period,
(select sum(val) from t5 where period between a.period and '2002-4') vsum
FROM t5 a where a.period between '2002-1' and '2002-4')
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------