github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/orderby1.test (about) 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_eqp_test 5.0 { 458 SELECT 5 ORDER BY 1 459 } { 460 QUERY PLAN 461 `--SCAN CONSTANT ROW 462 } 463 do_execsql_test 5.1 { 464 EXPLAIN QUERY PLAN SELECT 5 UNION ALL SELECT 3 ORDER BY 1 465 } {~/B-TREE/} 466 do_execsql_test 5.2 { 467 SELECT 5 UNION ALL SELECT 3 ORDER BY 1 468 } {3 5} 469 do_execsql_test 5.3 { 470 SELECT 986 AS x GROUP BY X ORDER BY X 471 } {986} 472 473 # The following test (originally derived from a single test within fuzz.test) 474 # verifies that a PseudoTable cursor is not closed prematurely in a deeply 475 # nested query. This test caused a segfault on 3.8.5 beta. 476 # 477 do_execsql_test 6.0 { 478 CREATE TABLE abc(a, b, c); 479 INSERT INTO abc VALUES(1, 2, 3); 480 INSERT INTO abc VALUES(4, 5, 6); 481 INSERT INTO abc VALUES(7, 8, 9); 482 SELECT ( 483 SELECT 'hardware' FROM ( 484 SELECT 'software' ORDER BY 'firmware' ASC, 'sportswear' DESC 485 ) GROUP BY 1 HAVING length(b) 486 ) 487 FROM abc; 488 } {hardware hardware hardware} 489 490 # Here is a test for a query-planner problem reported on the SQLite 491 # mailing list on 2014-09-18 by "Merike". Beginning with version 3.8.0, 492 # a separate sort was being used rather than using the single-column 493 # index. This was due to an oversight in the indexMightHelpWithOrderby() 494 # routine in where.c. 495 # 496 do_execsql_test 7.0 { 497 CREATE TABLE t7(a,b); 498 CREATE INDEX t7a ON t7(a); 499 CREATE INDEX t7ab ON t7(a,b); 500 EXPLAIN QUERY PLAN 501 SELECT * FROM t7 WHERE a=?1 ORDER BY rowid; 502 } {~/ORDER BY/} 503 504 #------------------------------------------------------------------------- 505 # Test a partial sort large enough to cause the sorter to spill data 506 # to disk. 507 # 508 reset_db 509 do_execsql_test 8.0 { 510 PRAGMA cache_size = 5; 511 CREATE TABLE t1(a, b); 512 CREATE INDEX i1 ON t1(a); 513 } 514 515 do_eqp_test 8.1 { 516 SELECT * FROM t1 ORDER BY a, b; 517 } { 518 QUERY PLAN 519 |--SCAN t1 USING INDEX i1 520 `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY 521 } 522 523 do_execsql_test 8.2 { 524 WITH cnt(i) AS ( 525 SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<10000 526 ) 527 INSERT INTO t1 SELECT i%2, randomblob(500) FROM cnt; 528 } 529 530 do_test 8.3 { 531 db eval { SELECT * FROM t1 ORDER BY a, b } { incr res $a } 532 set res 533 } 5000 534 535 #--------------------------------------------------------------------------- 536 # https://www.sqlite.org/src/tktview/cb3aa0641d9a413841c004293a4fc06cdc122029 537 # 538 # Adverse interaction between scalar subqueries and the partial-sorting 539 # logic. 540 # 541 do_execsql_test 9.0 { 542 DROP TABLE IF EXISTS t1; 543 CREATE TABLE t1(x INTEGER PRIMARY KEY); 544 INSERT INTO t1 VALUES(1),(2); 545 DROP TABLE IF EXISTS t2; 546 CREATE TABLE t2(y); 547 INSERT INTO t2 VALUES(9),(8),(3),(4); 548 SELECT (SELECT x||y FROM t2, t1 ORDER BY x, y); 549 } {13} 550 551 # Problem found by OSSFuzz on 2018-05-05. This was caused by a new 552 # optimization that had not been previously released. 553 # 554 do_execsql_test 10.0 { 555 CREATE TABLE t10(a,b); 556 INSERT INTO t10 VALUES(1,2),(8,9),(3,4),(5,4),(0,7); 557 CREATE INDEX t10b ON t10(b); 558 SELECT b, rowid, '^' FROM t10 ORDER BY b, a LIMIT 4; 559 } {2 1 ^ 4 3 ^ 4 4 ^ 7 5 ^} 560 561 do_catchsql_test 11.0 { 562 VALUES(2) EXCEPT SELECT '' ORDER BY abc 563 } {1 {1st ORDER BY term does not match any column in the result set}} 564 565 566 finish_test