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