123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- # 2012 Sept 27
- #
- # 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 implements regression tests for SQLite library. The
- # focus of this file is testing that the optimizations that disable
- # ORDER BY clauses when the natural order of a query is correct.
- #
- set testdir [file dirname $argv0]
- source $testdir/tester.tcl
- set ::testprefix orderby1
- # Generate test data for a join. Verify that the join gets the
- # correct answer.
- #
- do_test 1.0 {
- db eval {
- BEGIN;
- CREATE TABLE album(
- aid INTEGER PRIMARY KEY,
- title TEXT UNIQUE NOT NULL
- );
- CREATE TABLE track(
- tid INTEGER PRIMARY KEY,
- aid INTEGER NOT NULL REFERENCES album,
- tn INTEGER NOT NULL,
- name TEXT,
- UNIQUE(aid, tn)
- );
- INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
- INSERT INTO track VALUES
- (NULL, 1, 1, 'one-a'),
- (NULL, 2, 2, 'two-b'),
- (NULL, 3, 3, 'three-c'),
- (NULL, 1, 3, 'one-c'),
- (NULL, 2, 1, 'two-a'),
- (NULL, 3, 1, 'three-a');
- COMMIT;
- }
- } {}
- do_test 1.1a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- # Verify that the ORDER BY clause is optimized out
- #
- do_test 1.1b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
- }
- } {~/ORDER BY/} ;# ORDER BY optimized out
- # The same query with ORDER BY clause optimization disabled via + operators
- # should give exactly the same answer.
- #
- do_test 1.2a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- # The output is sorted manually in this case.
- #
- do_test 1.2b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
- }
- } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
- # The same query with ORDER BY optimizations turned off via built-in test.
- #
- do_test 1.3a {
- optimization_control db order-by-idx-join 0
- db cache flush
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- do_test 1.3b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
- optimization_control db all 1
- db cache flush
- # Reverse order sorts
- #
- do_test 1.4a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {three-a three-c two-a two-b one-a one-c}
- do_test 1.4b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
- }
- } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
- do_test 1.4c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
- do_test 1.5a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a}
- do_test 1.5b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
- do_test 1.5c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
- do_test 1.6a {
- db eval {
- SELECT name FROM album CROSS JOIN track USING (aid)
- ORDER BY title DESC, tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a}
- do_test 1.6b {
- db eval {
- SELECT name FROM album CROSS JOIN track USING (aid)
- ORDER BY +title DESC, +tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
- do_test 1.6c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album CROSS JOIN track USING (aid)
- ORDER BY title DESC, tn DESC
- }
- } {~/ORDER BY/} ;# ORDER BY
- # Reconstruct the test data to use indices rather than integer primary keys.
- #
- do_test 2.0 {
- db eval {
- BEGIN;
- DROP TABLE album;
- DROP TABLE track;
- CREATE TABLE album(
- aid INT PRIMARY KEY,
- title TEXT NOT NULL
- );
- CREATE INDEX album_i1 ON album(title, aid);
- CREATE TABLE track(
- aid INTEGER NOT NULL REFERENCES album,
- tn INTEGER NOT NULL,
- name TEXT,
- UNIQUE(aid, tn)
- );
- INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three');
- INSERT INTO track VALUES
- (1, 1, 'one-a'),
- (20, 2, 'two-b'),
- (3, 3, 'three-c'),
- (1, 3, 'one-c'),
- (20, 1, 'two-a'),
- (3, 1, 'three-a');
- COMMIT;
- }
- } {}
- do_test 2.1a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- # Verify that the ORDER BY clause is optimized out
- #
- do_test 2.1b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {/ORDER BY/} ;# ORDER BY required because of missing aid term in ORDER BY
- do_test 2.1c {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- do_test 2.1d {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
- }
- } {/ORDER BY/} ;# ORDER BY required in this case
- # The same query with ORDER BY clause optimization disabled via + operators
- # should give exactly the same answer.
- #
- do_test 2.2a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- # The output is sorted manually in this case.
- #
- do_test 2.2b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
- }
- } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
- # The same query with ORDER BY optimizations turned off via built-in test.
- #
- do_test 2.3a {
- optimization_control db order-by-idx-join 0
- db cache flush
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- do_test 2.3b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
- optimization_control db all 1
- db cache flush
- # Reverse order sorts
- #
- do_test 2.4a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {three-a three-c two-a two-b one-a one-c}
- do_test 2.4b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
- }
- } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
- do_test 2.4c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
- do_test 2.5a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a}
- do_test 2.5b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
- do_test 2.5c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
- do_test 2.6a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a}
- do_test 2.6b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
- do_test 2.6c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
- }
- } {/ORDER BY/} ;# ORDER BY required
- # Generate another test dataset, but this time using mixed ASC/DESC indices.
- #
- do_test 3.0 {
- db eval {
- BEGIN;
- DROP TABLE album;
- DROP TABLE track;
- CREATE TABLE album(
- aid INTEGER PRIMARY KEY,
- title TEXT UNIQUE NOT NULL
- );
- CREATE TABLE track(
- tid INTEGER PRIMARY KEY,
- aid INTEGER NOT NULL REFERENCES album,
- tn INTEGER NOT NULL,
- name TEXT,
- UNIQUE(aid ASC, tn DESC)
- );
- INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
- INSERT INTO track VALUES
- (NULL, 1, 1, 'one-a'),
- (NULL, 2, 2, 'two-b'),
- (NULL, 3, 3, 'three-c'),
- (NULL, 1, 3, 'one-c'),
- (NULL, 2, 1, 'two-a'),
- (NULL, 3, 1, 'three-a');
- COMMIT;
- }
- } {}
- do_test 3.1a {
- db eval {
- SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a}
- # Verify that the ORDER BY clause is optimized out
- #
- do_test 3.1b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {~/ORDER BY/} ;# ORDER BY optimized out
- # The same query with ORDER BY clause optimization disabled via + operators
- # should give exactly the same answer.
- #
- do_test 3.2a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a}
- # The output is sorted manually in this case.
- #
- do_test 3.2b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
- }
- } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
- # The same query with ORDER BY optimizations turned off via built-in test.
- #
- do_test 3.3a {
- optimization_control db order-by-idx-join 0
- db cache flush
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {one-c one-a two-b two-a three-c three-a}
- do_test 3.3b {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
- }
- } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
- optimization_control db all 1
- db cache flush
- # Without the mixed ASC/DESC on ORDER BY
- #
- do_test 3.4a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {one-a one-c two-a two-b three-a three-c}
- do_test 3.4b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
- }
- } {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting
- do_test 3.4c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
- }
- } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
- do_test 3.5a {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a}
- do_test 3.5b {
- db eval {
- SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
- }
- } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
- do_test 3.5c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
- }
- } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
- do_test 3.6a {
- db eval {
- SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {three-a three-c two-a two-b one-a one-c}
- do_test 3.6b {
- db eval {
- SELECT name FROM album CROSS JOIN track USING (aid)
- ORDER BY +title DESC, +tn
- }
- } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
- do_test 3.6c {
- db eval {
- EXPLAIN QUERY PLAN
- SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
- }
- } {~/ORDER BY/} ;# inverted ASC/DESC is optimized out
- # Ticket 5ed1772895bf3deeab78c5e3519b1da9165c541b (2013-06-04)
- # Incorrect ORDER BY on an indexed JOIN
- #
- do_test 4.0 {
- db eval {
- CREATE TABLE t41(a INT UNIQUE NOT NULL, b INT NOT NULL);
- CREATE INDEX t41ba ON t41(b,a);
- CREATE TABLE t42(x INT NOT NULL REFERENCES t41(a), y INT NOT NULL);
- CREATE UNIQUE INDEX t42xy ON t42(x,y);
- INSERT INTO t41 VALUES(1,1),(3,1);
- INSERT INTO t42 VALUES(1,13),(1,15),(3,14),(3,16);
-
- SELECT b, y FROM t41 CROSS JOIN t42 ON x=a ORDER BY b, y;
- }
- } {1 13 1 14 1 15 1 16}
- finish_test
|