OLD | NEW |
1 # 2001 September 15 | 1 # 2001 September 15 |
2 # | 2 # |
3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
5 # | 5 # |
6 # May you do good and not evil. | 6 # May you do good and not evil. |
7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
9 # | 9 # |
10 #*********************************************************************** | 10 #*********************************************************************** |
11 # This file implements regression tests for SQLite library. The | 11 # This file implements regression tests for SQLite library. The |
12 # focus of this file is testing SELECT statements that contain | 12 # focus of this file is testing SELECT statements that contain |
13 # aggregate min() and max() functions and which are handled as | 13 # aggregate min() and max() functions and which are handled as |
14 # as a special case. | 14 # as a special case. |
15 # | 15 # |
16 # $Id: minmax.test,v 1.21 2008/07/08 18:05:26 drh Exp $ | 16 # $Id: minmax.test,v 1.21 2008/07/08 18:05:26 drh Exp $ |
17 | 17 |
18 set testdir [file dirname $argv0] | 18 set testdir [file dirname $argv0] |
19 source $testdir/tester.tcl | 19 source $testdir/tester.tcl |
| 20 set ::testprefix minmax |
20 | 21 |
21 do_test minmax-1.0 { | 22 do_test minmax-1.0 { |
22 execsql { | 23 execsql { |
23 BEGIN; | 24 BEGIN; |
24 CREATE TABLE t1(x, y); | 25 CREATE TABLE t1(x, y); |
25 INSERT INTO t1 VALUES(1,1); | 26 INSERT INTO t1 VALUES(1,1); |
26 INSERT INTO t1 VALUES(2,2); | 27 INSERT INTO t1 VALUES(2,2); |
27 INSERT INTO t1 VALUES(3,2); | 28 INSERT INTO t1 VALUES(3,2); |
28 INSERT INTO t1 VALUES(4,3); | 29 INSERT INTO t1 VALUES(4,3); |
29 INSERT INTO t1 VALUES(5,3); | 30 INSERT INTO t1 VALUES(5,3); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 # Ticket #658: Test the min()/max() optimization when the FROM clause | 293 # Ticket #658: Test the min()/max() optimization when the FROM clause |
293 # is a subquery. | 294 # is a subquery. |
294 # | 295 # |
295 ifcapable {compound && subquery} { | 296 ifcapable {compound && subquery} { |
296 do_test minmax-9.1 { | 297 do_test minmax-9.1 { |
297 execsql { | 298 execsql { |
298 SELECT max(rowid) FROM ( | 299 SELECT max(rowid) FROM ( |
299 SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 | 300 SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 |
300 ) | 301 ) |
301 } | 302 } |
302 } {1} | 303 } {{}} |
303 do_test minmax-9.2 { | 304 do_test minmax-9.2 { |
304 execsql { | 305 execsql { |
305 SELECT max(rowid) FROM ( | 306 SELECT max(rowid) FROM ( |
306 SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5 | 307 SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5 |
307 ) | 308 ) |
308 } | 309 } |
309 } {{}} | 310 } {{}} |
310 } ;# ifcapable compound&&subquery | 311 } ;# ifcapable compound&&subquery |
311 | 312 |
312 # If there is a NULL in an aggregate max() or min(), ignore it. An | 313 # If there is a NULL in an aggregate max() or min(), ignore it. An |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 execsql { | 530 execsql { |
530 SELECT min(rowid) FROM t7 WHERE a=3 AND b=5 AND c=1015; | 531 SELECT min(rowid) FROM t7 WHERE a=3 AND b=5 AND c=1015; |
531 } | 532 } |
532 } {25} | 533 } {25} |
533 do_test minmax-12.17 { | 534 do_test minmax-12.17 { |
534 execsql { | 535 execsql { |
535 SELECT max(rowid) FROM t7 WHERE a=3 AND b=5 AND c=15; | 536 SELECT max(rowid) FROM t7 WHERE a=3 AND b=5 AND c=15; |
536 } | 537 } |
537 } {5} | 538 } {5} |
538 | 539 |
| 540 #------------------------------------------------------------------------- |
| 541 reset_db |
539 | 542 |
| 543 proc do_test_13 {op name sql1 sql2 res} { |
| 544 set ::sqlite_search_count 0 |
| 545 uplevel [list do_execsql_test $name.1 $sql1 $res] |
| 546 set a $::sqlite_search_count |
| 547 |
| 548 set ::sqlite_search_count 0 |
| 549 uplevel [list do_execsql_test $name.2 $sql2 $res] |
| 550 set b $::sqlite_search_count |
| 551 |
| 552 uplevel [list do_test $name.3 [list expr "$a $op $b"] 1] |
| 553 } |
| 554 |
| 555 # Run a test named $name. Check that SQL statements $sql1 and $sql2 both |
| 556 # return the same result, but that $sql2 increments the $sqlite_search_count |
| 557 # variable more often (indicating that it is visiting more rows to determine |
| 558 # the result). |
| 559 # |
| 560 proc do_test_13_opt {name sql1 sql2 res} { |
| 561 uplevel [list do_test_13 < $name $sql1 $sql2 $res] |
| 562 } |
| 563 |
| 564 # Like [do_test_13_noopt], except this time check that the $sqlite_search_count |
| 565 # variable is incremented the same number of times by both SQL statements. |
| 566 # |
| 567 proc do_test_13_noopt {name sql1 sql2 res} { |
| 568 uplevel [list do_test_13 == $name $sql1 $sql2 $res] |
| 569 } |
| 570 |
| 571 do_execsql_test 13.1 { |
| 572 CREATE TABLE t1(a, b, c); |
| 573 INSERT INTO t1 VALUES('a', 1, 1); |
| 574 INSERT INTO t1 VALUES('b', 6, 6); |
| 575 INSERT INTO t1 VALUES('c', 5, 5); |
| 576 INSERT INTO t1 VALUES('a', 4, 4); |
| 577 INSERT INTO t1 VALUES('a', 5, 5); |
| 578 INSERT INTO t1 VALUES('c', 6, 6); |
| 579 INSERT INTO t1 VALUES('b', 4, 4); |
| 580 INSERT INTO t1 VALUES('c', 7, 7); |
| 581 INSERT INTO t1 VALUES('b', 2, 2); |
| 582 INSERT INTO t1 VALUES('b', 3, 3); |
| 583 INSERT INTO t1 VALUES('a', 3, 3); |
| 584 INSERT INTO t1 VALUES('b', 5, 5); |
| 585 INSERT INTO t1 VALUES('c', 4, 4); |
| 586 INSERT INTO t1 VALUES('c', 3, 3); |
| 587 INSERT INTO t1 VALUES('a', 2, 2); |
| 588 SELECT * FROM t1 ORDER BY a, b, c; |
| 589 } {a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 |
| 590 b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 |
| 591 c 3 3 c 4 4 c 5 5 c 6 6 c 7 7 |
| 592 } |
| 593 do_execsql_test 13.2 { CREATE INDEX i1 ON t1(a, b, c) } |
| 594 |
| 595 do_test_13_opt 13.3 { |
| 596 SELECT min(b) FROM t1 WHERE a='b' |
| 597 } { |
| 598 SELECT min(c) FROM t1 WHERE a='b' |
| 599 } {2} |
| 600 |
| 601 do_test_13_opt 13.4 { |
| 602 SELECT a, min(b) FROM t1 WHERE a='b' |
| 603 } { |
| 604 SELECT a, min(c) FROM t1 WHERE a='b' |
| 605 } {b 2} |
| 606 |
| 607 do_test_13_opt 13.4 { |
| 608 SELECT a||c, max(b)+4 FROM t1 WHERE a='c' |
| 609 } { |
| 610 SELECT a||c, max(c)+4 FROM t1 WHERE a='c' |
| 611 } {c7 11} |
| 612 |
| 613 do_test_13_noopt 13.5 { |
| 614 SELECT a||c, max(b+1) FROM t1 WHERE a='c' |
| 615 } { |
| 616 SELECT a||c, max(c+1) FROM t1 WHERE a='c' |
| 617 } {c7 8} |
| 618 |
| 619 do_test_13_noopt 13.6 { |
| 620 SELECT count(b) FROM t1 WHERE a='c' |
| 621 } { |
| 622 SELECT count(c) FROM t1 WHERE a='c' |
| 623 } {5} |
| 624 |
| 625 do_test_13_noopt 13.7 { |
| 626 SELECT min(b), count(b) FROM t1 WHERE a='a'; |
| 627 } { |
| 628 SELECT min(c), count(c) FROM t1 WHERE a='a'; |
| 629 } {1 5} |
540 | 630 |
541 | 631 |
542 finish_test | 632 finish_test |
OLD | NEW |