minmax.test 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. # 2001 September 15
  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.
  15. #
  16. # $Id: minmax.test,v 1.21 2008/07/08 18:05:26 drh Exp $
  17. set testdir [file dirname $argv0]
  18. source $testdir/tester.tcl
  19. set ::testprefix minmax
  20. do_test minmax-1.0 {
  21. execsql {
  22. BEGIN;
  23. CREATE TABLE t1(x, y);
  24. INSERT INTO t1 VALUES(1,1);
  25. INSERT INTO t1 VALUES(2,2);
  26. INSERT INTO t1 VALUES(3,2);
  27. INSERT INTO t1 VALUES(4,3);
  28. INSERT INTO t1 VALUES(5,3);
  29. INSERT INTO t1 VALUES(6,3);
  30. INSERT INTO t1 VALUES(7,3);
  31. INSERT INTO t1 VALUES(8,4);
  32. INSERT INTO t1 VALUES(9,4);
  33. INSERT INTO t1 VALUES(10,4);
  34. INSERT INTO t1 VALUES(11,4);
  35. INSERT INTO t1 VALUES(12,4);
  36. INSERT INTO t1 VALUES(13,4);
  37. INSERT INTO t1 VALUES(14,4);
  38. INSERT INTO t1 VALUES(15,4);
  39. INSERT INTO t1 VALUES(16,5);
  40. INSERT INTO t1 VALUES(17,5);
  41. INSERT INTO t1 VALUES(18,5);
  42. INSERT INTO t1 VALUES(19,5);
  43. INSERT INTO t1 VALUES(20,5);
  44. COMMIT;
  45. SELECT DISTINCT y FROM t1 ORDER BY y;
  46. }
  47. } {1 2 3 4 5}
  48. do_test minmax-1.1 {
  49. set sqlite_search_count 0
  50. execsql {SELECT min(x) FROM t1}
  51. } {1}
  52. do_test minmax-1.2 {
  53. set sqlite_search_count
  54. } {19}
  55. do_test minmax-1.3 {
  56. set sqlite_search_count 0
  57. execsql {SELECT max(x) FROM t1}
  58. } {20}
  59. do_test minmax-1.4 {
  60. set sqlite_search_count
  61. } {19}
  62. do_test minmax-1.5 {
  63. execsql {CREATE INDEX t1i1 ON t1(x)}
  64. set sqlite_search_count 0
  65. execsql {SELECT min(x) FROM t1}
  66. } {1}
  67. do_test minmax-1.6 {
  68. set sqlite_search_count
  69. } {1}
  70. do_test minmax-1.7 {
  71. set sqlite_search_count 0
  72. execsql {SELECT max(x) FROM t1}
  73. } {20}
  74. do_test minmax-1.8 {
  75. set sqlite_search_count
  76. } {0}
  77. do_test minmax-1.9 {
  78. set sqlite_search_count 0
  79. execsql {SELECT max(y) FROM t1}
  80. } {5}
  81. do_test minmax-1.10 {
  82. set sqlite_search_count
  83. } {19}
  84. do_test minmax-1.21 {
  85. execsql {SELECT min(x) FROM t1 WHERE x=5}
  86. } {5}
  87. do_test minmax-1.22 {
  88. execsql {SELECT min(x) FROM t1 WHERE x>=5}
  89. } {5}
  90. do_test minmax-1.23 {
  91. execsql {SELECT min(x) FROM t1 WHERE x>=4.5}
  92. } {5}
  93. do_test minmax-1.24 {
  94. execsql {SELECT min(x) FROM t1 WHERE x<4.5}
  95. } {1}
  96. do_test minmax-2.0 {
  97. execsql {
  98. CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
  99. INSERT INTO t2 SELECT * FROM t1;
  100. }
  101. set sqlite_search_count 0
  102. execsql {SELECT min(a) FROM t2}
  103. } {1}
  104. do_test minmax-2.1 {
  105. set sqlite_search_count
  106. } {0}
  107. do_test minmax-2.2 {
  108. set sqlite_search_count 0
  109. execsql {SELECT max(a) FROM t2}
  110. } {20}
  111. do_test minmax-2.3 {
  112. set sqlite_search_count
  113. } {0}
  114. do_test minmax-3.0 {
  115. ifcapable subquery {
  116. execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
  117. } else {
  118. db function max_a_t2 {execsql {SELECT max(a) FROM t2}}
  119. execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)}
  120. }
  121. set sqlite_search_count 0
  122. execsql {SELECT max(a) FROM t2}
  123. } {21}
  124. do_test minmax-3.1 {
  125. set sqlite_search_count
  126. } {0}
  127. do_test minmax-3.2 {
  128. ifcapable subquery {
  129. execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
  130. } else {
  131. db function max_a_t2 {execsql {SELECT max(a) FROM t2}}
  132. execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)}
  133. }
  134. set sqlite_search_count 0
  135. ifcapable subquery {
  136. execsql { SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) }
  137. } else {
  138. execsql { SELECT b FROM t2 WHERE a=max_a_t2() }
  139. }
  140. } {999}
  141. do_test minmax-3.3 {
  142. set sqlite_search_count
  143. } {0}
  144. ifcapable {compound && subquery} {
  145. do_test minmax-4.1 {
  146. execsql {
  147. SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM
  148. (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y')
  149. }
  150. } {1 20}
  151. do_test minmax-4.2 {
  152. execsql {
  153. SELECT y, coalesce(sum(x),0) FROM
  154. (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1)
  155. GROUP BY y ORDER BY y;
  156. }
  157. } {1 1 2 5 3 22 4 92 5 90 6 0}
  158. do_test minmax-4.3 {
  159. execsql {
  160. SELECT y, count(x), count(*) FROM
  161. (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1)
  162. GROUP BY y ORDER BY y;
  163. }
  164. } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1}
  165. } ;# ifcapable compound
  166. # Make sure the min(x) and max(x) optimizations work on empty tables
  167. # including empty tables with indices. Ticket #296.
  168. #
  169. do_test minmax-5.1 {
  170. execsql {
  171. CREATE TABLE t3(x INTEGER UNIQUE NOT NULL);
  172. SELECT coalesce(min(x),999) FROM t3;
  173. }
  174. } {999}
  175. do_test minmax-5.2 {
  176. execsql {
  177. SELECT coalesce(min(rowid),999) FROM t3;
  178. }
  179. } {999}
  180. do_test minmax-5.3 {
  181. execsql {
  182. SELECT coalesce(max(x),999) FROM t3;
  183. }
  184. } {999}
  185. do_test minmax-5.4 {
  186. execsql {
  187. SELECT coalesce(max(rowid),999) FROM t3;
  188. }
  189. } {999}
  190. do_test minmax-5.5 {
  191. execsql {
  192. SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25;
  193. }
  194. } {999}
  195. # Make sure the min(x) and max(x) optimizations work when there
  196. # is a LIMIT clause. Ticket #396.
  197. #
  198. do_test minmax-6.1 {
  199. execsql {
  200. SELECT min(a) FROM t2 LIMIT 1
  201. }
  202. } {1}
  203. do_test minmax-6.2 {
  204. execsql {
  205. SELECT max(a) FROM t2 LIMIT 3
  206. }
  207. } {22}
  208. do_test minmax-6.3 {
  209. execsql {
  210. SELECT min(a) FROM t2 LIMIT 0,100
  211. }
  212. } {1}
  213. do_test minmax-6.4 {
  214. execsql {
  215. SELECT max(a) FROM t2 LIMIT 1,100
  216. }
  217. } {}
  218. do_test minmax-6.5 {
  219. execsql {
  220. SELECT min(x) FROM t3 LIMIT 1
  221. }
  222. } {{}}
  223. do_test minmax-6.6 {
  224. execsql {
  225. SELECT max(x) FROM t3 LIMIT 0
  226. }
  227. } {}
  228. do_test minmax-6.7 {
  229. execsql {
  230. SELECT max(a) FROM t2 LIMIT 0
  231. }
  232. } {}
  233. # Make sure the max(x) and min(x) optimizations work for nested
  234. # queries. Ticket #587.
  235. #
  236. do_test minmax-7.1 {
  237. execsql {
  238. SELECT max(x) FROM t1;
  239. }
  240. } 20
  241. ifcapable subquery {
  242. do_test minmax-7.2 {
  243. execsql {
  244. SELECT * FROM (SELECT max(x) FROM t1);
  245. }
  246. } 20
  247. }
  248. do_test minmax-7.3 {
  249. execsql {
  250. SELECT min(x) FROM t1;
  251. }
  252. } 1
  253. ifcapable subquery {
  254. do_test minmax-7.4 {
  255. execsql {
  256. SELECT * FROM (SELECT min(x) FROM t1);
  257. }
  258. } 1
  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 minmax-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 minmax-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. # Ticket #658: Test the min()/max() optimization when the FROM clause
  282. # is a subquery.
  283. #
  284. ifcapable {compound && subquery} {
  285. do_test minmax-9.1 {
  286. execsql {
  287. SELECT max(rowid) FROM (
  288. SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5
  289. )
  290. }
  291. } {{}}
  292. do_test minmax-9.2 {
  293. execsql {
  294. SELECT max(rowid) FROM (
  295. SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5
  296. )
  297. }
  298. } {{}}
  299. } ;# ifcapable compound&&subquery
  300. # If there is a NULL in an aggregate max() or min(), ignore it. An
  301. # aggregate min() or max() will only return NULL if all values are NULL.
  302. #
  303. do_test minmax-10.1 {
  304. execsql {
  305. CREATE TABLE t6(x);
  306. INSERT INTO t6 VALUES(1);
  307. INSERT INTO t6 VALUES(2);
  308. INSERT INTO t6 VALUES(NULL);
  309. SELECT coalesce(min(x),-1) FROM t6;
  310. }
  311. } {1}
  312. do_test minmax-10.2 {
  313. execsql {
  314. SELECT max(x) FROM t6;
  315. }
  316. } {2}
  317. do_test minmax-10.3 {
  318. execsql {
  319. CREATE INDEX i6 ON t6(x);
  320. SELECT coalesce(min(x),-1) FROM t6;
  321. }
  322. } {1}
  323. do_test minmax-10.4 {
  324. execsql {
  325. SELECT max(x) FROM t6;
  326. }
  327. } {2}
  328. do_test minmax-10.5 {
  329. execsql {
  330. DELETE FROM t6 WHERE x NOT NULL;
  331. SELECT count(*) FROM t6;
  332. }
  333. } 1
  334. do_test minmax-10.6 {
  335. execsql {
  336. SELECT count(x) FROM t6;
  337. }
  338. } 0
  339. ifcapable subquery {
  340. do_test minmax-10.7 {
  341. execsql {
  342. SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
  343. }
  344. } {{} {}}
  345. }
  346. do_test minmax-10.8 {
  347. execsql {
  348. SELECT min(x), max(x) FROM t6;
  349. }
  350. } {{} {}}
  351. do_test minmax-10.9 {
  352. execsql {
  353. INSERT INTO t6 SELECT * FROM t6;
  354. INSERT INTO t6 SELECT * FROM t6;
  355. INSERT INTO t6 SELECT * FROM t6;
  356. INSERT INTO t6 SELECT * FROM t6;
  357. INSERT INTO t6 SELECT * FROM t6;
  358. INSERT INTO t6 SELECT * FROM t6;
  359. INSERT INTO t6 SELECT * FROM t6;
  360. INSERT INTO t6 SELECT * FROM t6;
  361. INSERT INTO t6 SELECT * FROM t6;
  362. INSERT INTO t6 SELECT * FROM t6;
  363. SELECT count(*) FROM t6;
  364. }
  365. } 1024
  366. do_test minmax-10.10 {
  367. execsql {
  368. SELECT count(x) FROM t6;
  369. }
  370. } 0
  371. ifcapable subquery {
  372. do_test minmax-10.11 {
  373. execsql {
  374. SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
  375. }
  376. } {{} {}}
  377. }
  378. do_test minmax-10.12 {
  379. execsql {
  380. SELECT min(x), max(x) FROM t6;
  381. }
  382. } {{} {}}
  383. do_test minmax-11.1 {
  384. execsql {
  385. CREATE INDEX t1i2 ON t1(y,x);
  386. SELECT min(x) FROM t1 WHERE y=5;
  387. }
  388. } {16}
  389. do_test minmax-11.2 {
  390. execsql {
  391. SELECT max(x) FROM t1 WHERE y=5;
  392. }
  393. } {20}
  394. do_test minmax-11.3 {
  395. execsql {
  396. SELECT min(x) FROM t1 WHERE y=6;
  397. }
  398. } {{}}
  399. do_test minmax-11.4 {
  400. execsql {
  401. SELECT max(x) FROM t1 WHERE y=6;
  402. }
  403. } {{}}
  404. do_test minmax-11.5 {
  405. execsql {
  406. SELECT min(x) FROM t1 WHERE y=1;
  407. }
  408. } {1}
  409. do_test minmax-11.6 {
  410. execsql {
  411. SELECT max(x) FROM t1 WHERE y=1;
  412. }
  413. } {1}
  414. do_test minmax-11.7 {
  415. execsql {
  416. SELECT min(x) FROM t1 WHERE y=0;
  417. }
  418. } {{}}
  419. do_test minmax-11.8 {
  420. execsql {
  421. SELECT max(x) FROM t1 WHERE y=0;
  422. }
  423. } {{}}
  424. do_test minmax-11.9 {
  425. execsql {
  426. SELECT min(x) FROM t1 WHERE y=5 AND x>=17.5;
  427. }
  428. } {18}
  429. do_test minmax-11.10 {
  430. execsql {
  431. SELECT max(x) FROM t1 WHERE y=5 AND x>=17.5;
  432. }
  433. } {20}
  434. do_test minmax-12.1 {
  435. execsql {
  436. CREATE TABLE t7(a,b,c);
  437. INSERT INTO t7 SELECT y, x, x*y FROM t1;
  438. INSERT INTO t7 SELECT y, x, x*y+1000 FROM t1;
  439. CREATE INDEX t7i1 ON t7(a,b,c);
  440. SELECT min(a) FROM t7;
  441. }
  442. } {1}
  443. do_test minmax-12.2 {
  444. execsql {
  445. SELECT max(a) FROM t7;
  446. }
  447. } {5}
  448. do_test minmax-12.3 {
  449. execsql {
  450. SELECT max(a) FROM t7 WHERE a=5;
  451. }
  452. } {5}
  453. do_test minmax-12.4 {
  454. execsql {
  455. SELECT min(b) FROM t7 WHERE a=5;
  456. }
  457. } {16}
  458. do_test minmax-12.5 {
  459. execsql {
  460. SELECT max(b) FROM t7 WHERE a=5;
  461. }
  462. } {20}
  463. do_test minmax-12.6 {
  464. execsql {
  465. SELECT min(b) FROM t7 WHERE a=4;
  466. }
  467. } {8}
  468. do_test minmax-12.7 {
  469. execsql {
  470. SELECT max(b) FROM t7 WHERE a=4;
  471. }
  472. } {15}
  473. do_test minmax-12.8 {
  474. execsql {
  475. SELECT min(c) FROM t7 WHERE a=4 AND b=10;
  476. }
  477. } {40}
  478. do_test minmax-12.9 {
  479. execsql {
  480. SELECT max(c) FROM t7 WHERE a=4 AND b=10;
  481. }
  482. } {1040}
  483. do_test minmax-12.10 {
  484. execsql {
  485. SELECT min(rowid) FROM t7;
  486. }
  487. } {1}
  488. do_test minmax-12.11 {
  489. execsql {
  490. SELECT max(rowid) FROM t7;
  491. }
  492. } {40}
  493. do_test minmax-12.12 {
  494. execsql {
  495. SELECT min(rowid) FROM t7 WHERE a=3;
  496. }
  497. } {4}
  498. do_test minmax-12.13 {
  499. execsql {
  500. SELECT max(rowid) FROM t7 WHERE a=3;
  501. }
  502. } {27}
  503. do_test minmax-12.14 {
  504. execsql {
  505. SELECT min(rowid) FROM t7 WHERE a=3 AND b=5;
  506. }
  507. } {5}
  508. do_test minmax-12.15 {
  509. execsql {
  510. SELECT max(rowid) FROM t7 WHERE a=3 AND b=5;
  511. }
  512. } {25}
  513. do_test minmax-12.16 {
  514. execsql {
  515. SELECT min(rowid) FROM t7 WHERE a=3 AND b=5 AND c=1015;
  516. }
  517. } {25}
  518. do_test minmax-12.17 {
  519. execsql {
  520. SELECT max(rowid) FROM t7 WHERE a=3 AND b=5 AND c=15;
  521. }
  522. } {5}
  523. #-------------------------------------------------------------------------
  524. reset_db
  525. proc do_test_13 {op name sql1 sql2 res} {
  526. set ::sqlite_search_count 0
  527. uplevel [list do_execsql_test $name.1 $sql1 $res]
  528. set a $::sqlite_search_count
  529. set ::sqlite_search_count 0
  530. uplevel [list do_execsql_test $name.2 $sql2 $res]
  531. set b $::sqlite_search_count
  532. uplevel [list do_test $name.3 [list expr "$a $op $b"] 1]
  533. }
  534. # Run a test named $name. Check that SQL statements $sql1 and $sql2 both
  535. # return the same result, but that $sql2 increments the $sqlite_search_count
  536. # variable more often (indicating that it is visiting more rows to determine
  537. # the result).
  538. #
  539. proc do_test_13_opt {name sql1 sql2 res} {
  540. uplevel [list do_test_13 < $name $sql1 $sql2 $res]
  541. }
  542. # Like [do_test_13_noopt], except this time check that the $sqlite_search_count
  543. # variable is incremented the same number of times by both SQL statements.
  544. #
  545. proc do_test_13_noopt {name sql1 sql2 res} {
  546. uplevel [list do_test_13 == $name $sql1 $sql2 $res]
  547. }
  548. do_execsql_test 13.1 {
  549. CREATE TABLE t1(a, b, c);
  550. INSERT INTO t1 VALUES('a', 1, 1);
  551. INSERT INTO t1 VALUES('b', 6, 6);
  552. INSERT INTO t1 VALUES('c', 5, 5);
  553. INSERT INTO t1 VALUES('a', 4, 4);
  554. INSERT INTO t1 VALUES('a', 5, 5);
  555. INSERT INTO t1 VALUES('c', 6, 6);
  556. INSERT INTO t1 VALUES('b', 4, 4);
  557. INSERT INTO t1 VALUES('c', 7, 7);
  558. INSERT INTO t1 VALUES('b', 2, 2);
  559. INSERT INTO t1 VALUES('b', 3, 3);
  560. INSERT INTO t1 VALUES('a', 3, 3);
  561. INSERT INTO t1 VALUES('b', 5, 5);
  562. INSERT INTO t1 VALUES('c', 4, 4);
  563. INSERT INTO t1 VALUES('c', 3, 3);
  564. INSERT INTO t1 VALUES('a', 2, 2);
  565. SELECT * FROM t1 ORDER BY a, b, c;
  566. } {a 1 1 a 2 2 a 3 3 a 4 4 a 5 5
  567. b 2 2 b 3 3 b 4 4 b 5 5 b 6 6
  568. c 3 3 c 4 4 c 5 5 c 6 6 c 7 7
  569. }
  570. do_execsql_test 13.2 { CREATE INDEX i1 ON t1(a, b, c) }
  571. do_test_13_opt 13.3 {
  572. SELECT min(b) FROM t1 WHERE a='b'
  573. } {
  574. SELECT min(c) FROM t1 WHERE a='b'
  575. } {2}
  576. do_test_13_opt 13.4 {
  577. SELECT a, min(b) FROM t1 WHERE a='b'
  578. } {
  579. SELECT a, min(c) FROM t1 WHERE a='b'
  580. } {b 2}
  581. do_test_13_opt 13.4 {
  582. SELECT a||c, max(b)+4 FROM t1 WHERE a='c'
  583. } {
  584. SELECT a||c, max(c)+4 FROM t1 WHERE a='c'
  585. } {c7 11}
  586. do_test_13_noopt 13.5 {
  587. SELECT a||c, max(b+1) FROM t1 WHERE a='c'
  588. } {
  589. SELECT a||c, max(c+1) FROM t1 WHERE a='c'
  590. } {c7 8}
  591. do_test_13_noopt 13.6 {
  592. SELECT count(b) FROM t1 WHERE a='c'
  593. } {
  594. SELECT count(c) FROM t1 WHERE a='c'
  595. } {5}
  596. do_test_13_noopt 13.7 {
  597. SELECT min(b), count(b) FROM t1 WHERE a='a';
  598. } {
  599. SELECT min(c), count(c) FROM t1 WHERE a='a';
  600. } {1 5}
  601. finish_test