3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing that the optimizations that disable
13 # ORDER BY clauses when the natural order of a query is correct.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
19 set ::testprefix orderby1
21 # Generate test data for a join. Verify that the join gets the
28 aid INTEGER PRIMARY KEY,
29 title TEXT UNIQUE NOT NULL
32 tid INTEGER PRIMARY KEY,
33 aid INTEGER NOT NULL REFERENCES album,
38 INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
39 INSERT INTO track VALUES
40 (NULL, 1, 1, 'one-a'),
41 (NULL, 2, 2, 'two-b'),
42 (NULL, 3, 3, 'three-c'),
43 (NULL, 1, 3, 'one-c'),
44 (NULL, 2, 1, 'two-a'),
45 (NULL, 3, 1, 'three-a');
51 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
53 } {one-a one-c two-a two-b three-a three-c}
55 # Verify that the ORDER BY clause is optimized out
60 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
62 } {~/ORDER BY/} ;# ORDER BY optimized out
64 # The same query with ORDER BY clause optimization disabled via + operators
65 # should give exactly the same answer.
69 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
71 } {one-a one-c two-a two-b three-a three-c}
73 # The output is sorted manually in this case.
78 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
80 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
82 # The same query with ORDER BY optimizations turned off via built-in test.
85 optimization_control db order-by-idx-join 0
88 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
90 } {one-a one-c two-a two-b three-a three-c}
94 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
96 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
97 optimization_control db all 1
100 # Reverse order sorts
104 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
106 } {three-a three-c two-a two-b one-a one-c}
109 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
111 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
115 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
117 } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
121 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
123 } {one-c one-a two-b two-a three-c three-a}
126 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
128 } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
132 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
134 } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
138 SELECT name FROM album CROSS JOIN track USING (aid)
139 ORDER BY title DESC, tn DESC
141 } {three-c three-a two-b two-a one-c one-a}
144 SELECT name FROM album CROSS JOIN track USING (aid)
145 ORDER BY +title DESC, +tn DESC
147 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
151 SELECT name FROM album CROSS JOIN track USING (aid)
152 ORDER BY title DESC, tn DESC
154 } {~/ORDER BY/} ;# ORDER BY
157 # Reconstruct the test data to use indices rather than integer primary keys.
168 CREATE INDEX album_i1 ON album(title, aid);
170 aid INTEGER NOT NULL REFERENCES album,
175 INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three');
176 INSERT INTO track VALUES
188 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
190 } {one-a one-c two-a two-b three-a three-c}
192 # Verify that the ORDER BY clause is optimized out
197 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
199 } {/ORDER BY/} ;# ORDER BY required because of missing aid term in ORDER BY
203 SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
205 } {one-a one-c two-a two-b three-a three-c}
209 SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
211 } {/ORDER BY/} ;# ORDER BY required in this case
213 # The same query with ORDER BY clause optimization disabled via + operators
214 # should give exactly the same answer.
218 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
220 } {one-a one-c two-a two-b three-a three-c}
222 # The output is sorted manually in this case.
227 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
229 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
231 # The same query with ORDER BY optimizations turned off via built-in test.
234 optimization_control db order-by-idx-join 0
237 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
239 } {one-a one-c two-a two-b three-a three-c}
243 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
245 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
246 optimization_control db all 1
249 # Reverse order sorts
253 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
255 } {three-a three-c two-a two-b one-a one-c}
258 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
260 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
264 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
266 } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
271 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
273 } {one-c one-a two-b two-a three-c three-a}
276 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
278 } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
282 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
284 } {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
288 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
290 } {three-c three-a two-b two-a one-c one-a}
293 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
295 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
299 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
301 } {/ORDER BY/} ;# ORDER BY required
304 # Generate another test dataset, but this time using mixed ASC/DESC indices.
312 aid INTEGER PRIMARY KEY,
313 title TEXT UNIQUE NOT NULL
316 tid INTEGER PRIMARY KEY,
317 aid INTEGER NOT NULL REFERENCES album,
320 UNIQUE(aid ASC, tn DESC)
322 INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
323 INSERT INTO track VALUES
324 (NULL, 1, 1, 'one-a'),
325 (NULL, 2, 2, 'two-b'),
326 (NULL, 3, 3, 'three-c'),
327 (NULL, 1, 3, 'one-c'),
328 (NULL, 2, 1, 'two-a'),
329 (NULL, 3, 1, 'three-a');
335 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
337 } {one-c one-a two-b two-a three-c three-a}
339 # Verify that the ORDER BY clause is optimized out
344 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
346 } {~/ORDER BY/} ;# ORDER BY optimized out
348 # The same query with ORDER BY clause optimization disabled via + operators
349 # should give exactly the same answer.
353 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
355 } {one-c one-a two-b two-a three-c three-a}
357 # The output is sorted manually in this case.
362 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
364 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
366 # The same query with ORDER BY optimizations turned off via built-in test.
369 optimization_control db order-by-idx-join 0
372 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
374 } {one-c one-a two-b two-a three-c three-a}
378 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
380 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
381 optimization_control db all 1
384 # Without the mixed ASC/DESC on ORDER BY
388 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
390 } {one-a one-c two-a two-b three-a three-c}
393 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
395 } {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting
399 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
401 } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
405 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
407 } {three-c three-a two-b two-a one-c one-a}
410 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
412 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
416 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
418 } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
423 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
425 } {three-a three-c two-a two-b one-a one-c}
428 SELECT name FROM album CROSS JOIN track USING (aid)
429 ORDER BY +title DESC, +tn
431 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
435 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
437 } {~/ORDER BY/} ;# inverted ASC/DESC is optimized out
439 # Ticket 5ed1772895bf3deeab78c5e3519b1da9165c541b (2013-06-04)
440 # Incorrect ORDER BY on an indexed JOIN
444 CREATE TABLE t41(a INT UNIQUE NOT NULL, b INT NOT NULL);
445 CREATE INDEX t41ba ON t41(b,a);
446 CREATE TABLE t42(x INT NOT NULL REFERENCES t41(a), y INT NOT NULL);
447 CREATE UNIQUE INDEX t42xy ON t42(x,y);
448 INSERT INTO t41 VALUES(1,1),(3,1);
449 INSERT INTO t42 VALUES(1,13),(1,15),(3,14),(3,16);
451 SELECT b, y FROM t41 CROSS JOIN t42 ON x=a ORDER BY b, y;
453 } {1 13 1 14 1 15 1 16}
455 # No sorting of queries that omit the FROM clause.
457 do_execsql_test 5.0 {
458 EXPLAIN QUERY PLAN SELECT 5 ORDER BY 1
460 do_execsql_test 5.1 {
461 EXPLAIN QUERY PLAN SELECT 5 UNION ALL SELECT 3 ORDER BY 1
463 do_execsql_test 5.2 {
464 SELECT 5 UNION ALL SELECT 3 ORDER BY 1
467 # The following test (originally derived from a single test within fuzz.test)
468 # verifies that a PseudoTable cursor is not closed prematurely in a deeply
469 # nested query. This test caused a segfault on 3.8.5 beta.
471 do_execsql_test 6.0 {
472 CREATE TABLE abc(a, b, c);
473 INSERT INTO abc VALUES(1, 2, 3);
474 INSERT INTO abc VALUES(4, 5, 6);
475 INSERT INTO abc VALUES(7, 8, 9);
477 SELECT 'hardware' FROM (
478 SELECT 'software' ORDER BY 'firmware' ASC, 'sportswear' DESC
479 ) GROUP BY 1 HAVING length(b)
482 } {hardware hardware hardware}
484 # Here is a test for a query-planner problem reported on the SQLite
485 # mailing list on 2014-09-18 by "Merike". Beginning with version 3.8.0,
486 # a separate sort was being used rather than using the single-column
487 # index. This was due to an oversight in the indexMightHelpWithOrderby()
488 # routine in where.c.
490 do_execsql_test 7.0 {
491 CREATE TABLE t7(a,b);
492 CREATE INDEX t7a ON t7(a);
493 CREATE INDEX t7ab ON t7(a,b);
495 SELECT * FROM t7 WHERE a=?1 ORDER BY rowid;