diff --git a/manifest b/manifest index d0f482bc58..1951a0b5b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C Adjust\sthe\stest\ssuite\sto\saccount\sfor\srecent\schanges\srelated\sto\s#2822.\sMost\schanges\sare\srelated\sto\sEnglish\slanguage\serror\smessages\sonly.\s(CVS\s4622) +D 2007-12-13T07:58:51 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 0590398f62fc2c456ff4c45e9741f5a718b7e2ac F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -131,7 +131,7 @@ F src/pragma.c 0246032dbe681dded8710ac43eaf654eead1434e F src/prepare.c f811fdb6fd4a82cca673a6e1d5b041d6caf567f1 F src/printf.c 5732e393c45be7c09bfca9a786daef017e0066ef F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da -F src/select.c c2de6d7ba6f98d83e03dabc405e46f439cb37f20 +F src/select.c 14c4a8e9d784bfc4bfbb1576226f2bc0b9fbfd10 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c c97be281cfc3dcb14902f45e4b16f20038eb83ff F src/sqlite.h.in b16a7127dad4a3e5b1b26b3d64241f3373aa12ea @@ -335,7 +335,7 @@ F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert2.test 5a20e1ace5fa0800b58d28284212290189b49aed F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677 F test/insert4.test 6919ddacd79c2cfeb9785b0f84217f9cb14853b5 -F test/insert5.test e41e417a4f055c25d6c2b9847c775bf357df2390 +F test/insert5.test d577901d50e90791ad6bceeb2626bfecd0c1332f F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2 F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f F test/io.test 80a7a7f1a2792e037d447b03e8c22ee1f6eaf339 @@ -384,12 +384,12 @@ F test/misc1.test 1b89c02c4a33b49dee4cd1d20d161aaaba719075 F test/misc2.test 1ee89298de9c16b61454658b24999c403e86afe4 F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03 F test/misc4.test 91e8ed25c092c2bb4e0bb01864631e2930f8d7de -F test/misc5.test 33b95f12f18b7b9558c79545503f05728fbf2c22 +F test/misc5.test b0b4b7e0dd5d40335c8e849e5738d11a40bddc7c F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 3fbd0a9e3dd03331d9d76acd47bc179e1a97e15e F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82 -F test/null.test 6adcb4efd433e02c60499f96328014de87cff8b1 +F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/onefile.test b9cce375fd2a41ee3afa79a0a808954046b74458 F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df F test/pager.test 60303481b22b240c18d6dd1b64edcecc2f4b5a97 @@ -411,10 +411,10 @@ F test/rowid.test d125991eea1ffdea800d48471afd8fc4acc10b01 F test/safety.test 4a06934e45d03b8b50ebcd8d174eb0367d2fd851 F test/schema.test a8b000723375fd42c68d310091bdbd744fde647c F test/schema2.test 35e1c9696443d6694c8980c411497c2b5190d32e -F test/select1.test 79784038f0e7df66bb420e149c6fb91e61e11fb7 +F test/select1.test 871df931cbbc0e78170605628e8b5fc60765e265 F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3 -F test/select3.test 47439f28862489626b483b0c718cfb0562e6f6d5 -F test/select4.test 566b4ca1152e16d7090d76f98d93c80b9a1f6c53 +F test/select3.test 7f99c0d4067064e0865479a56faa7aaa29b9041a +F test/select4.test 69015a6c02c3d8efed01f15e5d025fb4e5256183 F test/select5.test 0b47058d3e916c1fc9fe81f44b438e02bade21ce F test/select6.test 399f14b9ba37b768afe5d2cd8c12e4f340a69db8 F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f @@ -479,7 +479,7 @@ F test/tkt2686.test 3022db0eee8ecf501f516557c77ef1c4039399cd F test/tkt2767.test 6b02308d553d194f329a469bf5c157fe724738d4 F test/tkt2817.test 709a2201a5590bf56cb97f6fb168a62282203fd1 F test/tkt2820.test 017fdee33aaef7abc092beab6088816f1942304b -F test/tkt2822.test 09033348a14f5a5729724b0db7c1687cfc876b9f +F test/tkt2822.test 1260ab1c84edccdb7dc27954bd555852d6877f2e F test/tkt2832.test cd56dc66bb31898b7eb2146baa5bde2eb80f96fe F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567 F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc @@ -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 bbddf16ac9539c7d48adfc73c5a90eecb8df6865 -R 377fa996f832a29c87d12a5f182c500b -U drh -Z f7fa31d1f83b3a0d837ffef0df0c17c3 +P 56063ec84b130bcdb0e90bc76fabca394d0d867f +R f457ed8bb872aba62e47c1fbbf619525 +U danielk1977 +Z 9c40edbf16b75a2e3c6478efc41069ac diff --git a/manifest.uuid b/manifest.uuid index 9d727bd1d7..07cf3eeb59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56063ec84b130bcdb0e90bc76fabca394d0d867f \ No newline at end of file +2f88b9b3e3c9abc3ae4a5dcef82707dd74f8aace \ No newline at end of file diff --git a/src/select.c b/src/select.c index 553144f3fa..02ec697409 100644 --- a/src/select.c +++ b/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.367 2007/12/13 03:45:08 drh Exp $ +** $Id: select.c,v 1.368 2007/12/13 07:58:51 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -2825,7 +2825,7 @@ int sqlite3SelectResolve( return SQLITE_ERROR; } if( p->pPrior==0 ){ - if( processOrderGroupBy(pParse, p, p->pOrderBy, 0, &sNC.hasAgg) ){ + if( processOrderGroupBy(pParse, p, p->pOrderBy, 1, &sNC.hasAgg) ){ return SQLITE_ERROR; } } diff --git a/test/insert5.test b/test/insert5.test index 4dd869b282..d8ea6dbae6 100644 --- a/test/insert5.test +++ b/test/insert5.test @@ -12,7 +12,7 @@ # The tests in this file ensure that a temporary table is used # when required by an "INSERT INTO ... SELECT ..." statement. # -# $Id: insert5.test,v 1.2 2007/12/10 05:03:48 danielk1977 Exp $ +# $Id: insert5.test,v 1.3 2007/12/13 07:58:51 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -85,12 +85,23 @@ do_test insert5-2.8 { SELECT * FROM main WHERE id > 10 AND max(id1, (SELECT id FROM b)) > 10; } } {1} + +# UPDATE: Using a column from the outer query (main.id) in the GROUP BY +# or ORDER BY of a sub-query is no longer supported. +# +# do_test insert5-2.9 { +# uses_temp_table { +# INSERT INTO b +# SELECT * FROM main +# WHERE id > 10 AND (SELECT count(*) FROM v2 GROUP BY main.id) +# } +# } {} do_test insert5-2.9 { - uses_temp_table { + catchsql { INSERT INTO b SELECT * FROM main WHERE id > 10 AND (SELECT count(*) FROM v2 GROUP BY main.id) } -} {1} +} {1 {no such column: main.id}} finish_test diff --git a/test/misc5.test b/test/misc5.test index d7094b147d..ebccf4c0a4 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -13,7 +13,7 @@ # This file implements tests for miscellanous features that were # left out of other test files. # -# $Id: misc5.test,v 1.18 2007/11/12 15:29:19 danielk1977 Exp $ +# $Id: misc5.test,v 1.19 2007/12/13 07:58:51 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -558,12 +558,12 @@ ifcapable subquery&&compound { CREATE TABLE logs(msg TEXT, timestamp INTEGER, dbtime TEXT); } catchsql { - SELECT * FROM logs WHERE logs.id >= (SELECT head FROM logs_base) + SELECT * FROM logs WHERE logs.oid >= (SELECT head FROM logs_base) UNION ALL SELECT * FROM logs LIMIT (SELECT lmt FROM logs_base) ; } - } {1 {no such column: logs.id}} + } {1 {no such table: logs_base}} } # Overflow the lemon parser stack by providing an overly complex diff --git a/test/null.test b/test/null.test index c6b202e819..f3782a7531 100644 --- a/test/null.test +++ b/test/null.test @@ -180,15 +180,15 @@ ifcapable compound { } } {{} 0 1} do_test null-6.5 { - execsql { + catchsql { select b from t1 union select c from t1 order by t1.a; } - } {{} 0 1} + } {1 {1st ORDER BY term does not match any column in the result set}} do_test null-6.6 { - execsql { + catchsql { select b from t1 union select c from t1 order by main.t1.a; } - } {{} 0 1} + } {1 {1st ORDER BY term does not match any column in the result set}} } ;# ifcapable compound # The UNIQUE constraint only applies to non-null values diff --git a/test/select1.test b/test/select1.test index aeed6fb3a9..519e693ca4 100644 --- a/test/select1.test +++ b/test/select1.test @@ -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.56 2007/12/10 05:03:48 danielk1977 Exp $ +# $Id: select1.test,v 1.57 2007/12/13 07:58:51 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -306,7 +306,7 @@ do_test select1-4.3 { do_test select1-4.4 { set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg] lappend v $msg -} {1 {misuse of aggregate function min()}} +} {1 {misuse of aggregate: min(f1)}} # The restriction not allowing constants in the ORDER BY clause # has been removed. See ticket #1768 @@ -374,12 +374,12 @@ do_test select1-4.10.1 { catchsql { SELECT * FROM t5 ORDER BY 3; } -} {1 {ORDER BY column number 3 out of range - should be between 1 and 2}} +} {1 {1st ORDER BY term out of range - should be between 1 and 2}} do_test select1-4.10.2 { catchsql { SELECT * FROM t5 ORDER BY -1; } -} {1 {ORDER BY column number -1 out of range - should be between 1 and 2}} +} {1 {1st ORDER BY term out of range - should be between 1 and 2}} do_test select1-4.11 { execsql { INSERT INTO t5 VALUES(3,10); @@ -520,7 +520,7 @@ do_test select1-6.11 { ORDER BY f2+101; }} msg] lappend v $msg -} {1 {ORDER BY term number 1 does not match any result column}} +} {1 {1st ORDER BY term does not match any column in the result set}} # Ticket #2296 ifcapable subquery { diff --git a/test/select3.test b/test/select3.test index ec8245ab82..53f8369057 100644 --- a/test/select3.test +++ b/test/select3.test @@ -12,7 +12,7 @@ # focus of this file is testing aggregate functions and the # GROUP BY and HAVING clauses of SELECT statements. # -# $Id: select3.test,v 1.21 2007/06/20 12:18:31 drh Exp $ +# $Id: select3.test,v 1.22 2007/12/13 07:58:51 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -93,12 +93,12 @@ do_test select3-2.10 { catchsql { SELECT log, count(*) FROM t1 GROUP BY 0 ORDER BY log; } -} {1 {GROUP BY column number 0 out of range - should be between 1 and 2}} +} {1 {1st GROUP BY term out of range - should be between 1 and 2}} do_test select3-2.11 { catchsql { SELECT log, count(*) FROM t1 GROUP BY 3 ORDER BY log; } -} {1 {GROUP BY column number 3 out of range - should be between 1 and 2}} +} {1 {1st GROUP BY term out of range - should be between 1 and 2}} do_test select3-2.12 { catchsql { SELECT log, count(*) FROM t1 GROUP BY 1 ORDER BY log; diff --git a/test/select4.test b/test/select4.test index df7dfee5fe..62b041adcc 100644 --- a/test/select4.test +++ b/test/select4.test @@ -12,7 +12,7 @@ # focus of this file is testing UNION, INTERSECT and EXCEPT operators # in SELECT statements. # -# $Id: select4.test,v 1.23 2007/12/13 03:45:08 drh Exp $ +# $Id: select4.test,v 1.24 2007/12/13 07:58:51 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -298,7 +298,7 @@ do_test select4-5.2c { ORDER BY "xyzzy"; }} msg] lappend v $msg -} {1 {ORDER BY term number 1 does not match any result column}} +} {1 {1st ORDER BY term does not match any column in the result set}} do_test select4-5.2d { set v [catch {execsql { SELECT DISTINCT log FROM t1 @@ -307,7 +307,7 @@ do_test select4-5.2d { ORDER BY "xyzzy"; }} msg] lappend v $msg -} {1 {ORDER BY term number 1 does not match any result column}} +} {1 {1st ORDER BY term does not match any column in the result set}} do_test select4-5.2e { set v [catch {execsql { SELECT DISTINCT log FROM t1 @@ -340,7 +340,7 @@ do_test select4-5.2h { SELECT n FROM t1 WHERE log=3 ORDER BY 2; } -} {1 {ORDER BY position 2 should be between 1 and 1}} +} {1 {1st ORDER BY term out of range - should be between 1 and 1}} do_test select4-5.2i { catchsql { SELECT DISTINCT 1, log FROM t1 @@ -575,13 +575,13 @@ do_test select4-9.7 { } ;# ifcapable subquery do_test select4-9.8 { - catchsql { + execsql { SELECT 0 AS x, 1 AS y UNION SELECT 2 AS y, -3 AS x ORDER BY x LIMIT 1; } -} {1 {ORDER BY term number 1 is ambiguous}} +} {0 1} do_test select4-9.9.1 { execsql2 { diff --git a/test/tkt2822.test b/test/tkt2822.test index 9876a86226..477510b47b 100644 --- a/test/tkt2822.test +++ b/test/tkt2822.test @@ -13,90 +13,148 @@ # ORDER BY clauses on compound SELECT statements raised by ticket # #2822 have been dealt with. # -# $Id: tkt2822.test,v 1.2 2007/12/12 04:38:27 danielk1977 Exp $ +# $Id: tkt2822.test,v 1.3 2007/12/13 07:58:51 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl +# The ORDER BY matching algorithm is three steps: +# +# (1) If the ORDER BY term is an integer constant i, then +# sort by the i-th column of the result set. +# +# (2) If the ORDER BY term is an identifier (not x.y or x.y.z +# but simply x) then look for a column alias with the same +# name. If found, then sort by that column. +# +# (3) Evaluate the term as an expression and sort by the +# value of the expression. +# +# For a compound SELECT the rules are modified slightly. +# In the third rule, the expression must exactly match one +# of the result columns. The sequences of three rules is +# attempted first on the left-most SELECT. If that doesn't +# work, we move to the right, one by one. This is not standard +# SQL, it is an SQLite extension. +# + + # Test plan: # # tkt2822-1.* - Simple identifier as ORDER BY expression. # tkt2822-2.* - More complex ORDER BY expressions. -do_test tkt2822-1.1 { +do_test tkt2822-0.1 { execsql { CREATE TABLE t1(a, b, c); - CREATE TABLE t2(c, b, a); + CREATE TABLE t2(a, b, c); - INSERT INTO t1 VALUES(1, 2, 3); - INSERT INTO t2 VALUES(3, 2, 1); + INSERT INTO t1 VALUES(1, 3, 9); + INSERT INTO t1 VALUES(3, 9, 27); + INSERT INTO t1 VALUES(5, 15, 45); + + INSERT INTO t2 VALUES(2, 6, 18); + INSERT INTO t2 VALUES(4, 12, 36); + INSERT INTO t2 VALUES(6, 18, 54); } } {} -# If an ORDER BY expression matches two different columns, it is an error. +# Test the "ORDER BY " syntax. # +do_test tkt2822-1.1 { + execsql { + SELECT a, b, c FROM t1 UNION ALL SELECT a, b, c FROM t2 ORDER BY 1; + } +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} do_test tkt2822-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 tkt2822-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 tkt2822-1.4 { execsql { - SELECT a, b, c FROM t2 UNION ALL SELECT a, b, c FROM t1 ORDER BY a; + SELECT a, CAST (b AS TEXT), c FROM t1 + UNION ALL + SELECT a, b, c FROM t2 + ORDER BY 2; } -} {1 2 3 1 2 3} +} {2 6 18 4 12 36 6 18 54 5 15 45 1 3 9 3 9 27} -do_test tkt2822-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. +# Test the "ORDER BY " syntax. # -do_test tkt2822-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 tkt2822-2.1 { execsql { - SELECT a+1, b+1 FROM t1 UNION ALL SELECT a, c FROM t2 ORDER BY a+1; + SELECT a, b, c FROM t1 UNION ALL SELECT a, b, c FROM t2 ORDER BY a; } -} {1 3 2 3} -do_test tkt2822-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 tkt2822-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}} +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} -do_test tkt2822-2.4 { +do_test tkt2822-2.2 { execsql { - SELECT t1.a, b+1 FROM t1 UNION ALL SELECT c, a+1 FROM t2 ORDER BY a; + SELECT a, CAST (b AS TEXT) AS x, c FROM t1 + UNION ALL + SELECT a, b, c FROM t2 + ORDER BY x; } -} {1 3 3 2} -do_test tkt2822-2.5 { +} {2 6 18 4 12 36 6 18 54 5 15 45 1 3 9 3 9 27} +do_test tkt2822-2.3 { execsql { - SELECT t1.a, b+1 FROM t1 UNION ALL SELECT c, a+1 FROM t2 ORDER BY t1.a; + SELECT t1.a, b, c FROM t1 UNION ALL SELECT t2.a, b, c FROM t2 ORDER BY a; } -} {1 3 3 2} +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} + +# Test the "ORDER BY " syntax. +# +do_test tkt2822-3.1 { + execsql { + SELECT a, CAST (b AS TEXT) AS x, c FROM t1 + UNION ALL + SELECT a, b, c FROM t2 + ORDER BY CAST (b AS TEXT); + } +} {2 6 18 4 12 36 6 18 54 5 15 45 1 3 9 3 9 27} +do_test tkt2822-3.2 { + execsql { + SELECT t1.a, b, c FROM t1 UNION ALL SELECT t2.a, b, c FROM t2 ORDER BY t1.a; + } +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} + +# Test that if a match cannot be found in the leftmost SELECT, an +# attempt is made to find a match in subsequent SELECT statements. +# +do_test tkt2822-3.1 { + execsql { + SELECT a, b, c FROM t1 UNION ALL SELECT a AS x, b, c FROM t2 ORDER BY x; + } +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} +do_test tkt2822-3.2 { + # But the leftmost SELECT takes precedence. + execsql { + SELECT a AS b, CAST (b AS TEXT) AS a, c FROM t1 + UNION ALL + SELECT a, b, c FROM t2 + ORDER BY a; + } +} {2 6 18 4 12 36 6 18 54 5 15 45 1 3 9 3 9 27} +do_test tkt2822-3.3 { + execsql { + SELECT a, b, c FROM t2 + UNION ALL + SELECT a AS b, CAST (b AS TEXT) AS a, c FROM t1 + ORDER BY a; + } +} {1 3 9 2 6 18 3 9 27 4 12 36 5 15 45 6 18 54} + +# Test some error conditions (ORDER BY clauses that match no column). +# +do_test tkt2822-4.1 { + catchsql { + SELECT a, b, c FROM t1 UNION ALL SELECT a, b, c FROM t2 ORDER BY x + } +} {1 {1st ORDER BY term does not match any column in the result set}} +do_test tkt2822-4.2 { + catchsql { + SELECT a, CAST (b AS TEXT) AS x, c FROM t1 + UNION ALL + SELECT a, b, c FROM t2 + ORDER BY CAST (b AS INTEGER); + } +} {1 {1st ORDER BY term does not match any column in the result set}} finish_test