xref: /titanic_51/usr/src/lib/libsqlite/test/minmax.test (revision c5c4113dfcabb1eed3d4bdf7609de5170027a794)
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