15cf8e8c7Sdrh# 2001 September 15 25cf8e8c7Sdrh# 35cf8e8c7Sdrh# The author disclaims copyright to this source code. In place of 45cf8e8c7Sdrh# a legal notice, here is a blessing: 55cf8e8c7Sdrh# 65cf8e8c7Sdrh# May you do good and not evil. 75cf8e8c7Sdrh# May you find forgiveness for yourself and forgive others. 85cf8e8c7Sdrh# May you share freely, never taking more than you give. 95cf8e8c7Sdrh# 105cf8e8c7Sdrh#*********************************************************************** 115cf8e8c7Sdrh# This file implements regression tests for SQLite library. The 125cf8e8c7Sdrh# focus of this file is testing SELECT statements that contain 135cf8e8c7Sdrh# aggregate min() and max() functions and which are handled as 145cf8e8c7Sdrh# as a special case. 155cf8e8c7Sdrh# 160880a746Sdrh# $Id: minmax.test,v 1.21 2008/07/08 18:05:26 drh Exp $ 175cf8e8c7Sdrh 185cf8e8c7Sdrhset testdir [file dirname $argv0] 195cf8e8c7Sdrhsource $testdir/tester.tcl 204ac391fcSdanset ::testprefix minmax 215cf8e8c7Sdrh 225cf8e8c7Sdrhdo_test minmax-1.0 { 235cf8e8c7Sdrh execsql { 245cf8e8c7Sdrh BEGIN; 255cf8e8c7Sdrh CREATE TABLE t1(x, y); 265cf8e8c7Sdrh INSERT INTO t1 VALUES(1,1); 275cf8e8c7Sdrh INSERT INTO t1 VALUES(2,2); 285cf8e8c7Sdrh INSERT INTO t1 VALUES(3,2); 295cf8e8c7Sdrh INSERT INTO t1 VALUES(4,3); 305cf8e8c7Sdrh INSERT INTO t1 VALUES(5,3); 315cf8e8c7Sdrh INSERT INTO t1 VALUES(6,3); 325cf8e8c7Sdrh INSERT INTO t1 VALUES(7,3); 335cf8e8c7Sdrh INSERT INTO t1 VALUES(8,4); 345cf8e8c7Sdrh INSERT INTO t1 VALUES(9,4); 355cf8e8c7Sdrh INSERT INTO t1 VALUES(10,4); 365cf8e8c7Sdrh INSERT INTO t1 VALUES(11,4); 375cf8e8c7Sdrh INSERT INTO t1 VALUES(12,4); 385cf8e8c7Sdrh INSERT INTO t1 VALUES(13,4); 395cf8e8c7Sdrh INSERT INTO t1 VALUES(14,4); 405cf8e8c7Sdrh INSERT INTO t1 VALUES(15,4); 415cf8e8c7Sdrh INSERT INTO t1 VALUES(16,5); 425cf8e8c7Sdrh INSERT INTO t1 VALUES(17,5); 435cf8e8c7Sdrh INSERT INTO t1 VALUES(18,5); 445cf8e8c7Sdrh INSERT INTO t1 VALUES(19,5); 455cf8e8c7Sdrh INSERT INTO t1 VALUES(20,5); 465cf8e8c7Sdrh COMMIT; 475cf8e8c7Sdrh SELECT DISTINCT y FROM t1 ORDER BY y; 485cf8e8c7Sdrh } 495cf8e8c7Sdrh} {1 2 3 4 5} 505cf8e8c7Sdrh 515cf8e8c7Sdrhdo_test minmax-1.1 { 525cf8e8c7Sdrh set sqlite_search_count 0 535cf8e8c7Sdrh execsql {SELECT min(x) FROM t1} 545cf8e8c7Sdrh} {1} 555cf8e8c7Sdrhdo_test minmax-1.2 { 565cf8e8c7Sdrh set sqlite_search_count 575cf8e8c7Sdrh} {19} 585cf8e8c7Sdrhdo_test minmax-1.3 { 595cf8e8c7Sdrh set sqlite_search_count 0 605cf8e8c7Sdrh execsql {SELECT max(x) FROM t1} 615cf8e8c7Sdrh} {20} 625cf8e8c7Sdrhdo_test minmax-1.4 { 635cf8e8c7Sdrh set sqlite_search_count 645cf8e8c7Sdrh} {19} 655cf8e8c7Sdrhdo_test minmax-1.5 { 665cf8e8c7Sdrh execsql {CREATE INDEX t1i1 ON t1(x)} 675cf8e8c7Sdrh set sqlite_search_count 0 685cf8e8c7Sdrh execsql {SELECT min(x) FROM t1} 695cf8e8c7Sdrh} {1} 705cf8e8c7Sdrhdo_test minmax-1.6 { 715cf8e8c7Sdrh set sqlite_search_count 72a9d1ccb9Sdanielk1977} {1} 735cf8e8c7Sdrhdo_test minmax-1.7 { 745cf8e8c7Sdrh set sqlite_search_count 0 755cf8e8c7Sdrh execsql {SELECT max(x) FROM t1} 765cf8e8c7Sdrh} {20} 775cf8e8c7Sdrhdo_test minmax-1.8 { 785cf8e8c7Sdrh set sqlite_search_count 79a9d1ccb9Sdanielk1977} {0} 805cf8e8c7Sdrhdo_test minmax-1.9 { 815cf8e8c7Sdrh set sqlite_search_count 0 825cf8e8c7Sdrh execsql {SELECT max(y) FROM t1} 835cf8e8c7Sdrh} {5} 845cf8e8c7Sdrhdo_test minmax-1.10 { 855cf8e8c7Sdrh set sqlite_search_count 865cf8e8c7Sdrh} {19} 875cf8e8c7Sdrh 880880a746Sdrhdo_test minmax-1.21 { 890880a746Sdrh execsql {SELECT min(x) FROM t1 WHERE x=5} 900880a746Sdrh} {5} 910880a746Sdrhdo_test minmax-1.22 { 920880a746Sdrh execsql {SELECT min(x) FROM t1 WHERE x>=5} 930880a746Sdrh} {5} 940880a746Sdrhdo_test minmax-1.23 { 950880a746Sdrh execsql {SELECT min(x) FROM t1 WHERE x>=4.5} 960880a746Sdrh} {5} 970880a746Sdrhdo_test minmax-1.24 { 980880a746Sdrh execsql {SELECT min(x) FROM t1 WHERE x<4.5} 990880a746Sdrh} {1} 1000880a746Sdrh 1015cf8e8c7Sdrhdo_test minmax-2.0 { 1025cf8e8c7Sdrh execsql { 1035cf8e8c7Sdrh CREATE TABLE t2(a INTEGER PRIMARY KEY, b); 1045cf8e8c7Sdrh INSERT INTO t2 SELECT * FROM t1; 1055cf8e8c7Sdrh } 1065cf8e8c7Sdrh set sqlite_search_count 0 1075cf8e8c7Sdrh execsql {SELECT min(a) FROM t2} 1085cf8e8c7Sdrh} {1} 1095cf8e8c7Sdrhdo_test minmax-2.1 { 1105cf8e8c7Sdrh set sqlite_search_count 1115cf8e8c7Sdrh} {0} 1125cf8e8c7Sdrhdo_test minmax-2.2 { 1135cf8e8c7Sdrh set sqlite_search_count 0 1145cf8e8c7Sdrh execsql {SELECT max(a) FROM t2} 1155cf8e8c7Sdrh} {20} 1165cf8e8c7Sdrhdo_test minmax-2.3 { 1175cf8e8c7Sdrh set sqlite_search_count 1185cf8e8c7Sdrh} {0} 1195cf8e8c7Sdrh 1205cf8e8c7Sdrhdo_test minmax-3.0 { 1213e8c37e7Sdanielk1977 ifcapable subquery { 1225cf8e8c7Sdrh execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 1233e8c37e7Sdanielk1977 } else { 1243e8c37e7Sdanielk1977 db function max_a_t2 {execsql {SELECT max(a) FROM t2}} 1253e8c37e7Sdanielk1977 execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} 1263e8c37e7Sdanielk1977 } 1275cf8e8c7Sdrh set sqlite_search_count 0 1285cf8e8c7Sdrh execsql {SELECT max(a) FROM t2} 1295cf8e8c7Sdrh} {21} 1305cf8e8c7Sdrhdo_test minmax-3.1 { 1315cf8e8c7Sdrh set sqlite_search_count 1325cf8e8c7Sdrh} {0} 1335cf8e8c7Sdrhdo_test minmax-3.2 { 1343e8c37e7Sdanielk1977 ifcapable subquery { 1355cf8e8c7Sdrh execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 1363e8c37e7Sdanielk1977 } else { 1373e8c37e7Sdanielk1977 db function max_a_t2 {execsql {SELECT max(a) FROM t2}} 1383e8c37e7Sdanielk1977 execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} 1393e8c37e7Sdanielk1977 } 1405cf8e8c7Sdrh set sqlite_search_count 0 1413e8c37e7Sdanielk1977 ifcapable subquery { 1423e8c37e7Sdanielk1977 execsql { SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) } 1433e8c37e7Sdanielk1977 } else { 1443e8c37e7Sdanielk1977 execsql { SELECT b FROM t2 WHERE a=max_a_t2() } 1455cf8e8c7Sdrh } 1465cf8e8c7Sdrh} {999} 1475cf8e8c7Sdrhdo_test minmax-3.3 { 1485cf8e8c7Sdrh set sqlite_search_count 1495cf8e8c7Sdrh} {0} 1505cf8e8c7Sdrh 151e61b9f4fSdanielk1977ifcapable {compound && subquery} { 152bb113518Sdrh do_test minmax-4.1 { 153bb113518Sdrh execsql { 154268380caSdrh SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM 155bb113518Sdrh (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y') 156bb113518Sdrh } 1579eb516c0Sdrh } {1 20} 158f570f011Sdrh do_test minmax-4.2 { 159f570f011Sdrh execsql { 1603f219f46Sdrh SELECT y, coalesce(sum(x),0) FROM 16192378253Sdrh (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1) 162f570f011Sdrh GROUP BY y ORDER BY y; 163f570f011Sdrh } 1643d1d95e6Sdrh } {1 1 2 5 3 22 4 92 5 90 6 0} 165f570f011Sdrh do_test minmax-4.3 { 166f570f011Sdrh execsql { 167f570f011Sdrh SELECT y, count(x), count(*) FROM 16892378253Sdrh (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1) 169f570f011Sdrh GROUP BY y ORDER BY y; 170f570f011Sdrh } 171f570f011Sdrh } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1} 17227c77438Sdanielk1977} ;# ifcapable compound 1735cf8e8c7Sdrh 174d4d595f9Sdrh# Make sure the min(x) and max(x) optimizations work on empty tables 175d4d595f9Sdrh# including empty tables with indices. Ticket #296. 176d4d595f9Sdrh# 177d4d595f9Sdrhdo_test minmax-5.1 { 178d4d595f9Sdrh execsql { 179d4d595f9Sdrh CREATE TABLE t3(x INTEGER UNIQUE NOT NULL); 180d4d595f9Sdrh SELECT coalesce(min(x),999) FROM t3; 181d4d595f9Sdrh } 182d4d595f9Sdrh} {999} 183d4d595f9Sdrhdo_test minmax-5.2 { 184d4d595f9Sdrh execsql { 185d4d595f9Sdrh SELECT coalesce(min(rowid),999) FROM t3; 186d4d595f9Sdrh } 187d4d595f9Sdrh} {999} 188d4d595f9Sdrhdo_test minmax-5.3 { 189d4d595f9Sdrh execsql { 190d4d595f9Sdrh SELECT coalesce(max(x),999) FROM t3; 191d4d595f9Sdrh } 192d4d595f9Sdrh} {999} 193d4d595f9Sdrhdo_test minmax-5.4 { 194d4d595f9Sdrh execsql { 195d4d595f9Sdrh SELECT coalesce(max(rowid),999) FROM t3; 196d4d595f9Sdrh } 197d4d595f9Sdrh} {999} 198d4d595f9Sdrhdo_test minmax-5.5 { 199d4d595f9Sdrh execsql { 200d4d595f9Sdrh SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25; 201d4d595f9Sdrh } 202d4d595f9Sdrh} {999} 203d4d595f9Sdrh 204e5f50722Sdrh# Make sure the min(x) and max(x) optimizations work when there 205e5f50722Sdrh# is a LIMIT clause. Ticket #396. 206e5f50722Sdrh# 207e5f50722Sdrhdo_test minmax-6.1 { 208e5f50722Sdrh execsql { 209e5f50722Sdrh SELECT min(a) FROM t2 LIMIT 1 210e5f50722Sdrh } 211e5f50722Sdrh} {1} 212e5f50722Sdrhdo_test minmax-6.2 { 213e5f50722Sdrh execsql { 214e5f50722Sdrh SELECT max(a) FROM t2 LIMIT 3 215e5f50722Sdrh } 216e5f50722Sdrh} {22} 217e5f50722Sdrhdo_test minmax-6.3 { 218e5f50722Sdrh execsql { 219e5f50722Sdrh SELECT min(a) FROM t2 LIMIT 0,100 220e5f50722Sdrh } 221e5f50722Sdrh} {1} 222e5f50722Sdrhdo_test minmax-6.4 { 223e5f50722Sdrh execsql { 224e5f50722Sdrh SELECT max(a) FROM t2 LIMIT 1,100 225e5f50722Sdrh } 226e5f50722Sdrh} {} 227e5f50722Sdrhdo_test minmax-6.5 { 228e5f50722Sdrh execsql { 229e5f50722Sdrh SELECT min(x) FROM t3 LIMIT 1 230e5f50722Sdrh } 231e5f50722Sdrh} {{}} 232e5f50722Sdrhdo_test minmax-6.6 { 233e5f50722Sdrh execsql { 234e5f50722Sdrh SELECT max(x) FROM t3 LIMIT 0 235e5f50722Sdrh } 236e5f50722Sdrh} {} 237e5f50722Sdrhdo_test minmax-6.7 { 238e5f50722Sdrh execsql { 239e5f50722Sdrh SELECT max(a) FROM t2 LIMIT 0 240e5f50722Sdrh } 241e5f50722Sdrh} {} 242e5f50722Sdrh 2430c37e630Sdrh# Make sure the max(x) and min(x) optimizations work for nested 2440c37e630Sdrh# queries. Ticket #587. 2450c37e630Sdrh# 2460c37e630Sdrhdo_test minmax-7.1 { 2470c37e630Sdrh execsql { 2480c37e630Sdrh SELECT max(x) FROM t1; 2490c37e630Sdrh } 2500c37e630Sdrh} 20 2513e8c37e7Sdanielk1977ifcapable subquery { 2520c37e630Sdrh do_test minmax-7.2 { 2530c37e630Sdrh execsql { 2540c37e630Sdrh SELECT * FROM (SELECT max(x) FROM t1); 2550c37e630Sdrh } 2560c37e630Sdrh } 20 2573e8c37e7Sdanielk1977} 2580c37e630Sdrhdo_test minmax-7.3 { 2590c37e630Sdrh execsql { 2600c37e630Sdrh SELECT min(x) FROM t1; 2610c37e630Sdrh } 2620c37e630Sdrh} 1 2633e8c37e7Sdanielk1977ifcapable subquery { 2640c37e630Sdrh do_test minmax-7.4 { 2650c37e630Sdrh execsql { 2660c37e630Sdrh SELECT * FROM (SELECT min(x) FROM t1); 2670c37e630Sdrh } 2680c37e630Sdrh } 1 2693e8c37e7Sdanielk1977} 2700c37e630Sdrh 271268380caSdrh# Make sure min(x) and max(x) work correctly when the datatype is 272268380caSdrh# TEXT instead of NUMERIC. Ticket #623. 273268380caSdrh# 274268380caSdrhdo_test minmax-8.1 { 275268380caSdrh execsql { 276268380caSdrh CREATE TABLE t4(a TEXT); 277268380caSdrh INSERT INTO t4 VALUES('1234'); 278268380caSdrh INSERT INTO t4 VALUES('234'); 279268380caSdrh INSERT INTO t4 VALUES('34'); 280268380caSdrh SELECT min(a), max(a) FROM t4; 281268380caSdrh } 282268380caSdrh} {1234 34} 283268380caSdrhdo_test minmax-8.2 { 284268380caSdrh execsql { 285268380caSdrh CREATE TABLE t5(a INTEGER); 286268380caSdrh INSERT INTO t5 VALUES('1234'); 287268380caSdrh INSERT INTO t5 VALUES('234'); 288268380caSdrh INSERT INTO t5 VALUES('34'); 289268380caSdrh SELECT min(a), max(a) FROM t5; 290268380caSdrh } 291268380caSdrh} {34 1234} 292268380caSdrh 2936e17529eSdrh# Ticket #658: Test the min()/max() optimization when the FROM clause 2946e17529eSdrh# is a subquery. 2956e17529eSdrh# 296e61b9f4fSdanielk1977ifcapable {compound && subquery} { 2976e5020e8Sdrh do_test minmax-9.0 { 2986e5020e8Sdrh execsql { 2996e5020e8Sdrh SELECT max(rowid) AS yy FROM t4 UNION SELECT max(rowid) FROM t5 3006e5020e8Sdrh } 3016e5020e8Sdrh } {3} 3026e17529eSdrh do_test minmax-9.1 { 3036e17529eSdrh execsql { 3046e5020e8Sdrh SELECT max(yy) FROM ( 3056e5020e8Sdrh SELECT max(rowid) AS yy FROM t4 UNION SELECT max(rowid) FROM t5 3066e17529eSdrh ) 3076e17529eSdrh } 3086e5020e8Sdrh } {3} 3096e17529eSdrh do_test minmax-9.2 { 3106e17529eSdrh execsql { 3116e5020e8Sdrh SELECT max(yy) FROM ( 3126e5020e8Sdrh SELECT max(rowid) AS yy FROM t4 EXCEPT SELECT max(rowid) FROM t5 3136e17529eSdrh ) 3146e17529eSdrh } 3156e17529eSdrh } {{}} 316e61b9f4fSdanielk1977} ;# ifcapable compound&&subquery 317d4d595f9Sdrh 3189eb516c0Sdrh# If there is a NULL in an aggregate max() or min(), ignore it. An 3199eb516c0Sdrh# aggregate min() or max() will only return NULL if all values are NULL. 3203aeab9e4Sdanielk1977# 3213aeab9e4Sdanielk1977do_test minmax-10.1 { 3223aeab9e4Sdanielk1977 execsql { 3233aeab9e4Sdanielk1977 CREATE TABLE t6(x); 3243aeab9e4Sdanielk1977 INSERT INTO t6 VALUES(1); 3253aeab9e4Sdanielk1977 INSERT INTO t6 VALUES(2); 3263aeab9e4Sdanielk1977 INSERT INTO t6 VALUES(NULL); 3273aeab9e4Sdanielk1977 SELECT coalesce(min(x),-1) FROM t6; 3283aeab9e4Sdanielk1977 } 3299eb516c0Sdrh} {1} 3303aeab9e4Sdanielk1977do_test minmax-10.2 { 3313aeab9e4Sdanielk1977 execsql { 3323aeab9e4Sdanielk1977 SELECT max(x) FROM t6; 3333aeab9e4Sdanielk1977 } 3343aeab9e4Sdanielk1977} {2} 3353aeab9e4Sdanielk1977do_test minmax-10.3 { 3363aeab9e4Sdanielk1977 execsql { 3373aeab9e4Sdanielk1977 CREATE INDEX i6 ON t6(x); 3383aeab9e4Sdanielk1977 SELECT coalesce(min(x),-1) FROM t6; 3393aeab9e4Sdanielk1977 } 3409eb516c0Sdrh} {1} 3413aeab9e4Sdanielk1977do_test minmax-10.4 { 3423aeab9e4Sdanielk1977 execsql { 3433aeab9e4Sdanielk1977 SELECT max(x) FROM t6; 3443aeab9e4Sdanielk1977 } 3453aeab9e4Sdanielk1977} {2} 3469eb516c0Sdrhdo_test minmax-10.5 { 3479eb516c0Sdrh execsql { 3489eb516c0Sdrh DELETE FROM t6 WHERE x NOT NULL; 3499eb516c0Sdrh SELECT count(*) FROM t6; 3509eb516c0Sdrh } 3519eb516c0Sdrh} 1 3529eb516c0Sdrhdo_test minmax-10.6 { 3539eb516c0Sdrh execsql { 3549eb516c0Sdrh SELECT count(x) FROM t6; 3559eb516c0Sdrh } 3569eb516c0Sdrh} 0 3573e8c37e7Sdanielk1977ifcapable subquery { 3589eb516c0Sdrh do_test minmax-10.7 { 3599eb516c0Sdrh execsql { 3609eb516c0Sdrh SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 3619eb516c0Sdrh } 3629eb516c0Sdrh } {{} {}} 3633e8c37e7Sdanielk1977} 3649eb516c0Sdrhdo_test minmax-10.8 { 3659eb516c0Sdrh execsql { 3669eb516c0Sdrh SELECT min(x), max(x) FROM t6; 3679eb516c0Sdrh } 3689eb516c0Sdrh} {{} {}} 3699eb516c0Sdrhdo_test minmax-10.9 { 3709eb516c0Sdrh execsql { 3719eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3729eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3739eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3749eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3759eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3769eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3779eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3789eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3799eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3809eb516c0Sdrh INSERT INTO t6 SELECT * FROM t6; 3819eb516c0Sdrh SELECT count(*) FROM t6; 3829eb516c0Sdrh } 3839eb516c0Sdrh} 1024 3849eb516c0Sdrhdo_test minmax-10.10 { 3859eb516c0Sdrh execsql { 3869eb516c0Sdrh SELECT count(x) FROM t6; 3879eb516c0Sdrh } 3889eb516c0Sdrh} 0 3893e8c37e7Sdanielk1977ifcapable subquery { 3909eb516c0Sdrh do_test minmax-10.11 { 3919eb516c0Sdrh execsql { 3929eb516c0Sdrh SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 3939eb516c0Sdrh } 3949eb516c0Sdrh } {{} {}} 3953e8c37e7Sdanielk1977} 3969eb516c0Sdrhdo_test minmax-10.12 { 3979eb516c0Sdrh execsql { 3989eb516c0Sdrh SELECT min(x), max(x) FROM t6; 3999eb516c0Sdrh } 4009eb516c0Sdrh} {{} {}} 4019eb516c0Sdrh 4023aeab9e4Sdanielk1977 4030880a746Sdrhdo_test minmax-11.1 { 4040880a746Sdrh execsql { 4050880a746Sdrh CREATE INDEX t1i2 ON t1(y,x); 4060880a746Sdrh SELECT min(x) FROM t1 WHERE y=5; 4070880a746Sdrh } 4080880a746Sdrh} {16} 4090880a746Sdrhdo_test minmax-11.2 { 4100880a746Sdrh execsql { 4110880a746Sdrh SELECT max(x) FROM t1 WHERE y=5; 4120880a746Sdrh } 4130880a746Sdrh} {20} 4140880a746Sdrhdo_test minmax-11.3 { 4150880a746Sdrh execsql { 4160880a746Sdrh SELECT min(x) FROM t1 WHERE y=6; 4170880a746Sdrh } 4180880a746Sdrh} {{}} 4190880a746Sdrhdo_test minmax-11.4 { 4200880a746Sdrh execsql { 4210880a746Sdrh SELECT max(x) FROM t1 WHERE y=6; 4220880a746Sdrh } 4230880a746Sdrh} {{}} 4240880a746Sdrhdo_test minmax-11.5 { 4250880a746Sdrh execsql { 4260880a746Sdrh SELECT min(x) FROM t1 WHERE y=1; 4270880a746Sdrh } 4280880a746Sdrh} {1} 4290880a746Sdrhdo_test minmax-11.6 { 4300880a746Sdrh execsql { 4310880a746Sdrh SELECT max(x) FROM t1 WHERE y=1; 4320880a746Sdrh } 4330880a746Sdrh} {1} 4340880a746Sdrhdo_test minmax-11.7 { 4350880a746Sdrh execsql { 4360880a746Sdrh SELECT min(x) FROM t1 WHERE y=0; 4370880a746Sdrh } 4380880a746Sdrh} {{}} 4390880a746Sdrhdo_test minmax-11.8 { 4400880a746Sdrh execsql { 4410880a746Sdrh SELECT max(x) FROM t1 WHERE y=0; 4420880a746Sdrh } 4430880a746Sdrh} {{}} 4440880a746Sdrhdo_test minmax-11.9 { 4450880a746Sdrh execsql { 4460880a746Sdrh SELECT min(x) FROM t1 WHERE y=5 AND x>=17.5; 4470880a746Sdrh } 4480880a746Sdrh} {18} 4490880a746Sdrhdo_test minmax-11.10 { 4500880a746Sdrh execsql { 4510880a746Sdrh SELECT max(x) FROM t1 WHERE y=5 AND x>=17.5; 4520880a746Sdrh } 4530880a746Sdrh} {20} 4540880a746Sdrh 4550880a746Sdrhdo_test minmax-12.1 { 4560880a746Sdrh execsql { 4570880a746Sdrh CREATE TABLE t7(a,b,c); 4580880a746Sdrh INSERT INTO t7 SELECT y, x, x*y FROM t1; 4590880a746Sdrh INSERT INTO t7 SELECT y, x, x*y+1000 FROM t1; 4600880a746Sdrh CREATE INDEX t7i1 ON t7(a,b,c); 4610880a746Sdrh SELECT min(a) FROM t7; 4620880a746Sdrh } 4630880a746Sdrh} {1} 4640880a746Sdrhdo_test minmax-12.2 { 4650880a746Sdrh execsql { 4660880a746Sdrh SELECT max(a) FROM t7; 4670880a746Sdrh } 4680880a746Sdrh} {5} 4690880a746Sdrhdo_test minmax-12.3 { 4700880a746Sdrh execsql { 4710880a746Sdrh SELECT max(a) FROM t7 WHERE a=5; 4720880a746Sdrh } 4730880a746Sdrh} {5} 4740880a746Sdrhdo_test minmax-12.4 { 4750880a746Sdrh execsql { 4760880a746Sdrh SELECT min(b) FROM t7 WHERE a=5; 4770880a746Sdrh } 4780880a746Sdrh} {16} 4790880a746Sdrhdo_test minmax-12.5 { 4800880a746Sdrh execsql { 4810880a746Sdrh SELECT max(b) FROM t7 WHERE a=5; 4820880a746Sdrh } 4830880a746Sdrh} {20} 4840880a746Sdrhdo_test minmax-12.6 { 4850880a746Sdrh execsql { 4860880a746Sdrh SELECT min(b) FROM t7 WHERE a=4; 4870880a746Sdrh } 4880880a746Sdrh} {8} 4890880a746Sdrhdo_test minmax-12.7 { 4900880a746Sdrh execsql { 4910880a746Sdrh SELECT max(b) FROM t7 WHERE a=4; 4920880a746Sdrh } 4930880a746Sdrh} {15} 4940880a746Sdrhdo_test minmax-12.8 { 4950880a746Sdrh execsql { 4960880a746Sdrh SELECT min(c) FROM t7 WHERE a=4 AND b=10; 4970880a746Sdrh } 4980880a746Sdrh} {40} 4990880a746Sdrhdo_test minmax-12.9 { 5000880a746Sdrh execsql { 5010880a746Sdrh SELECT max(c) FROM t7 WHERE a=4 AND b=10; 5020880a746Sdrh } 5030880a746Sdrh} {1040} 5040880a746Sdrhdo_test minmax-12.10 { 5050880a746Sdrh execsql { 5060880a746Sdrh SELECT min(rowid) FROM t7; 5070880a746Sdrh } 5080880a746Sdrh} {1} 5090880a746Sdrhdo_test minmax-12.11 { 5100880a746Sdrh execsql { 5110880a746Sdrh SELECT max(rowid) FROM t7; 5120880a746Sdrh } 5130880a746Sdrh} {40} 5140880a746Sdrhdo_test minmax-12.12 { 5150880a746Sdrh execsql { 5160880a746Sdrh SELECT min(rowid) FROM t7 WHERE a=3; 5170880a746Sdrh } 5180880a746Sdrh} {4} 5190880a746Sdrhdo_test minmax-12.13 { 5200880a746Sdrh execsql { 5210880a746Sdrh SELECT max(rowid) FROM t7 WHERE a=3; 5220880a746Sdrh } 5230880a746Sdrh} {27} 5240880a746Sdrhdo_test minmax-12.14 { 5250880a746Sdrh execsql { 5260880a746Sdrh SELECT min(rowid) FROM t7 WHERE a=3 AND b=5; 5270880a746Sdrh } 5280880a746Sdrh} {5} 5290880a746Sdrhdo_test minmax-12.15 { 5300880a746Sdrh execsql { 5310880a746Sdrh SELECT max(rowid) FROM t7 WHERE a=3 AND b=5; 5320880a746Sdrh } 5330880a746Sdrh} {25} 5340880a746Sdrhdo_test minmax-12.16 { 5350880a746Sdrh execsql { 5360880a746Sdrh SELECT min(rowid) FROM t7 WHERE a=3 AND b=5 AND c=1015; 5370880a746Sdrh } 5380880a746Sdrh} {25} 5390880a746Sdrhdo_test minmax-12.17 { 5400880a746Sdrh execsql { 5410880a746Sdrh SELECT max(rowid) FROM t7 WHERE a=3 AND b=5 AND c=15; 5420880a746Sdrh } 5430880a746Sdrh} {5} 5440880a746Sdrh 5454ac391fcSdan#------------------------------------------------------------------------- 5464ac391fcSdanreset_db 5470880a746Sdrh 5484ac391fcSdanproc do_test_13 {op name sql1 sql2 res} { 5494ac391fcSdan set ::sqlite_search_count 0 5504ac391fcSdan uplevel [list do_execsql_test $name.1 $sql1 $res] 5514ac391fcSdan set a $::sqlite_search_count 5524ac391fcSdan 5534ac391fcSdan set ::sqlite_search_count 0 5544ac391fcSdan uplevel [list do_execsql_test $name.2 $sql2 $res] 5554ac391fcSdan set b $::sqlite_search_count 5564ac391fcSdan 5574ac391fcSdan uplevel [list do_test $name.3 [list expr "$a $op $b"] 1] 5584ac391fcSdan} 5594ac391fcSdan 5604ac391fcSdan# Run a test named $name. Check that SQL statements $sql1 and $sql2 both 5614ac391fcSdan# return the same result, but that $sql2 increments the $sqlite_search_count 5624ac391fcSdan# variable more often (indicating that it is visiting more rows to determine 5634ac391fcSdan# the result). 5644ac391fcSdan# 5654ac391fcSdanproc do_test_13_opt {name sql1 sql2 res} { 5664ac391fcSdan uplevel [list do_test_13 < $name $sql1 $sql2 $res] 5674ac391fcSdan} 5684ac391fcSdan 5694ac391fcSdan# Like [do_test_13_noopt], except this time check that the $sqlite_search_count 5704ac391fcSdan# variable is incremented the same number of times by both SQL statements. 5714ac391fcSdan# 5724ac391fcSdanproc do_test_13_noopt {name sql1 sql2 res} { 5734ac391fcSdan uplevel [list do_test_13 == $name $sql1 $sql2 $res] 5744ac391fcSdan} 5754ac391fcSdan 5764ac391fcSdando_execsql_test 13.1 { 5774ac391fcSdan CREATE TABLE t1(a, b, c); 5784ac391fcSdan INSERT INTO t1 VALUES('a', 1, 1); 5794ac391fcSdan INSERT INTO t1 VALUES('b', 6, 6); 5804ac391fcSdan INSERT INTO t1 VALUES('c', 5, 5); 5814ac391fcSdan INSERT INTO t1 VALUES('a', 4, 4); 5824ac391fcSdan INSERT INTO t1 VALUES('a', 5, 5); 5834ac391fcSdan INSERT INTO t1 VALUES('c', 6, 6); 5844ac391fcSdan INSERT INTO t1 VALUES('b', 4, 4); 5854ac391fcSdan INSERT INTO t1 VALUES('c', 7, 7); 5864ac391fcSdan INSERT INTO t1 VALUES('b', 2, 2); 5874ac391fcSdan INSERT INTO t1 VALUES('b', 3, 3); 5884ac391fcSdan INSERT INTO t1 VALUES('a', 3, 3); 5894ac391fcSdan INSERT INTO t1 VALUES('b', 5, 5); 5904ac391fcSdan INSERT INTO t1 VALUES('c', 4, 4); 5914ac391fcSdan INSERT INTO t1 VALUES('c', 3, 3); 5924ac391fcSdan INSERT INTO t1 VALUES('a', 2, 2); 5934ac391fcSdan SELECT * FROM t1 ORDER BY a, b, c; 5944ac391fcSdan} {a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 5954ac391fcSdan b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 5964ac391fcSdan c 3 3 c 4 4 c 5 5 c 6 6 c 7 7 5974ac391fcSdan} 5984ac391fcSdando_execsql_test 13.2 { CREATE INDEX i1 ON t1(a, b, c) } 5994ac391fcSdan 6004ac391fcSdando_test_13_opt 13.3 { 6014ac391fcSdan SELECT min(b) FROM t1 WHERE a='b' 6024ac391fcSdan} { 6034ac391fcSdan SELECT min(c) FROM t1 WHERE a='b' 6044ac391fcSdan} {2} 6054ac391fcSdan 6064ac391fcSdando_test_13_opt 13.4 { 6074ac391fcSdan SELECT a, min(b) FROM t1 WHERE a='b' 6084ac391fcSdan} { 6094ac391fcSdan SELECT a, min(c) FROM t1 WHERE a='b' 6104ac391fcSdan} {b 2} 6114ac391fcSdan 6124ac391fcSdando_test_13_opt 13.4 { 6134ac391fcSdan SELECT a||c, max(b)+4 FROM t1 WHERE a='c' 6144ac391fcSdan} { 6154ac391fcSdan SELECT a||c, max(c)+4 FROM t1 WHERE a='c' 6164ac391fcSdan} {c7 11} 6174ac391fcSdan 6184ac391fcSdando_test_13_noopt 13.5 { 6194ac391fcSdan SELECT a||c, max(b+1) FROM t1 WHERE a='c' 6204ac391fcSdan} { 6214ac391fcSdan SELECT a||c, max(c+1) FROM t1 WHERE a='c' 6224ac391fcSdan} {c7 8} 6234ac391fcSdan 6244ac391fcSdando_test_13_noopt 13.6 { 6254ac391fcSdan SELECT count(b) FROM t1 WHERE a='c' 6264ac391fcSdan} { 6274ac391fcSdan SELECT count(c) FROM t1 WHERE a='c' 6284ac391fcSdan} {5} 6294ac391fcSdan 6304ac391fcSdando_test_13_noopt 13.7 { 6314ac391fcSdan SELECT min(b), count(b) FROM t1 WHERE a='a'; 6324ac391fcSdan} { 6334ac391fcSdan SELECT min(c), count(c) FROM t1 WHERE a='a'; 6344ac391fcSdan} {1 5} 6350880a746Sdrh 636426f4ab0Sdrh# 2016-07-26. https://www.sqlite.org/src/info/a0bac8b3c3d1bb75 637426f4ab0Sdrh# Incorrect result on a min() query after a CREATE INDEX. 638426f4ab0Sdrh# 639426f4ab0Sdrhdo_execsql_test 14.1 { 640426f4ab0Sdrh CREATE TABLE t14(a INTEGER, b INTEGER); 641426f4ab0Sdrh INSERT INTO t14(a,b) VALUES(100,2),(200,2),(300,2),(400,1),(500,2); 642426f4ab0Sdrh SELECT min(a) FROM t14 WHERE b='2' AND a>'50'; 643426f4ab0Sdrh} {100} 644426f4ab0Sdrhdo_execsql_test 14.2 { 645426f4ab0Sdrh CREATE INDEX t14ba ON t14(b,a); 646426f4ab0Sdrh SELECT min(a) FROM t14 WHERE b='2' AND a>'50'; 647426f4ab0Sdrh} {100} 648426f4ab0Sdrh 649*ce68b6bfSdrh# 2021-08-21. https://sqlite.org/forum/forumpost/cfcb4b461d 650*ce68b6bfSdrh# 651*ce68b6bfSdrhreset_db 652*ce68b6bfSdrhdo_execsql_test 15.1 { 653*ce68b6bfSdrh CREATE TABLE t1(a); 654*ce68b6bfSdrh CREATE TABLE t2(b); 655*ce68b6bfSdrh CREATE TABLE t3(c); 656*ce68b6bfSdrh INSERT INTO t1 VALUES(0); 657*ce68b6bfSdrh INSERT INTO t2 VALUES(5); 658*ce68b6bfSdrh SELECT MIN((SELECT b FROM t2 UNION SELECT x FROM (SELECT x FROM (SELECT 1 AS x WHERE t1.a=1) UNION ALL SELECT c FROM t3))) FROM t1; 659*ce68b6bfSdrh} {5} 6600880a746Sdrh 6615cf8e8c7Sdrhfinish_test 662