github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/minmax2.test (about) 1 # 2007 July 17 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 SELECT statements that contain 13 # aggregate min() and max() functions and which are handled as 14 # as a special case. This file makes sure that the min/max 15 # optimization works right in the presence of descending 16 # indices. Ticket #2514. 17 # 18 # $Id: minmax2.test,v 1.2 2008/01/05 17:39:30 danielk1977 Exp $ 19 20 set testdir [file dirname $argv0] 21 source $testdir/tester.tcl 22 23 do_test minmax2-1.0 { 24 sqlite3_db_config db LEGACY_FILE_FORMAT 0 25 execsql { 26 BEGIN; 27 CREATE TABLE t1(x, y); 28 INSERT INTO t1 VALUES(1,1); 29 INSERT INTO t1 VALUES(2,2); 30 INSERT INTO t1 VALUES(3,2); 31 INSERT INTO t1 VALUES(4,3); 32 INSERT INTO t1 VALUES(5,3); 33 INSERT INTO t1 VALUES(6,3); 34 INSERT INTO t1 VALUES(7,3); 35 INSERT INTO t1 VALUES(8,4); 36 INSERT INTO t1 VALUES(9,4); 37 INSERT INTO t1 VALUES(10,4); 38 INSERT INTO t1 VALUES(11,4); 39 INSERT INTO t1 VALUES(12,4); 40 INSERT INTO t1 VALUES(13,4); 41 INSERT INTO t1 VALUES(14,4); 42 INSERT INTO t1 VALUES(15,4); 43 INSERT INTO t1 VALUES(16,5); 44 INSERT INTO t1 VALUES(17,5); 45 INSERT INTO t1 VALUES(18,5); 46 INSERT INTO t1 VALUES(19,5); 47 INSERT INTO t1 VALUES(20,5); 48 COMMIT; 49 SELECT DISTINCT y FROM t1 ORDER BY y; 50 } 51 } {1 2 3 4 5} 52 53 do_test minmax2-1.1 { 54 set sqlite_search_count 0 55 execsql {SELECT min(x) FROM t1} 56 } {1} 57 do_test minmax2-1.2 { 58 set sqlite_search_count 59 } {19} 60 do_test minmax2-1.3 { 61 set sqlite_search_count 0 62 execsql {SELECT max(x) FROM t1} 63 } {20} 64 do_test minmax2-1.4 { 65 set sqlite_search_count 66 } {19} 67 do_test minmax2-1.5 { 68 execsql {CREATE INDEX t1i1 ON t1(x DESC)} 69 set sqlite_search_count 0 70 execsql {SELECT min(x) FROM t1} 71 } {1} 72 do_test minmax2-1.6 { 73 set sqlite_search_count 74 } {1} 75 do_test minmax2-1.7 { 76 set sqlite_search_count 0 77 execsql {SELECT max(x) FROM t1} 78 } {20} 79 do_test minmax2-1.8 { 80 set sqlite_search_count 81 } {0} 82 do_test minmax2-1.9 { 83 set sqlite_search_count 0 84 execsql {SELECT max(y) FROM t1} 85 } {5} 86 do_test minmax2-1.10 { 87 set sqlite_search_count 88 } {19} 89 90 do_test minmax2-2.0 { 91 execsql { 92 CREATE TABLE t2(a INTEGER PRIMARY KEY, b); 93 INSERT INTO t2 SELECT * FROM t1; 94 } 95 set sqlite_search_count 0 96 execsql {SELECT min(a) FROM t2} 97 } {1} 98 do_test minmax2-2.1 { 99 set sqlite_search_count 100 } {0} 101 do_test minmax2-2.2 { 102 set sqlite_search_count 0 103 execsql {SELECT max(a) FROM t2} 104 } {20} 105 do_test minmax2-2.3 { 106 set sqlite_search_count 107 } {0} 108 109 do_test minmax2-3.0 { 110 ifcapable subquery { 111 execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 112 } else { 113 db function max_a_t2 {execsql {SELECT max(a) FROM t2}} 114 execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} 115 } 116 set sqlite_search_count 0 117 execsql {SELECT max(a) FROM t2} 118 } {21} 119 do_test minmax2-3.1 { 120 set sqlite_search_count 121 } {0} 122 do_test minmax2-3.2 { 123 ifcapable subquery { 124 execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)} 125 } else { 126 db function max_a_t2 {execsql {SELECT max(a) FROM t2}} 127 execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)} 128 } 129 set sqlite_search_count 0 130 ifcapable subquery { 131 execsql { SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) } 132 } else { 133 execsql { SELECT b FROM t2 WHERE a=max_a_t2() } 134 } 135 } {999} 136 do_test minmax2-3.3 { 137 set sqlite_search_count 138 } {0} 139 140 ifcapable {compound && subquery} { 141 do_test minmax2-4.1 { 142 execsql { 143 SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM 144 (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y') 145 } 146 } {1 20} 147 do_test minmax2-4.2 { 148 execsql { 149 SELECT y, coalesce(sum(x),0) FROM 150 (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1) 151 GROUP BY y ORDER BY y; 152 } 153 } {1 1 2 5 3 22 4 92 5 90 6 0} 154 do_test minmax2-4.3 { 155 execsql { 156 SELECT y, count(x), count(*) FROM 157 (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1) 158 GROUP BY y ORDER BY y; 159 } 160 } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1} 161 } ;# ifcapable compound 162 163 # Make sure the min(x) and max(x) optimizations work on empty tables 164 # including empty tables with indices. Ticket #296. 165 # 166 do_test minmax2-5.1 { 167 execsql { 168 CREATE TABLE t3(x INTEGER UNIQUE NOT NULL); 169 SELECT coalesce(min(x),999) FROM t3; 170 } 171 } {999} 172 do_test minmax2-5.2 { 173 execsql { 174 SELECT coalesce(min(rowid),999) FROM t3; 175 } 176 } {999} 177 do_test minmax2-5.3 { 178 execsql { 179 SELECT coalesce(max(x),999) FROM t3; 180 } 181 } {999} 182 do_test minmax2-5.4 { 183 execsql { 184 SELECT coalesce(max(rowid),999) FROM t3; 185 } 186 } {999} 187 do_test minmax2-5.5 { 188 execsql { 189 SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25; 190 } 191 } {999} 192 193 # Make sure the min(x) and max(x) optimizations work when there 194 # is a LIMIT clause. Ticket #396. 195 # 196 do_test minmax2-6.1 { 197 execsql { 198 SELECT min(a) FROM t2 LIMIT 1 199 } 200 } {1} 201 do_test minmax2-6.2 { 202 execsql { 203 SELECT max(a) FROM t2 LIMIT 3 204 } 205 } {22} 206 do_test minmax2-6.3 { 207 execsql { 208 SELECT min(a) FROM t2 LIMIT 0,100 209 } 210 } {1} 211 do_test minmax2-6.4 { 212 execsql { 213 SELECT max(a) FROM t2 LIMIT 1,100 214 } 215 } {} 216 do_test minmax2-6.5 { 217 execsql { 218 SELECT min(x) FROM t3 LIMIT 1 219 } 220 } {{}} 221 do_test minmax2-6.6 { 222 execsql { 223 SELECT max(x) FROM t3 LIMIT 0 224 } 225 } {} 226 do_test minmax2-6.7 { 227 execsql { 228 SELECT max(a) FROM t2 LIMIT 0 229 } 230 } {} 231 232 # Make sure the max(x) and min(x) optimizations work for nested 233 # queries. Ticket #587. 234 # 235 do_test minmax2-7.1 { 236 execsql { 237 SELECT max(x) FROM t1; 238 } 239 } 20 240 ifcapable subquery { 241 do_test minmax2-7.2 { 242 execsql { 243 SELECT * FROM (SELECT max(x) FROM t1); 244 } 245 } 20 246 } 247 do_test minmax2-7.3 { 248 execsql { 249 SELECT min(x) FROM t1; 250 } 251 } 1 252 ifcapable subquery { 253 do_test minmax2-7.4 { 254 execsql { 255 SELECT * FROM (SELECT min(x) FROM t1); 256 } 257 } 1 258 } 259 260 # Make sure min(x) and max(x) work correctly when the datatype is 261 # TEXT instead of NUMERIC. Ticket #623. 262 # 263 do_test minmax2-8.1 { 264 execsql { 265 CREATE TABLE t4(a TEXT); 266 INSERT INTO t4 VALUES('1234'); 267 INSERT INTO t4 VALUES('234'); 268 INSERT INTO t4 VALUES('34'); 269 SELECT min(a), max(a) FROM t4; 270 } 271 } {1234 34} 272 do_test minmax2-8.2 { 273 execsql { 274 CREATE TABLE t5(a INTEGER); 275 INSERT INTO t5 VALUES('1234'); 276 INSERT INTO t5 VALUES('234'); 277 INSERT INTO t5 VALUES('34'); 278 SELECT min(a), max(a) FROM t5; 279 } 280 } {34 1234} 281 282 # Ticket #658: Test the min()/max() optimization when the FROM clause 283 # is a subquery. 284 # 285 ifcapable {compound && subquery} { 286 do_test minmax2-9.0 { 287 execsql { 288 SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 289 } 290 } {3} 291 do_test minmax2-9.1 { 292 execsql { 293 SELECT max(yy) FROM ( 294 SELECT max(rowid) AS yy FROM t4 UNION SELECT max(rowid) FROM t5 295 ) 296 } 297 } {3} 298 do_test minmax2-9.2 { 299 execsql { 300 SELECT max(yy) FROM ( 301 SELECT max(rowid) AS yy FROM t4 EXCEPT SELECT max(rowid) FROM t5 302 ) 303 } 304 } {{}} 305 } ;# ifcapable compound&&subquery 306 307 # If there is a NULL in an aggregate max() or min(), ignore it. An 308 # aggregate min() or max() will only return NULL if all values are NULL. 309 # 310 do_test minmax2-10.1 { 311 execsql { 312 CREATE TABLE t6(x); 313 INSERT INTO t6 VALUES(1); 314 INSERT INTO t6 VALUES(2); 315 INSERT INTO t6 VALUES(NULL); 316 SELECT coalesce(min(x),-1) FROM t6; 317 } 318 } {1} 319 do_test minmax2-10.2 { 320 execsql { 321 SELECT max(x) FROM t6; 322 } 323 } {2} 324 do_test minmax2-10.3 { 325 execsql { 326 CREATE INDEX i6 ON t6(x DESC); 327 SELECT coalesce(min(x),-1) FROM t6; 328 } 329 } {1} 330 do_test minmax2-10.4 { 331 execsql { 332 SELECT max(x) FROM t6; 333 } 334 } {2} 335 do_test minmax2-10.5 { 336 execsql { 337 DELETE FROM t6 WHERE x NOT NULL; 338 SELECT count(*) FROM t6; 339 } 340 } 1 341 do_test minmax2-10.6 { 342 execsql { 343 SELECT count(x) FROM t6; 344 } 345 } 0 346 ifcapable subquery { 347 do_test minmax2-10.7 { 348 execsql { 349 SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 350 } 351 } {{} {}} 352 } 353 do_test minmax2-10.8 { 354 execsql { 355 SELECT min(x), max(x) FROM t6; 356 } 357 } {{} {}} 358 do_test minmax2-10.9 { 359 execsql { 360 INSERT INTO t6 SELECT * FROM t6; 361 INSERT INTO t6 SELECT * FROM t6; 362 INSERT INTO t6 SELECT * FROM t6; 363 INSERT INTO t6 SELECT * FROM t6; 364 INSERT INTO t6 SELECT * FROM t6; 365 INSERT INTO t6 SELECT * FROM t6; 366 INSERT INTO t6 SELECT * FROM t6; 367 INSERT INTO t6 SELECT * FROM t6; 368 INSERT INTO t6 SELECT * FROM t6; 369 INSERT INTO t6 SELECT * FROM t6; 370 SELECT count(*) FROM t6; 371 } 372 } 1024 373 do_test minmax2-10.10 { 374 execsql { 375 SELECT count(x) FROM t6; 376 } 377 } 0 378 ifcapable subquery { 379 do_test minmax2-10.11 { 380 execsql { 381 SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6); 382 } 383 } {{} {}} 384 } 385 do_test minmax2-10.12 { 386 execsql { 387 SELECT min(x), max(x) FROM t6; 388 } 389 } {{} {}} 390 391 # 2017-10-26. Extend the min/max optimization to indexes on expressions 392 # 393 do_execsql_test minmax2-11.100 { 394 CREATE TABLE t11(a,b,c); 395 INSERT INTO t11(a,b,c) VALUES(1,10,5),(2,8,11),(3,1,4),(4,20,1),(5,16,4); 396 CREATE INDEX t11bc ON t11(b+c); 397 SELECT max(b+c) FROM t11; 398 } {21} 399 do_execsql_test minmax2-11.110 { 400 SELECT a, max(b+c) FROM t11; 401 } {4 21} 402 do_test minmax2-11.111 { 403 db eval {SELECT max(b+c) FROM t11} 404 db status step 405 } {0} 406 do_test minmax2-11.112 { 407 db eval {SELECT max(c+b) FROM t11} 408 db status step 409 } {4} 410 do_execsql_test minmax2-11.120 { 411 SELECT a, min(b+c) FROM t11; 412 } {3 5} 413 do_test minmax2-11.121 { 414 db eval {SELECT min(b+c) FROM t11} 415 db status step 416 } {0} 417 do_test minmax2-11.122 { 418 db eval {SELECT min(c+b) FROM t11} 419 db status step 420 } {4} 421 do_execsql_test minmax2-11.130 { 422 INSERT INTO t11(a,b,c) VALUES(6,NULL,0),(7,0,NULL); 423 SELECT a, min(b+c) FROM t11; 424 } {3 5} 425 426 finish_test