1*c5c4113dSnw141292 2*c5c4113dSnw141292#pragma ident "%Z%%M% %I% %E% SMI" 3*c5c4113dSnw141292 4*c5c4113dSnw141292# 2001 September 15 5*c5c4113dSnw141292# 6*c5c4113dSnw141292# The author disclaims copyright to this source code. In place of 7*c5c4113dSnw141292# a legal notice, here is a blessing: 8*c5c4113dSnw141292# 9*c5c4113dSnw141292# May you do good and not evil. 10*c5c4113dSnw141292# May you find forgiveness for yourself and forgive others. 11*c5c4113dSnw141292# May you share freely, never taking more than you give. 12*c5c4113dSnw141292# 13*c5c4113dSnw141292#*********************************************************************** 14*c5c4113dSnw141292# This file implements regression tests for SQLite library. The 15*c5c4113dSnw141292# focus of this file is testing SELECT statements that contain 16*c5c4113dSnw141292# aggregate min() and max() functions and which are handled as 17*c5c4113dSnw141292# as a special case. 18*c5c4113dSnw141292# 19*c5c4113dSnw141292# $Id: minmax.test,v 1.9.2.2 2004/07/18 21:14:05 drh Exp $ 20*c5c4113dSnw141292 21*c5c4113dSnw141292set testdir [file dirname $argv0] 22*c5c4113dSnw141292source $testdir/tester.tcl 23*c5c4113dSnw141292 24*c5c4113dSnw141292do_test minmax-1.0 { 25*c5c4113dSnw141292 execsql { 26*c5c4113dSnw141292 BEGIN; 27*c5c4113dSnw141292 CREATE TABLE t1(x, y); 28*c5c4113dSnw141292 INSERT INTO t1 VALUES(1,1); 29*c5c4113dSnw141292 INSERT INTO t1 VALUES(2,2); 30*c5c4113dSnw141292 INSERT INTO t1 VALUES(3,2); 31*c5c4113dSnw141292 INSERT INTO t1 VALUES(4,3); 32*c5c4113dSnw141292 INSERT INTO t1 VALUES(5,3); 33*c5c4113dSnw141292 INSERT INTO t1 VALUES(6,3); 34*c5c4113dSnw141292 INSERT INTO t1 VALUES(7,3); 35*c5c4113dSnw141292 INSERT INTO t1 VALUES(8,4); 36*c5c4113dSnw141292 INSERT INTO t1 VALUES(9,4); 37*c5c4113dSnw141292 INSERT INTO t1 VALUES(10,4); 38*c5c4113dSnw141292 INSERT INTO t1 VALUES(11,4); 39*c5c4113dSnw141292 INSERT INTO t1 VALUES(12,4); 40*c5c4113dSnw141292 INSERT INTO t1 VALUES(13,4); 41*c5c4113dSnw141292 INSERT INTO t1 VALUES(14,4); 42*c5c4113dSnw141292 INSERT INTO t1 VALUES(15,4); 43*c5c4113dSnw141292 INSERT INTO t1 VALUES(16,5); 44*c5c4113dSnw141292 INSERT INTO t1 VALUES(17,5); 45*c5c4113dSnw141292 INSERT INTO t1 VALUES(18,5); 46*c5c4113dSnw141292 INSERT INTO t1 VALUES(19,5); 47*c5c4113dSnw141292 INSERT INTO t1 VALUES(20,5); 48*c5c4113dSnw141292 COMMIT; 49*c5c4113dSnw141292 SELECT DISTINCT y FROM t1 ORDER BY y; 50*c5c4113dSnw141292 } 51*c5c4113dSnw141292} {1 2 3 4 5} 52*c5c4113dSnw141292 53*c5c4113dSnw141292do_test minmax-1.1 { 54*c5c4113dSnw141292 set sqlite_search_count 0 55*c5c4113dSnw141292 execsql {SELECT min(x) FROM t1} 56*c5c4113dSnw141292} {1} 57*c5c4113dSnw141292do_test minmax-1.2 { 58*c5c4113dSnw141292 set sqlite_search_count 59*c5c4113dSnw141292} {19} 60*c5c4113dSnw141292do_test minmax-1.3 { 61*c5c4113dSnw141292 set sqlite_search_count 0 62*c5c4113dSnw141292 execsql {SELECT max(x) FROM t1} 63*c5c4113dSnw141292} {20} 64*c5c4113dSnw141292do_test minmax-1.4 { 65*c5c4113dSnw141292 set sqlite_search_count 66*c5c4113dSnw141292} {19} 67*c5c4113dSnw141292do_test minmax-1.5 { 68*c5c4113dSnw141292 execsql {CREATE INDEX t1i1 ON t1(x)} 69*c5c4113dSnw141292 set sqlite_search_count 0 70*c5c4113dSnw141292 execsql {SELECT min(x) FROM t1} 71*c5c4113dSnw141292} {1} 72*c5c4113dSnw141292do_test minmax-1.6 { 73*c5c4113dSnw141292 set sqlite_search_count 74*c5c4113dSnw141292} {2} 75*c5c4113dSnw141292do_test minmax-1.7 { 76*c5c4113dSnw141292 set sqlite_search_count 0 77*c5c4113dSnw141292 execsql {SELECT max(x) FROM t1} 78*c5c4113dSnw141292} {20} 79*c5c4113dSnw141292do_test minmax-1.8 { 80*c5c4113dSnw141292 set sqlite_search_count 81*c5c4113dSnw141292} {1} 82*c5c4113dSnw141292do_test minmax-1.9 { 83*c5c4113dSnw141292 set sqlite_search_count 0 84*c5c4113dSnw141292 execsql {SELECT max(y) FROM t1} 85*c5c4113dSnw141292} {5} 86*c5c4113dSnw141292do_test minmax-1.10 { 87*c5c4113dSnw141292 set sqlite_search_count 88*c5c4113dSnw141292} {19} 89*c5c4113dSnw141292 90*c5c4113dSnw141292do_test minmax-2.0 { 91*c5c4113dSnw141292 execsql { 92*c5c4113dSnw141292 CREATE TABLE t2(a INTEGER PRIMARY KEY, b); 93*c5c4113dSnw141292 INSERT INTO t2 SELECT * FROM t1; 94*c5c4113dSnw141292 } 95*c5c4113dSnw141292 set sqlite_search_count 0 96*c5c4113dSnw141292 execsql {SELECT min(a) FROM t2} 97*c5c4113dSnw141292} {1} 98*c5c4113dSnw141292do_test minmax-2.1 { 99*c5c4113dSnw141292 set sqlite_search_count 100*c5c4113dSnw141292} {0} 101*c5c4113dSnw141292do_test minmax-2.2 { 102*c5c4113dSnw141292 set sqlite_search_count 0 103*c5c4113dSnw141292 execsql {SELECT max(a) FROM t2} 104*c5c4113dSnw141292} {20} 105*c5c4113dSnw141292do_test minmax-2.3 { 106*c5c4113dSnw141292 set sqlite_search_count 107*c5c4113dSnw141292} {0} 108*c5c4113dSnw141292 109*c5c4113dSnw141292do_test minmax-3.0 { 110*c5c4113dSnw141292 execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 111*c5c4113dSnw141292 set sqlite_search_count 0 112*c5c4113dSnw141292 execsql {SELECT max(a) FROM t2} 113*c5c4113dSnw141292} {21} 114*c5c4113dSnw141292do_test minmax-3.1 { 115*c5c4113dSnw141292 set sqlite_search_count 116*c5c4113dSnw141292} {0} 117*c5c4113dSnw141292do_test minmax-3.2 { 118*c5c4113dSnw141292 execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 119*c5c4113dSnw141292 set sqlite_search_count 0 120*c5c4113dSnw141292 execsql { 121*c5c4113dSnw141292 SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) 122*c5c4113dSnw141292 } 123*c5c4113dSnw141292} {999} 124*c5c4113dSnw141292do_test minmax-3.3 { 125*c5c4113dSnw141292 set sqlite_search_count 126*c5c4113dSnw141292} {0} 127*c5c4113dSnw141292 128*c5c4113dSnw141292do_test minmax-4.1 { 129*c5c4113dSnw141292 execsql { 130*c5c4113dSnw141292 SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM 131*c5c4113dSnw141292 (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y') 132*c5c4113dSnw141292 } 133*c5c4113dSnw141292} {1 20} 134*c5c4113dSnw141292do_test minmax-4.2 { 135*c5c4113dSnw141292 execsql { 136*c5c4113dSnw141292 SELECT y, sum(x) FROM 137*c5c4113dSnw141292 (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1) 138*c5c4113dSnw141292 GROUP BY y ORDER BY y; 139*c5c4113dSnw141292 } 140*c5c4113dSnw141292} {1 1 2 5 3 22 4 92 5 90 6 0} 141*c5c4113dSnw141292do_test minmax-4.3 { 142*c5c4113dSnw141292 execsql { 143*c5c4113dSnw141292 SELECT y, count(x), count(*) FROM 144*c5c4113dSnw141292 (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1) 145*c5c4113dSnw141292 GROUP BY y ORDER BY y; 146*c5c4113dSnw141292 } 147*c5c4113dSnw141292} {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1} 148*c5c4113dSnw141292 149*c5c4113dSnw141292# Make sure the min(x) and max(x) optimizations work on empty tables 150*c5c4113dSnw141292# including empty tables with indices. Ticket #296. 151*c5c4113dSnw141292# 152*c5c4113dSnw141292do_test minmax-5.1 { 153*c5c4113dSnw141292 execsql { 154*c5c4113dSnw141292 CREATE TABLE t3(x INTEGER UNIQUE NOT NULL); 155*c5c4113dSnw141292 SELECT coalesce(min(x),999) FROM t3; 156*c5c4113dSnw141292 } 157*c5c4113dSnw141292} {999} 158*c5c4113dSnw141292do_test minmax-5.2 { 159*c5c4113dSnw141292 execsql { 160*c5c4113dSnw141292 SELECT coalesce(min(rowid),999) FROM t3; 161*c5c4113dSnw141292 } 162*c5c4113dSnw141292} {999} 163*c5c4113dSnw141292do_test minmax-5.3 { 164*c5c4113dSnw141292 execsql { 165*c5c4113dSnw141292 SELECT coalesce(max(x),999) FROM t3; 166*c5c4113dSnw141292 } 167*c5c4113dSnw141292} {999} 168*c5c4113dSnw141292do_test minmax-5.4 { 169*c5c4113dSnw141292 execsql { 170*c5c4113dSnw141292 SELECT coalesce(max(rowid),999) FROM t3; 171*c5c4113dSnw141292 } 172*c5c4113dSnw141292} {999} 173*c5c4113dSnw141292do_test minmax-5.5 { 174*c5c4113dSnw141292 execsql { 175*c5c4113dSnw141292 SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25; 176*c5c4113dSnw141292 } 177*c5c4113dSnw141292} {999} 178*c5c4113dSnw141292 179*c5c4113dSnw141292# Make sure the min(x) and max(x) optimizations work when there 180*c5c4113dSnw141292# is a LIMIT clause. Ticket #396. 181*c5c4113dSnw141292# 182*c5c4113dSnw141292do_test minmax-6.1 { 183*c5c4113dSnw141292 execsql { 184*c5c4113dSnw141292 SELECT min(a) FROM t2 LIMIT 1 185*c5c4113dSnw141292 } 186*c5c4113dSnw141292} {1} 187*c5c4113dSnw141292do_test minmax-6.2 { 188*c5c4113dSnw141292 execsql { 189*c5c4113dSnw141292 SELECT max(a) FROM t2 LIMIT 3 190*c5c4113dSnw141292 } 191*c5c4113dSnw141292} {22} 192*c5c4113dSnw141292do_test minmax-6.3 { 193*c5c4113dSnw141292 execsql { 194*c5c4113dSnw141292 SELECT min(a) FROM t2 LIMIT 0,100 195*c5c4113dSnw141292 } 196*c5c4113dSnw141292} {1} 197*c5c4113dSnw141292do_test minmax-6.4 { 198*c5c4113dSnw141292 execsql { 199*c5c4113dSnw141292 SELECT max(a) FROM t2 LIMIT 1,100 200*c5c4113dSnw141292 } 201*c5c4113dSnw141292} {} 202*c5c4113dSnw141292do_test minmax-6.5 { 203*c5c4113dSnw141292 execsql { 204*c5c4113dSnw141292 SELECT min(x) FROM t3 LIMIT 1 205*c5c4113dSnw141292 } 206*c5c4113dSnw141292} {{}} 207*c5c4113dSnw141292do_test minmax-6.6 { 208*c5c4113dSnw141292 execsql { 209*c5c4113dSnw141292 SELECT max(x) FROM t3 LIMIT 0 210*c5c4113dSnw141292 } 211*c5c4113dSnw141292} {} 212*c5c4113dSnw141292do_test minmax-6.7 { 213*c5c4113dSnw141292 execsql { 214*c5c4113dSnw141292 SELECT max(a) FROM t2 LIMIT 0 215*c5c4113dSnw141292 } 216*c5c4113dSnw141292} {} 217*c5c4113dSnw141292 218*c5c4113dSnw141292# Make sure the max(x) and min(x) optimizations work for nested 219*c5c4113dSnw141292# queries. Ticket #587. 220*c5c4113dSnw141292# 221*c5c4113dSnw141292do_test minmax-7.1 { 222*c5c4113dSnw141292 execsql { 223*c5c4113dSnw141292 SELECT max(x) FROM t1; 224*c5c4113dSnw141292 } 225*c5c4113dSnw141292} 20 226*c5c4113dSnw141292do_test minmax-7.2 { 227*c5c4113dSnw141292 execsql { 228*c5c4113dSnw141292 SELECT * FROM (SELECT max(x) FROM t1); 229*c5c4113dSnw141292 } 230*c5c4113dSnw141292} 20 231*c5c4113dSnw141292do_test minmax-7.3 { 232*c5c4113dSnw141292 execsql { 233*c5c4113dSnw141292 SELECT min(x) FROM t1; 234*c5c4113dSnw141292 } 235*c5c4113dSnw141292} 1 236*c5c4113dSnw141292do_test minmax-7.4 { 237*c5c4113dSnw141292 execsql { 238*c5c4113dSnw141292 SELECT * FROM (SELECT min(x) FROM t1); 239*c5c4113dSnw141292 } 240*c5c4113dSnw141292} 1 241*c5c4113dSnw141292 242*c5c4113dSnw141292# Make sure min(x) and max(x) work correctly when the datatype is 243*c5c4113dSnw141292# TEXT instead of NUMERIC. Ticket #623. 244*c5c4113dSnw141292# 245*c5c4113dSnw141292do_test minmax-8.1 { 246*c5c4113dSnw141292 execsql { 247*c5c4113dSnw141292 CREATE TABLE t4(a TEXT); 248*c5c4113dSnw141292 INSERT INTO t4 VALUES('1234'); 249*c5c4113dSnw141292 INSERT INTO t4 VALUES('234'); 250*c5c4113dSnw141292 INSERT INTO t4 VALUES('34'); 251*c5c4113dSnw141292 SELECT min(a), max(a) FROM t4; 252*c5c4113dSnw141292 } 253*c5c4113dSnw141292} {1234 34} 254*c5c4113dSnw141292do_test minmax-8.2 { 255*c5c4113dSnw141292 execsql { 256*c5c4113dSnw141292 CREATE TABLE t5(a INTEGER); 257*c5c4113dSnw141292 INSERT INTO t5 VALUES('1234'); 258*c5c4113dSnw141292 INSERT INTO t5 VALUES('234'); 259*c5c4113dSnw141292 INSERT INTO t5 VALUES('34'); 260*c5c4113dSnw141292 SELECT min(a), max(a) FROM t5; 261*c5c4113dSnw141292 } 262*c5c4113dSnw141292} {34 1234} 263*c5c4113dSnw141292 264*c5c4113dSnw141292# Ticket #658: Test the min()/max() optimization when the FROM clause 265*c5c4113dSnw141292# is a subquery. 266*c5c4113dSnw141292# 267*c5c4113dSnw141292do_test minmax-9.1 { 268*c5c4113dSnw141292 execsql { 269*c5c4113dSnw141292 SELECT max(rowid) FROM ( 270*c5c4113dSnw141292 SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 271*c5c4113dSnw141292 ) 272*c5c4113dSnw141292 } 273*c5c4113dSnw141292} {1} 274*c5c4113dSnw141292do_test minmax-9.2 { 275*c5c4113dSnw141292 execsql { 276*c5c4113dSnw141292 SELECT max(rowid) FROM ( 277*c5c4113dSnw141292 SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5 278*c5c4113dSnw141292 ) 279*c5c4113dSnw141292 } 280*c5c4113dSnw141292} {{}} 281*c5c4113dSnw141292 282*c5c4113dSnw141292# If there is a NULL in an aggregate max() or min(), ignore it. An 283*c5c4113dSnw141292# aggregate min() or max() will only return NULL if all values are NULL. 284*c5c4113dSnw141292# 285*c5c4113dSnw141292do_test minmax-10.1 { 286*c5c4113dSnw141292 execsql { 287*c5c4113dSnw141292 CREATE TABLE t6(x); 288*c5c4113dSnw141292 INSERT INTO t6 VALUES(1); 289*c5c4113dSnw141292 INSERT INTO t6 VALUES(2); 290*c5c4113dSnw141292 INSERT INTO t6 VALUES(NULL); 291*c5c4113dSnw141292 SELECT coalesce(min(x),-1) FROM t6; 292*c5c4113dSnw141292 } 293*c5c4113dSnw141292} {1} 294*c5c4113dSnw141292do_test minmax-10.2 { 295*c5c4113dSnw141292 execsql { 296*c5c4113dSnw141292 SELECT max(x) FROM t6; 297*c5c4113dSnw141292 } 298*c5c4113dSnw141292} {2} 299*c5c4113dSnw141292do_test minmax-10.3 { 300*c5c4113dSnw141292 execsql { 301*c5c4113dSnw141292 CREATE INDEX i6 ON t6(x); 302*c5c4113dSnw141292 SELECT coalesce(min(x),-1) FROM t6; 303*c5c4113dSnw141292 } 304*c5c4113dSnw141292} {1} 305*c5c4113dSnw141292do_test minmax-10.4 { 306*c5c4113dSnw141292 execsql { 307*c5c4113dSnw141292 SELECT max(x) FROM t6; 308*c5c4113dSnw141292 } 309*c5c4113dSnw141292} {2} 310*c5c4113dSnw141292do_test minmax-10.5 { 311*c5c4113dSnw141292 execsql { 312*c5c4113dSnw141292 DELETE FROM t6 WHERE x NOT NULL; 313*c5c4113dSnw141292 SELECT count(*) FROM t6; 314*c5c4113dSnw141292 } 315*c5c4113dSnw141292} 1 316*c5c4113dSnw141292do_test minmax-10.6 { 317*c5c4113dSnw141292 execsql { 318*c5c4113dSnw141292 SELECT count(x) FROM t6; 319*c5c4113dSnw141292 } 320*c5c4113dSnw141292} 0 321*c5c4113dSnw141292do_test minmax-10.7 { 322*c5c4113dSnw141292 execsql { 323*c5c4113dSnw141292 SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 324*c5c4113dSnw141292 } 325*c5c4113dSnw141292} {{} {}} 326*c5c4113dSnw141292do_test minmax-10.8 { 327*c5c4113dSnw141292 execsql { 328*c5c4113dSnw141292 SELECT min(x), max(x) FROM t6; 329*c5c4113dSnw141292 } 330*c5c4113dSnw141292} {{} {}} 331*c5c4113dSnw141292do_test minmax-10.9 { 332*c5c4113dSnw141292 execsql { 333*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 334*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 335*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 336*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 337*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 338*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 339*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 340*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 341*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 342*c5c4113dSnw141292 INSERT INTO t6 SELECT * FROM t6; 343*c5c4113dSnw141292 SELECT count(*) FROM t6; 344*c5c4113dSnw141292 } 345*c5c4113dSnw141292} 1024 346*c5c4113dSnw141292do_test minmax-10.10 { 347*c5c4113dSnw141292 execsql { 348*c5c4113dSnw141292 SELECT count(x) FROM t6; 349*c5c4113dSnw141292 } 350*c5c4113dSnw141292} 0 351*c5c4113dSnw141292do_test minmax-10.11 { 352*c5c4113dSnw141292 execsql { 353*c5c4113dSnw141292 SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 354*c5c4113dSnw141292 } 355*c5c4113dSnw141292} {{} {}} 356*c5c4113dSnw141292do_test minmax-10.12 { 357*c5c4113dSnw141292 execsql { 358*c5c4113dSnw141292 SELECT min(x), max(x) FROM t6; 359*c5c4113dSnw141292 } 360*c5c4113dSnw141292} {{} {}} 361*c5c4113dSnw141292 362*c5c4113dSnw141292finish_test 363