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] -----------------------------------------------------------------------------