OLD | NEW |
| (Empty) |
1 # 2012 Sept 27 | |
2 # | |
3 # The author disclaims copyright to this source code. In place of | |
4 # a legal notice, here is a blessing: | |
5 # | |
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. | |
9 # | |
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. | |
14 # | |
15 | |
16 | |
17 set testdir [file dirname $argv0] | |
18 source $testdir/tester.tcl | |
19 set ::testprefix orderby1 | |
20 | |
21 # Generate test data for a join. Verify that the join gets the | |
22 # correct answer. | |
23 # | |
24 do_test 1.0 { | |
25 db eval { | |
26 BEGIN; | |
27 CREATE TABLE album( | |
28 aid INTEGER PRIMARY KEY, | |
29 title TEXT UNIQUE NOT NULL | |
30 ); | |
31 CREATE TABLE track( | |
32 tid INTEGER PRIMARY KEY, | |
33 aid INTEGER NOT NULL REFERENCES album, | |
34 tn INTEGER NOT NULL, | |
35 name TEXT, | |
36 UNIQUE(aid, tn) | |
37 ); | |
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'); | |
46 COMMIT; | |
47 } | |
48 } {} | |
49 do_test 1.1a { | |
50 db eval { | |
51 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
52 } | |
53 } {one-a one-c two-a two-b three-a three-c} | |
54 | |
55 # Verify that the ORDER BY clause is optimized out | |
56 # | |
57 do_test 1.1b { | |
58 db eval { | |
59 EXPLAIN QUERY PLAN | |
60 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn | |
61 } | |
62 } {~/ORDER BY/} ;# ORDER BY optimized out | |
63 | |
64 # The same query with ORDER BY clause optimization disabled via + operators | |
65 # should give exactly the same answer. | |
66 # | |
67 do_test 1.2a { | |
68 db eval { | |
69 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn | |
70 } | |
71 } {one-a one-c two-a two-b three-a three-c} | |
72 | |
73 # The output is sorted manually in this case. | |
74 # | |
75 do_test 1.2b { | |
76 db eval { | |
77 EXPLAIN QUERY PLAN | |
78 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn | |
79 } | |
80 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms | |
81 | |
82 # The same query with ORDER BY optimizations turned off via built-in test. | |
83 # | |
84 do_test 1.3a { | |
85 optimization_control db order-by-idx-join 0 | |
86 db cache flush | |
87 db eval { | |
88 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
89 } | |
90 } {one-a one-c two-a two-b three-a three-c} | |
91 do_test 1.3b { | |
92 db eval { | |
93 EXPLAIN QUERY PLAN | |
94 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
95 } | |
96 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization | |
97 optimization_control db all 1 | |
98 db cache flush | |
99 | |
100 # Reverse order sorts | |
101 # | |
102 do_test 1.4a { | |
103 db eval { | |
104 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn | |
105 } | |
106 } {three-a three-c two-a two-b one-a one-c} | |
107 do_test 1.4b { | |
108 db eval { | |
109 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn | |
110 } | |
111 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting | |
112 do_test 1.4c { | |
113 db eval { | |
114 EXPLAIN QUERY PLAN | |
115 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn | |
116 } | |
117 } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints | |
118 | |
119 do_test 1.5a { | |
120 db eval { | |
121 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
122 } | |
123 } {one-c one-a two-b two-a three-c three-a} | |
124 do_test 1.5b { | |
125 db eval { | |
126 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC | |
127 } | |
128 } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting | |
129 do_test 1.5c { | |
130 db eval { | |
131 EXPLAIN QUERY PLAN | |
132 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
133 } | |
134 } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints | |
135 | |
136 do_test 1.6a { | |
137 db eval { | |
138 SELECT name FROM album CROSS JOIN track USING (aid) | |
139 ORDER BY title DESC, tn DESC | |
140 } | |
141 } {three-c three-a two-b two-a one-c one-a} | |
142 do_test 1.6b { | |
143 db eval { | |
144 SELECT name FROM album CROSS JOIN track USING (aid) | |
145 ORDER BY +title DESC, +tn DESC | |
146 } | |
147 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting | |
148 do_test 1.6c { | |
149 db eval { | |
150 EXPLAIN QUERY PLAN | |
151 SELECT name FROM album CROSS JOIN track USING (aid) | |
152 ORDER BY title DESC, tn DESC | |
153 } | |
154 } {~/ORDER BY/} ;# ORDER BY | |
155 | |
156 | |
157 # Reconstruct the test data to use indices rather than integer primary keys. | |
158 # | |
159 do_test 2.0 { | |
160 db eval { | |
161 BEGIN; | |
162 DROP TABLE album; | |
163 DROP TABLE track; | |
164 CREATE TABLE album( | |
165 aid INT PRIMARY KEY, | |
166 title TEXT NOT NULL | |
167 ); | |
168 CREATE INDEX album_i1 ON album(title, aid); | |
169 CREATE TABLE track( | |
170 aid INTEGER NOT NULL REFERENCES album, | |
171 tn INTEGER NOT NULL, | |
172 name TEXT, | |
173 UNIQUE(aid, tn) | |
174 ); | |
175 INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three'); | |
176 INSERT INTO track VALUES | |
177 (1, 1, 'one-a'), | |
178 (20, 2, 'two-b'), | |
179 (3, 3, 'three-c'), | |
180 (1, 3, 'one-c'), | |
181 (20, 1, 'two-a'), | |
182 (3, 1, 'three-a'); | |
183 COMMIT; | |
184 } | |
185 } {} | |
186 do_test 2.1a { | |
187 db eval { | |
188 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
189 } | |
190 } {one-a one-c two-a two-b three-a three-c} | |
191 | |
192 # Verify that the ORDER BY clause is optimized out | |
193 # | |
194 do_test 2.1b { | |
195 db eval { | |
196 EXPLAIN QUERY PLAN | |
197 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
198 } | |
199 } {/ORDER BY/} ;# ORDER BY required because of missing aid term in ORDER BY | |
200 | |
201 do_test 2.1c { | |
202 db eval { | |
203 SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn | |
204 } | |
205 } {one-a one-c two-a two-b three-a three-c} | |
206 do_test 2.1d { | |
207 db eval { | |
208 EXPLAIN QUERY PLAN | |
209 SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn | |
210 } | |
211 } {/ORDER BY/} ;# ORDER BY required in this case | |
212 | |
213 # The same query with ORDER BY clause optimization disabled via + operators | |
214 # should give exactly the same answer. | |
215 # | |
216 do_test 2.2a { | |
217 db eval { | |
218 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn | |
219 } | |
220 } {one-a one-c two-a two-b three-a three-c} | |
221 | |
222 # The output is sorted manually in this case. | |
223 # | |
224 do_test 2.2b { | |
225 db eval { | |
226 EXPLAIN QUERY PLAN | |
227 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn | |
228 } | |
229 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms | |
230 | |
231 # The same query with ORDER BY optimizations turned off via built-in test. | |
232 # | |
233 do_test 2.3a { | |
234 optimization_control db order-by-idx-join 0 | |
235 db cache flush | |
236 db eval { | |
237 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
238 } | |
239 } {one-a one-c two-a two-b three-a three-c} | |
240 do_test 2.3b { | |
241 db eval { | |
242 EXPLAIN QUERY PLAN | |
243 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
244 } | |
245 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization | |
246 optimization_control db all 1 | |
247 db cache flush | |
248 | |
249 # Reverse order sorts | |
250 # | |
251 do_test 2.4a { | |
252 db eval { | |
253 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn | |
254 } | |
255 } {three-a three-c two-a two-b one-a one-c} | |
256 do_test 2.4b { | |
257 db eval { | |
258 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn | |
259 } | |
260 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting | |
261 do_test 2.4c { | |
262 db eval { | |
263 EXPLAIN QUERY PLAN | |
264 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn | |
265 } | |
266 } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC | |
267 | |
268 | |
269 do_test 2.5a { | |
270 db eval { | |
271 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
272 } | |
273 } {one-c one-a two-b two-a three-c three-a} | |
274 do_test 2.5b { | |
275 db eval { | |
276 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC | |
277 } | |
278 } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting | |
279 do_test 2.5c { | |
280 db eval { | |
281 EXPLAIN QUERY PLAN | |
282 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
283 } | |
284 } {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC | |
285 | |
286 do_test 2.6a { | |
287 db eval { | |
288 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC | |
289 } | |
290 } {three-c three-a two-b two-a one-c one-a} | |
291 do_test 2.6b { | |
292 db eval { | |
293 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC | |
294 } | |
295 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting | |
296 do_test 2.6c { | |
297 db eval { | |
298 EXPLAIN QUERY PLAN | |
299 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC | |
300 } | |
301 } {/ORDER BY/} ;# ORDER BY required | |
302 | |
303 | |
304 # Generate another test dataset, but this time using mixed ASC/DESC indices. | |
305 # | |
306 do_test 3.0 { | |
307 db eval { | |
308 BEGIN; | |
309 DROP TABLE album; | |
310 DROP TABLE track; | |
311 CREATE TABLE album( | |
312 aid INTEGER PRIMARY KEY, | |
313 title TEXT UNIQUE NOT NULL | |
314 ); | |
315 CREATE TABLE track( | |
316 tid INTEGER PRIMARY KEY, | |
317 aid INTEGER NOT NULL REFERENCES album, | |
318 tn INTEGER NOT NULL, | |
319 name TEXT, | |
320 UNIQUE(aid ASC, tn DESC) | |
321 ); | |
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'); | |
330 COMMIT; | |
331 } | |
332 } {} | |
333 do_test 3.1a { | |
334 db eval { | |
335 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC | |
336 } | |
337 } {one-c one-a two-b two-a three-c three-a} | |
338 | |
339 # Verify that the ORDER BY clause is optimized out | |
340 # | |
341 do_test 3.1b { | |
342 db eval { | |
343 EXPLAIN QUERY PLAN | |
344 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC | |
345 } | |
346 } {~/ORDER BY/} ;# ORDER BY optimized out | |
347 | |
348 # The same query with ORDER BY clause optimization disabled via + operators | |
349 # should give exactly the same answer. | |
350 # | |
351 do_test 3.2a { | |
352 db eval { | |
353 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC | |
354 } | |
355 } {one-c one-a two-b two-a three-c three-a} | |
356 | |
357 # The output is sorted manually in this case. | |
358 # | |
359 do_test 3.2b { | |
360 db eval { | |
361 EXPLAIN QUERY PLAN | |
362 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC | |
363 } | |
364 } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms | |
365 | |
366 # The same query with ORDER BY optimizations turned off via built-in test. | |
367 # | |
368 do_test 3.3a { | |
369 optimization_control db order-by-idx-join 0 | |
370 db cache flush | |
371 db eval { | |
372 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
373 } | |
374 } {one-c one-a two-b two-a three-c three-a} | |
375 do_test 3.3b { | |
376 db eval { | |
377 EXPLAIN QUERY PLAN | |
378 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC | |
379 } | |
380 } {/ORDER BY/} ;# separate sorting pass due to disabled optimization | |
381 optimization_control db all 1 | |
382 db cache flush | |
383 | |
384 # Without the mixed ASC/DESC on ORDER BY | |
385 # | |
386 do_test 3.4a { | |
387 db eval { | |
388 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
389 } | |
390 } {one-a one-c two-a two-b three-a three-c} | |
391 do_test 3.4b { | |
392 db eval { | |
393 SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn | |
394 } | |
395 } {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting | |
396 do_test 3.4c { | |
397 db eval { | |
398 EXPLAIN QUERY PLAN | |
399 SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn | |
400 } | |
401 } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints | |
402 | |
403 do_test 3.5a { | |
404 db eval { | |
405 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC | |
406 } | |
407 } {three-c three-a two-b two-a one-c one-a} | |
408 do_test 3.5b { | |
409 db eval { | |
410 SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC | |
411 } | |
412 } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting | |
413 do_test 3.5c { | |
414 db eval { | |
415 EXPLAIN QUERY PLAN | |
416 SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC | |
417 } | |
418 } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints | |
419 | |
420 | |
421 do_test 3.6a { | |
422 db eval { | |
423 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn | |
424 } | |
425 } {three-a three-c two-a two-b one-a one-c} | |
426 do_test 3.6b { | |
427 db eval { | |
428 SELECT name FROM album CROSS JOIN track USING (aid) | |
429 ORDER BY +title DESC, +tn | |
430 } | |
431 } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting | |
432 do_test 3.6c { | |
433 db eval { | |
434 EXPLAIN QUERY PLAN | |
435 SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn | |
436 } | |
437 } {~/ORDER BY/} ;# inverted ASC/DESC is optimized out | |
438 | |
439 # Ticket 5ed1772895bf3deeab78c5e3519b1da9165c541b (2013-06-04) | |
440 # Incorrect ORDER BY on an indexed JOIN | |
441 # | |
442 do_test 4.0 { | |
443 db eval { | |
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); | |
450 | |
451 SELECT b, y FROM t41 CROSS JOIN t42 ON x=a ORDER BY b, y; | |
452 } | |
453 } {1 13 1 14 1 15 1 16} | |
454 | |
455 # No sorting of queries that omit the FROM clause. | |
456 # | |
457 do_execsql_test 5.0 { | |
458 EXPLAIN QUERY PLAN SELECT 5 ORDER BY 1 | |
459 } {} | |
460 do_execsql_test 5.1 { | |
461 EXPLAIN QUERY PLAN SELECT 5 UNION ALL SELECT 3 ORDER BY 1 | |
462 } {~/B-TREE/} | |
463 do_execsql_test 5.2 { | |
464 SELECT 5 UNION ALL SELECT 3 ORDER BY 1 | |
465 } {3 5} | |
466 | |
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. | |
470 # | |
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); | |
476 SELECT ( | |
477 SELECT 'hardware' FROM ( | |
478 SELECT 'software' ORDER BY 'firmware' ASC, 'sportswear' DESC | |
479 ) GROUP BY 1 HAVING length(b) | |
480 ) | |
481 FROM abc; | |
482 } {hardware hardware hardware} | |
483 | |
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. | |
489 # | |
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); | |
494 EXPLAIN QUERY PLAN | |
495 SELECT * FROM t7 WHERE a=?1 ORDER BY rowid; | |
496 } {~/ORDER BY/} | |
497 | |
498 | |
499 finish_test | |
OLD | NEW |