xref: /sqlite-3.40.0/test/minmax.test (revision ce68b6bf)
15cf8e8c7Sdrh# 2001 September 15
25cf8e8c7Sdrh#
35cf8e8c7Sdrh# The author disclaims copyright to this source code.  In place of
45cf8e8c7Sdrh# a legal notice, here is a blessing:
55cf8e8c7Sdrh#
65cf8e8c7Sdrh#    May you do good and not evil.
75cf8e8c7Sdrh#    May you find forgiveness for yourself and forgive others.
85cf8e8c7Sdrh#    May you share freely, never taking more than you give.
95cf8e8c7Sdrh#
105cf8e8c7Sdrh#***********************************************************************
115cf8e8c7Sdrh# This file implements regression tests for SQLite library.  The
125cf8e8c7Sdrh# focus of this file is testing SELECT statements that contain
135cf8e8c7Sdrh# aggregate min() and max() functions and which are handled as
145cf8e8c7Sdrh# as a special case.
155cf8e8c7Sdrh#
160880a746Sdrh# $Id: minmax.test,v 1.21 2008/07/08 18:05:26 drh Exp $
175cf8e8c7Sdrh
185cf8e8c7Sdrhset testdir [file dirname $argv0]
195cf8e8c7Sdrhsource $testdir/tester.tcl
204ac391fcSdanset ::testprefix minmax
215cf8e8c7Sdrh
225cf8e8c7Sdrhdo_test minmax-1.0 {
235cf8e8c7Sdrh  execsql {
245cf8e8c7Sdrh    BEGIN;
255cf8e8c7Sdrh    CREATE TABLE t1(x, y);
265cf8e8c7Sdrh    INSERT INTO t1 VALUES(1,1);
275cf8e8c7Sdrh    INSERT INTO t1 VALUES(2,2);
285cf8e8c7Sdrh    INSERT INTO t1 VALUES(3,2);
295cf8e8c7Sdrh    INSERT INTO t1 VALUES(4,3);
305cf8e8c7Sdrh    INSERT INTO t1 VALUES(5,3);
315cf8e8c7Sdrh    INSERT INTO t1 VALUES(6,3);
325cf8e8c7Sdrh    INSERT INTO t1 VALUES(7,3);
335cf8e8c7Sdrh    INSERT INTO t1 VALUES(8,4);
345cf8e8c7Sdrh    INSERT INTO t1 VALUES(9,4);
355cf8e8c7Sdrh    INSERT INTO t1 VALUES(10,4);
365cf8e8c7Sdrh    INSERT INTO t1 VALUES(11,4);
375cf8e8c7Sdrh    INSERT INTO t1 VALUES(12,4);
385cf8e8c7Sdrh    INSERT INTO t1 VALUES(13,4);
395cf8e8c7Sdrh    INSERT INTO t1 VALUES(14,4);
405cf8e8c7Sdrh    INSERT INTO t1 VALUES(15,4);
415cf8e8c7Sdrh    INSERT INTO t1 VALUES(16,5);
425cf8e8c7Sdrh    INSERT INTO t1 VALUES(17,5);
435cf8e8c7Sdrh    INSERT INTO t1 VALUES(18,5);
445cf8e8c7Sdrh    INSERT INTO t1 VALUES(19,5);
455cf8e8c7Sdrh    INSERT INTO t1 VALUES(20,5);
465cf8e8c7Sdrh    COMMIT;
475cf8e8c7Sdrh    SELECT DISTINCT y FROM t1 ORDER BY y;
485cf8e8c7Sdrh  }
495cf8e8c7Sdrh} {1 2 3 4 5}
505cf8e8c7Sdrh
515cf8e8c7Sdrhdo_test minmax-1.1 {
525cf8e8c7Sdrh  set sqlite_search_count 0
535cf8e8c7Sdrh  execsql {SELECT min(x) FROM t1}
545cf8e8c7Sdrh} {1}
555cf8e8c7Sdrhdo_test minmax-1.2 {
565cf8e8c7Sdrh  set sqlite_search_count
575cf8e8c7Sdrh} {19}
585cf8e8c7Sdrhdo_test minmax-1.3 {
595cf8e8c7Sdrh  set sqlite_search_count 0
605cf8e8c7Sdrh  execsql {SELECT max(x) FROM t1}
615cf8e8c7Sdrh} {20}
625cf8e8c7Sdrhdo_test minmax-1.4 {
635cf8e8c7Sdrh  set sqlite_search_count
645cf8e8c7Sdrh} {19}
655cf8e8c7Sdrhdo_test minmax-1.5 {
665cf8e8c7Sdrh  execsql {CREATE INDEX t1i1 ON t1(x)}
675cf8e8c7Sdrh  set sqlite_search_count 0
685cf8e8c7Sdrh  execsql {SELECT min(x) FROM t1}
695cf8e8c7Sdrh} {1}
705cf8e8c7Sdrhdo_test minmax-1.6 {
715cf8e8c7Sdrh  set sqlite_search_count
72a9d1ccb9Sdanielk1977} {1}
735cf8e8c7Sdrhdo_test minmax-1.7 {
745cf8e8c7Sdrh  set sqlite_search_count 0
755cf8e8c7Sdrh  execsql {SELECT max(x) FROM t1}
765cf8e8c7Sdrh} {20}
775cf8e8c7Sdrhdo_test minmax-1.8 {
785cf8e8c7Sdrh  set sqlite_search_count
79a9d1ccb9Sdanielk1977} {0}
805cf8e8c7Sdrhdo_test minmax-1.9 {
815cf8e8c7Sdrh  set sqlite_search_count 0
825cf8e8c7Sdrh  execsql {SELECT max(y) FROM t1}
835cf8e8c7Sdrh} {5}
845cf8e8c7Sdrhdo_test minmax-1.10 {
855cf8e8c7Sdrh  set sqlite_search_count
865cf8e8c7Sdrh} {19}
875cf8e8c7Sdrh
880880a746Sdrhdo_test minmax-1.21 {
890880a746Sdrh  execsql {SELECT min(x) FROM t1 WHERE x=5}
900880a746Sdrh} {5}
910880a746Sdrhdo_test minmax-1.22 {
920880a746Sdrh  execsql {SELECT min(x) FROM t1 WHERE x>=5}
930880a746Sdrh} {5}
940880a746Sdrhdo_test minmax-1.23 {
950880a746Sdrh  execsql {SELECT min(x) FROM t1 WHERE x>=4.5}
960880a746Sdrh} {5}
970880a746Sdrhdo_test minmax-1.24 {
980880a746Sdrh  execsql {SELECT min(x) FROM t1 WHERE x<4.5}
990880a746Sdrh} {1}
1000880a746Sdrh
1015cf8e8c7Sdrhdo_test minmax-2.0 {
1025cf8e8c7Sdrh  execsql {
1035cf8e8c7Sdrh    CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
1045cf8e8c7Sdrh    INSERT INTO t2 SELECT * FROM t1;
1055cf8e8c7Sdrh  }
1065cf8e8c7Sdrh  set sqlite_search_count 0
1075cf8e8c7Sdrh  execsql {SELECT min(a) FROM t2}
1085cf8e8c7Sdrh} {1}
1095cf8e8c7Sdrhdo_test minmax-2.1 {
1105cf8e8c7Sdrh  set sqlite_search_count
1115cf8e8c7Sdrh} {0}
1125cf8e8c7Sdrhdo_test minmax-2.2 {
1135cf8e8c7Sdrh  set sqlite_search_count 0
1145cf8e8c7Sdrh  execsql {SELECT max(a) FROM t2}
1155cf8e8c7Sdrh} {20}
1165cf8e8c7Sdrhdo_test minmax-2.3 {
1175cf8e8c7Sdrh  set sqlite_search_count
1185cf8e8c7Sdrh} {0}
1195cf8e8c7Sdrh
1205cf8e8c7Sdrhdo_test minmax-3.0 {
1213e8c37e7Sdanielk1977  ifcapable subquery {
1225cf8e8c7Sdrh    execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
1233e8c37e7Sdanielk1977  } else {
1243e8c37e7Sdanielk1977    db function max_a_t2 {execsql {SELECT max(a) FROM t2}}
1253e8c37e7Sdanielk1977    execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)}
1263e8c37e7Sdanielk1977  }
1275cf8e8c7Sdrh  set sqlite_search_count 0
1285cf8e8c7Sdrh  execsql {SELECT max(a) FROM t2}
1295cf8e8c7Sdrh} {21}
1305cf8e8c7Sdrhdo_test minmax-3.1 {
1315cf8e8c7Sdrh  set sqlite_search_count
1325cf8e8c7Sdrh} {0}
1335cf8e8c7Sdrhdo_test minmax-3.2 {
1343e8c37e7Sdanielk1977  ifcapable subquery {
1355cf8e8c7Sdrh    execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
1363e8c37e7Sdanielk1977  } else {
1373e8c37e7Sdanielk1977    db function max_a_t2 {execsql {SELECT max(a) FROM t2}}
1383e8c37e7Sdanielk1977    execsql {INSERT INTO t2 VALUES(max_a_t2()+1,999)}
1393e8c37e7Sdanielk1977  }
1405cf8e8c7Sdrh  set sqlite_search_count 0
1413e8c37e7Sdanielk1977  ifcapable subquery {
1423e8c37e7Sdanielk1977    execsql { SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2) }
1433e8c37e7Sdanielk1977  } else {
1443e8c37e7Sdanielk1977    execsql { SELECT b FROM t2 WHERE a=max_a_t2() }
1455cf8e8c7Sdrh  }
1465cf8e8c7Sdrh} {999}
1475cf8e8c7Sdrhdo_test minmax-3.3 {
1485cf8e8c7Sdrh  set sqlite_search_count
1495cf8e8c7Sdrh} {0}
1505cf8e8c7Sdrh
151e61b9f4fSdanielk1977ifcapable {compound && subquery} {
152bb113518Sdrh  do_test minmax-4.1 {
153bb113518Sdrh    execsql {
154268380caSdrh      SELECT coalesce(min(x+0),-1), coalesce(max(x+0),-1) FROM
155bb113518Sdrh        (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y')
156bb113518Sdrh    }
1579eb516c0Sdrh  } {1 20}
158f570f011Sdrh  do_test minmax-4.2 {
159f570f011Sdrh    execsql {
1603f219f46Sdrh      SELECT y, coalesce(sum(x),0) FROM
16192378253Sdrh        (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1)
162f570f011Sdrh      GROUP BY y ORDER BY y;
163f570f011Sdrh    }
1643d1d95e6Sdrh  } {1 1 2 5 3 22 4 92 5 90 6 0}
165f570f011Sdrh  do_test minmax-4.3 {
166f570f011Sdrh    execsql {
167f570f011Sdrh      SELECT y, count(x), count(*) FROM
16892378253Sdrh        (SELECT null AS x, y+1 AS y FROM t1 UNION SELECT * FROM t1)
169f570f011Sdrh      GROUP BY y ORDER BY y;
170f570f011Sdrh    }
171f570f011Sdrh  } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1}
17227c77438Sdanielk1977} ;# ifcapable compound
1735cf8e8c7Sdrh
174d4d595f9Sdrh# Make sure the min(x) and max(x) optimizations work on empty tables
175d4d595f9Sdrh# including empty tables with indices. Ticket #296.
176d4d595f9Sdrh#
177d4d595f9Sdrhdo_test minmax-5.1 {
178d4d595f9Sdrh  execsql {
179d4d595f9Sdrh    CREATE TABLE t3(x INTEGER UNIQUE NOT NULL);
180d4d595f9Sdrh    SELECT coalesce(min(x),999) FROM t3;
181d4d595f9Sdrh  }
182d4d595f9Sdrh} {999}
183d4d595f9Sdrhdo_test minmax-5.2 {
184d4d595f9Sdrh  execsql {
185d4d595f9Sdrh    SELECT coalesce(min(rowid),999) FROM t3;
186d4d595f9Sdrh  }
187d4d595f9Sdrh} {999}
188d4d595f9Sdrhdo_test minmax-5.3 {
189d4d595f9Sdrh  execsql {
190d4d595f9Sdrh    SELECT coalesce(max(x),999) FROM t3;
191d4d595f9Sdrh  }
192d4d595f9Sdrh} {999}
193d4d595f9Sdrhdo_test minmax-5.4 {
194d4d595f9Sdrh  execsql {
195d4d595f9Sdrh    SELECT coalesce(max(rowid),999) FROM t3;
196d4d595f9Sdrh  }
197d4d595f9Sdrh} {999}
198d4d595f9Sdrhdo_test minmax-5.5 {
199d4d595f9Sdrh  execsql {
200d4d595f9Sdrh    SELECT coalesce(max(rowid),999) FROM t3 WHERE rowid<25;
201d4d595f9Sdrh  }
202d4d595f9Sdrh} {999}
203d4d595f9Sdrh
204e5f50722Sdrh# Make sure the min(x) and max(x) optimizations work when there
205e5f50722Sdrh# is a LIMIT clause.  Ticket #396.
206e5f50722Sdrh#
207e5f50722Sdrhdo_test minmax-6.1 {
208e5f50722Sdrh  execsql {
209e5f50722Sdrh    SELECT min(a) FROM t2 LIMIT 1
210e5f50722Sdrh  }
211e5f50722Sdrh} {1}
212e5f50722Sdrhdo_test minmax-6.2 {
213e5f50722Sdrh  execsql {
214e5f50722Sdrh    SELECT max(a) FROM t2 LIMIT 3
215e5f50722Sdrh  }
216e5f50722Sdrh} {22}
217e5f50722Sdrhdo_test minmax-6.3 {
218e5f50722Sdrh  execsql {
219e5f50722Sdrh    SELECT min(a) FROM t2 LIMIT 0,100
220e5f50722Sdrh  }
221e5f50722Sdrh} {1}
222e5f50722Sdrhdo_test minmax-6.4 {
223e5f50722Sdrh  execsql {
224e5f50722Sdrh    SELECT max(a) FROM t2 LIMIT 1,100
225e5f50722Sdrh  }
226e5f50722Sdrh} {}
227e5f50722Sdrhdo_test minmax-6.5 {
228e5f50722Sdrh  execsql {
229e5f50722Sdrh    SELECT min(x) FROM t3 LIMIT 1
230e5f50722Sdrh  }
231e5f50722Sdrh} {{}}
232e5f50722Sdrhdo_test minmax-6.6 {
233e5f50722Sdrh  execsql {
234e5f50722Sdrh    SELECT max(x) FROM t3 LIMIT 0
235e5f50722Sdrh  }
236e5f50722Sdrh} {}
237e5f50722Sdrhdo_test minmax-6.7 {
238e5f50722Sdrh  execsql {
239e5f50722Sdrh    SELECT max(a) FROM t2 LIMIT 0
240e5f50722Sdrh  }
241e5f50722Sdrh} {}
242e5f50722Sdrh
2430c37e630Sdrh# Make sure the max(x) and min(x) optimizations work for nested
2440c37e630Sdrh# queries.  Ticket #587.
2450c37e630Sdrh#
2460c37e630Sdrhdo_test minmax-7.1 {
2470c37e630Sdrh  execsql {
2480c37e630Sdrh    SELECT max(x) FROM t1;
2490c37e630Sdrh  }
2500c37e630Sdrh} 20
2513e8c37e7Sdanielk1977ifcapable subquery {
2520c37e630Sdrh  do_test minmax-7.2 {
2530c37e630Sdrh    execsql {
2540c37e630Sdrh      SELECT * FROM (SELECT max(x) FROM t1);
2550c37e630Sdrh    }
2560c37e630Sdrh  } 20
2573e8c37e7Sdanielk1977}
2580c37e630Sdrhdo_test minmax-7.3 {
2590c37e630Sdrh  execsql {
2600c37e630Sdrh    SELECT min(x) FROM t1;
2610c37e630Sdrh  }
2620c37e630Sdrh} 1
2633e8c37e7Sdanielk1977ifcapable subquery {
2640c37e630Sdrh  do_test minmax-7.4 {
2650c37e630Sdrh    execsql {
2660c37e630Sdrh      SELECT * FROM (SELECT min(x) FROM t1);
2670c37e630Sdrh    }
2680c37e630Sdrh  } 1
2693e8c37e7Sdanielk1977}
2700c37e630Sdrh
271268380caSdrh# Make sure min(x) and max(x) work correctly when the datatype is
272268380caSdrh# TEXT instead of NUMERIC.  Ticket #623.
273268380caSdrh#
274268380caSdrhdo_test minmax-8.1 {
275268380caSdrh  execsql {
276268380caSdrh    CREATE TABLE t4(a TEXT);
277268380caSdrh    INSERT INTO t4 VALUES('1234');
278268380caSdrh    INSERT INTO t4 VALUES('234');
279268380caSdrh    INSERT INTO t4 VALUES('34');
280268380caSdrh    SELECT min(a), max(a) FROM t4;
281268380caSdrh  }
282268380caSdrh} {1234 34}
283268380caSdrhdo_test minmax-8.2 {
284268380caSdrh  execsql {
285268380caSdrh    CREATE TABLE t5(a INTEGER);
286268380caSdrh    INSERT INTO t5 VALUES('1234');
287268380caSdrh    INSERT INTO t5 VALUES('234');
288268380caSdrh    INSERT INTO t5 VALUES('34');
289268380caSdrh    SELECT min(a), max(a) FROM t5;
290268380caSdrh  }
291268380caSdrh} {34 1234}
292268380caSdrh
2936e17529eSdrh# Ticket #658:  Test the min()/max() optimization when the FROM clause
2946e17529eSdrh# is a subquery.
2956e17529eSdrh#
296e61b9f4fSdanielk1977ifcapable {compound && subquery} {
2976e5020e8Sdrh  do_test minmax-9.0 {
2986e5020e8Sdrh    execsql {
2996e5020e8Sdrh      SELECT max(rowid) AS yy FROM t4 UNION SELECT max(rowid) FROM t5
3006e5020e8Sdrh    }
3016e5020e8Sdrh  } {3}
3026e17529eSdrh  do_test minmax-9.1 {
3036e17529eSdrh    execsql {
3046e5020e8Sdrh      SELECT max(yy) FROM (
3056e5020e8Sdrh        SELECT max(rowid) AS yy FROM t4 UNION SELECT max(rowid) FROM t5
3066e17529eSdrh      )
3076e17529eSdrh    }
3086e5020e8Sdrh  } {3}
3096e17529eSdrh  do_test minmax-9.2 {
3106e17529eSdrh    execsql {
3116e5020e8Sdrh      SELECT max(yy) FROM (
3126e5020e8Sdrh        SELECT max(rowid) AS yy FROM t4 EXCEPT SELECT max(rowid) FROM t5
3136e17529eSdrh      )
3146e17529eSdrh    }
3156e17529eSdrh  } {{}}
316e61b9f4fSdanielk1977} ;# ifcapable compound&&subquery
317d4d595f9Sdrh
3189eb516c0Sdrh# If there is a NULL in an aggregate max() or min(), ignore it.  An
3199eb516c0Sdrh# aggregate min() or max() will only return NULL if all values are NULL.
3203aeab9e4Sdanielk1977#
3213aeab9e4Sdanielk1977do_test minmax-10.1 {
3223aeab9e4Sdanielk1977  execsql {
3233aeab9e4Sdanielk1977    CREATE TABLE t6(x);
3243aeab9e4Sdanielk1977    INSERT INTO t6 VALUES(1);
3253aeab9e4Sdanielk1977    INSERT INTO t6 VALUES(2);
3263aeab9e4Sdanielk1977    INSERT INTO t6 VALUES(NULL);
3273aeab9e4Sdanielk1977    SELECT coalesce(min(x),-1) FROM t6;
3283aeab9e4Sdanielk1977  }
3299eb516c0Sdrh} {1}
3303aeab9e4Sdanielk1977do_test minmax-10.2 {
3313aeab9e4Sdanielk1977  execsql {
3323aeab9e4Sdanielk1977    SELECT max(x) FROM t6;
3333aeab9e4Sdanielk1977  }
3343aeab9e4Sdanielk1977} {2}
3353aeab9e4Sdanielk1977do_test minmax-10.3 {
3363aeab9e4Sdanielk1977  execsql {
3373aeab9e4Sdanielk1977    CREATE INDEX i6 ON t6(x);
3383aeab9e4Sdanielk1977    SELECT coalesce(min(x),-1) FROM t6;
3393aeab9e4Sdanielk1977  }
3409eb516c0Sdrh} {1}
3413aeab9e4Sdanielk1977do_test minmax-10.4 {
3423aeab9e4Sdanielk1977  execsql {
3433aeab9e4Sdanielk1977    SELECT max(x) FROM t6;
3443aeab9e4Sdanielk1977  }
3453aeab9e4Sdanielk1977} {2}
3469eb516c0Sdrhdo_test minmax-10.5 {
3479eb516c0Sdrh  execsql {
3489eb516c0Sdrh    DELETE FROM t6 WHERE x NOT NULL;
3499eb516c0Sdrh    SELECT count(*) FROM t6;
3509eb516c0Sdrh  }
3519eb516c0Sdrh} 1
3529eb516c0Sdrhdo_test minmax-10.6 {
3539eb516c0Sdrh  execsql {
3549eb516c0Sdrh    SELECT count(x) FROM t6;
3559eb516c0Sdrh  }
3569eb516c0Sdrh} 0
3573e8c37e7Sdanielk1977ifcapable subquery {
3589eb516c0Sdrh  do_test minmax-10.7 {
3599eb516c0Sdrh    execsql {
3609eb516c0Sdrh      SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
3619eb516c0Sdrh    }
3629eb516c0Sdrh  } {{} {}}
3633e8c37e7Sdanielk1977}
3649eb516c0Sdrhdo_test minmax-10.8 {
3659eb516c0Sdrh  execsql {
3669eb516c0Sdrh    SELECT min(x), max(x) FROM t6;
3679eb516c0Sdrh  }
3689eb516c0Sdrh} {{} {}}
3699eb516c0Sdrhdo_test minmax-10.9 {
3709eb516c0Sdrh  execsql {
3719eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3729eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3739eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3749eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3759eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3769eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3779eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3789eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3799eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3809eb516c0Sdrh    INSERT INTO t6 SELECT * FROM t6;
3819eb516c0Sdrh    SELECT count(*) FROM t6;
3829eb516c0Sdrh  }
3839eb516c0Sdrh} 1024
3849eb516c0Sdrhdo_test minmax-10.10 {
3859eb516c0Sdrh  execsql {
3869eb516c0Sdrh    SELECT count(x) FROM t6;
3879eb516c0Sdrh  }
3889eb516c0Sdrh} 0
3893e8c37e7Sdanielk1977ifcapable subquery {
3909eb516c0Sdrh  do_test minmax-10.11 {
3919eb516c0Sdrh    execsql {
3929eb516c0Sdrh      SELECT (SELECT min(x) FROM t6), (SELECT max(x) FROM t6);
3939eb516c0Sdrh    }
3949eb516c0Sdrh  } {{} {}}
3953e8c37e7Sdanielk1977}
3969eb516c0Sdrhdo_test minmax-10.12 {
3979eb516c0Sdrh  execsql {
3989eb516c0Sdrh    SELECT min(x), max(x) FROM t6;
3999eb516c0Sdrh  }
4009eb516c0Sdrh} {{} {}}
4019eb516c0Sdrh
4023aeab9e4Sdanielk1977
4030880a746Sdrhdo_test minmax-11.1 {
4040880a746Sdrh  execsql {
4050880a746Sdrh    CREATE INDEX t1i2 ON t1(y,x);
4060880a746Sdrh    SELECT min(x) FROM t1 WHERE y=5;
4070880a746Sdrh  }
4080880a746Sdrh} {16}
4090880a746Sdrhdo_test minmax-11.2 {
4100880a746Sdrh  execsql {
4110880a746Sdrh    SELECT max(x) FROM t1 WHERE y=5;
4120880a746Sdrh  }
4130880a746Sdrh} {20}
4140880a746Sdrhdo_test minmax-11.3 {
4150880a746Sdrh  execsql {
4160880a746Sdrh    SELECT min(x) FROM t1 WHERE y=6;
4170880a746Sdrh  }
4180880a746Sdrh} {{}}
4190880a746Sdrhdo_test minmax-11.4 {
4200880a746Sdrh  execsql {
4210880a746Sdrh    SELECT max(x) FROM t1 WHERE y=6;
4220880a746Sdrh  }
4230880a746Sdrh} {{}}
4240880a746Sdrhdo_test minmax-11.5 {
4250880a746Sdrh  execsql {
4260880a746Sdrh    SELECT min(x) FROM t1 WHERE y=1;
4270880a746Sdrh  }
4280880a746Sdrh} {1}
4290880a746Sdrhdo_test minmax-11.6 {
4300880a746Sdrh  execsql {
4310880a746Sdrh    SELECT max(x) FROM t1 WHERE y=1;
4320880a746Sdrh  }
4330880a746Sdrh} {1}
4340880a746Sdrhdo_test minmax-11.7 {
4350880a746Sdrh  execsql {
4360880a746Sdrh    SELECT min(x) FROM t1 WHERE y=0;
4370880a746Sdrh  }
4380880a746Sdrh} {{}}
4390880a746Sdrhdo_test minmax-11.8 {
4400880a746Sdrh  execsql {
4410880a746Sdrh    SELECT max(x) FROM t1 WHERE y=0;
4420880a746Sdrh  }
4430880a746Sdrh} {{}}
4440880a746Sdrhdo_test minmax-11.9 {
4450880a746Sdrh  execsql {
4460880a746Sdrh    SELECT min(x) FROM t1 WHERE y=5 AND x>=17.5;
4470880a746Sdrh  }
4480880a746Sdrh} {18}
4490880a746Sdrhdo_test minmax-11.10 {
4500880a746Sdrh  execsql {
4510880a746Sdrh    SELECT max(x) FROM t1 WHERE y=5 AND x>=17.5;
4520880a746Sdrh  }
4530880a746Sdrh} {20}
4540880a746Sdrh
4550880a746Sdrhdo_test minmax-12.1 {
4560880a746Sdrh  execsql {
4570880a746Sdrh    CREATE TABLE t7(a,b,c);
4580880a746Sdrh    INSERT INTO t7 SELECT y, x, x*y FROM t1;
4590880a746Sdrh    INSERT INTO t7 SELECT y, x, x*y+1000 FROM t1;
4600880a746Sdrh    CREATE INDEX t7i1 ON t7(a,b,c);
4610880a746Sdrh    SELECT min(a) FROM t7;
4620880a746Sdrh  }
4630880a746Sdrh} {1}
4640880a746Sdrhdo_test minmax-12.2 {
4650880a746Sdrh  execsql {
4660880a746Sdrh    SELECT max(a) FROM t7;
4670880a746Sdrh  }
4680880a746Sdrh} {5}
4690880a746Sdrhdo_test minmax-12.3 {
4700880a746Sdrh  execsql {
4710880a746Sdrh    SELECT max(a) FROM t7 WHERE a=5;
4720880a746Sdrh  }
4730880a746Sdrh} {5}
4740880a746Sdrhdo_test minmax-12.4 {
4750880a746Sdrh  execsql {
4760880a746Sdrh    SELECT min(b) FROM t7 WHERE a=5;
4770880a746Sdrh  }
4780880a746Sdrh} {16}
4790880a746Sdrhdo_test minmax-12.5 {
4800880a746Sdrh  execsql {
4810880a746Sdrh    SELECT max(b) FROM t7 WHERE a=5;
4820880a746Sdrh  }
4830880a746Sdrh} {20}
4840880a746Sdrhdo_test minmax-12.6 {
4850880a746Sdrh  execsql {
4860880a746Sdrh    SELECT min(b) FROM t7 WHERE a=4;
4870880a746Sdrh  }
4880880a746Sdrh} {8}
4890880a746Sdrhdo_test minmax-12.7 {
4900880a746Sdrh  execsql {
4910880a746Sdrh    SELECT max(b) FROM t7 WHERE a=4;
4920880a746Sdrh  }
4930880a746Sdrh} {15}
4940880a746Sdrhdo_test minmax-12.8 {
4950880a746Sdrh  execsql {
4960880a746Sdrh    SELECT min(c) FROM t7 WHERE a=4 AND b=10;
4970880a746Sdrh  }
4980880a746Sdrh} {40}
4990880a746Sdrhdo_test minmax-12.9 {
5000880a746Sdrh  execsql {
5010880a746Sdrh    SELECT max(c) FROM t7 WHERE a=4 AND b=10;
5020880a746Sdrh  }
5030880a746Sdrh} {1040}
5040880a746Sdrhdo_test minmax-12.10 {
5050880a746Sdrh  execsql {
5060880a746Sdrh    SELECT min(rowid) FROM t7;
5070880a746Sdrh  }
5080880a746Sdrh} {1}
5090880a746Sdrhdo_test minmax-12.11 {
5100880a746Sdrh  execsql {
5110880a746Sdrh    SELECT max(rowid) FROM t7;
5120880a746Sdrh  }
5130880a746Sdrh} {40}
5140880a746Sdrhdo_test minmax-12.12 {
5150880a746Sdrh  execsql {
5160880a746Sdrh    SELECT min(rowid) FROM t7 WHERE a=3;
5170880a746Sdrh  }
5180880a746Sdrh} {4}
5190880a746Sdrhdo_test minmax-12.13 {
5200880a746Sdrh  execsql {
5210880a746Sdrh    SELECT max(rowid) FROM t7 WHERE a=3;
5220880a746Sdrh  }
5230880a746Sdrh} {27}
5240880a746Sdrhdo_test minmax-12.14 {
5250880a746Sdrh  execsql {
5260880a746Sdrh    SELECT min(rowid) FROM t7 WHERE a=3 AND b=5;
5270880a746Sdrh  }
5280880a746Sdrh} {5}
5290880a746Sdrhdo_test minmax-12.15 {
5300880a746Sdrh  execsql {
5310880a746Sdrh    SELECT max(rowid) FROM t7 WHERE a=3 AND b=5;
5320880a746Sdrh  }
5330880a746Sdrh} {25}
5340880a746Sdrhdo_test minmax-12.16 {
5350880a746Sdrh  execsql {
5360880a746Sdrh    SELECT min(rowid) FROM t7 WHERE a=3 AND b=5 AND c=1015;
5370880a746Sdrh  }
5380880a746Sdrh} {25}
5390880a746Sdrhdo_test minmax-12.17 {
5400880a746Sdrh  execsql {
5410880a746Sdrh    SELECT max(rowid) FROM t7 WHERE a=3 AND b=5 AND c=15;
5420880a746Sdrh  }
5430880a746Sdrh} {5}
5440880a746Sdrh
5454ac391fcSdan#-------------------------------------------------------------------------
5464ac391fcSdanreset_db
5470880a746Sdrh
5484ac391fcSdanproc do_test_13 {op name sql1 sql2 res} {
5494ac391fcSdan  set ::sqlite_search_count 0
5504ac391fcSdan  uplevel [list do_execsql_test $name.1 $sql1 $res]
5514ac391fcSdan  set a $::sqlite_search_count
5524ac391fcSdan
5534ac391fcSdan  set ::sqlite_search_count 0
5544ac391fcSdan  uplevel [list do_execsql_test $name.2 $sql2 $res]
5554ac391fcSdan  set b $::sqlite_search_count
5564ac391fcSdan
5574ac391fcSdan  uplevel [list do_test $name.3 [list expr "$a $op $b"] 1]
5584ac391fcSdan}
5594ac391fcSdan
5604ac391fcSdan# Run a test named $name. Check that SQL statements $sql1 and $sql2 both
5614ac391fcSdan# return the same result, but that $sql2 increments the $sqlite_search_count
5624ac391fcSdan# variable more often (indicating that it is visiting more rows to determine
5634ac391fcSdan# the result).
5644ac391fcSdan#
5654ac391fcSdanproc do_test_13_opt {name sql1 sql2 res} {
5664ac391fcSdan  uplevel [list do_test_13 < $name $sql1 $sql2 $res]
5674ac391fcSdan}
5684ac391fcSdan
5694ac391fcSdan# Like [do_test_13_noopt], except this time check that the $sqlite_search_count
5704ac391fcSdan# variable is incremented the same number of times by both SQL statements.
5714ac391fcSdan#
5724ac391fcSdanproc do_test_13_noopt {name sql1 sql2 res} {
5734ac391fcSdan  uplevel [list do_test_13 == $name $sql1 $sql2 $res]
5744ac391fcSdan}
5754ac391fcSdan
5764ac391fcSdando_execsql_test 13.1 {
5774ac391fcSdan  CREATE TABLE t1(a, b, c);
5784ac391fcSdan  INSERT INTO t1 VALUES('a', 1, 1);
5794ac391fcSdan  INSERT INTO t1 VALUES('b', 6, 6);
5804ac391fcSdan  INSERT INTO t1 VALUES('c', 5, 5);
5814ac391fcSdan  INSERT INTO t1 VALUES('a', 4, 4);
5824ac391fcSdan  INSERT INTO t1 VALUES('a', 5, 5);
5834ac391fcSdan  INSERT INTO t1 VALUES('c', 6, 6);
5844ac391fcSdan  INSERT INTO t1 VALUES('b', 4, 4);
5854ac391fcSdan  INSERT INTO t1 VALUES('c', 7, 7);
5864ac391fcSdan  INSERT INTO t1 VALUES('b', 2, 2);
5874ac391fcSdan  INSERT INTO t1 VALUES('b', 3, 3);
5884ac391fcSdan  INSERT INTO t1 VALUES('a', 3, 3);
5894ac391fcSdan  INSERT INTO t1 VALUES('b', 5, 5);
5904ac391fcSdan  INSERT INTO t1 VALUES('c', 4, 4);
5914ac391fcSdan  INSERT INTO t1 VALUES('c', 3, 3);
5924ac391fcSdan  INSERT INTO t1 VALUES('a', 2, 2);
5934ac391fcSdan  SELECT * FROM t1 ORDER BY a, b, c;
5944ac391fcSdan} {a 1 1 a 2 2 a 3 3 a 4 4 a 5 5
5954ac391fcSdan   b 2 2 b 3 3 b 4 4 b 5 5 b 6 6
5964ac391fcSdan   c 3 3 c 4 4 c 5 5 c 6 6 c 7 7
5974ac391fcSdan}
5984ac391fcSdando_execsql_test 13.2 { CREATE INDEX i1 ON t1(a, b, c) }
5994ac391fcSdan
6004ac391fcSdando_test_13_opt 13.3 {
6014ac391fcSdan  SELECT min(b) FROM t1 WHERE a='b'
6024ac391fcSdan} {
6034ac391fcSdan  SELECT min(c) FROM t1 WHERE a='b'
6044ac391fcSdan} {2}
6054ac391fcSdan
6064ac391fcSdando_test_13_opt 13.4 {
6074ac391fcSdan  SELECT a, min(b) FROM t1 WHERE a='b'
6084ac391fcSdan} {
6094ac391fcSdan  SELECT a, min(c) FROM t1 WHERE a='b'
6104ac391fcSdan} {b 2}
6114ac391fcSdan
6124ac391fcSdando_test_13_opt 13.4 {
6134ac391fcSdan  SELECT a||c, max(b)+4 FROM t1 WHERE a='c'
6144ac391fcSdan} {
6154ac391fcSdan  SELECT a||c, max(c)+4 FROM t1 WHERE a='c'
6164ac391fcSdan} {c7 11}
6174ac391fcSdan
6184ac391fcSdando_test_13_noopt 13.5 {
6194ac391fcSdan  SELECT a||c, max(b+1) FROM t1 WHERE a='c'
6204ac391fcSdan} {
6214ac391fcSdan  SELECT a||c, max(c+1) FROM t1 WHERE a='c'
6224ac391fcSdan} {c7 8}
6234ac391fcSdan
6244ac391fcSdando_test_13_noopt 13.6 {
6254ac391fcSdan  SELECT count(b) FROM t1 WHERE a='c'
6264ac391fcSdan} {
6274ac391fcSdan  SELECT count(c) FROM t1 WHERE a='c'
6284ac391fcSdan} {5}
6294ac391fcSdan
6304ac391fcSdando_test_13_noopt 13.7 {
6314ac391fcSdan  SELECT min(b), count(b) FROM t1 WHERE a='a';
6324ac391fcSdan} {
6334ac391fcSdan  SELECT min(c), count(c) FROM t1 WHERE a='a';
6344ac391fcSdan} {1 5}
6350880a746Sdrh
636426f4ab0Sdrh# 2016-07-26.  https://www.sqlite.org/src/info/a0bac8b3c3d1bb75
637426f4ab0Sdrh# Incorrect result on a min() query after a CREATE INDEX.
638426f4ab0Sdrh#
639426f4ab0Sdrhdo_execsql_test 14.1 {
640426f4ab0Sdrh  CREATE TABLE t14(a INTEGER, b INTEGER);
641426f4ab0Sdrh  INSERT INTO t14(a,b) VALUES(100,2),(200,2),(300,2),(400,1),(500,2);
642426f4ab0Sdrh  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
643426f4ab0Sdrh} {100}
644426f4ab0Sdrhdo_execsql_test 14.2 {
645426f4ab0Sdrh  CREATE INDEX t14ba ON t14(b,a);
646426f4ab0Sdrh  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
647426f4ab0Sdrh} {100}
648426f4ab0Sdrh
649*ce68b6bfSdrh# 2021-08-21.  https://sqlite.org/forum/forumpost/cfcb4b461d
650*ce68b6bfSdrh#
651*ce68b6bfSdrhreset_db
652*ce68b6bfSdrhdo_execsql_test 15.1 {
653*ce68b6bfSdrh  CREATE TABLE t1(a);
654*ce68b6bfSdrh  CREATE TABLE t2(b);
655*ce68b6bfSdrh  CREATE TABLE t3(c);
656*ce68b6bfSdrh  INSERT INTO t1 VALUES(0);
657*ce68b6bfSdrh  INSERT INTO t2 VALUES(5);
658*ce68b6bfSdrh  SELECT MIN((SELECT b FROM t2 UNION SELECT x FROM (SELECT x FROM (SELECT 1 AS x WHERE t1.a=1) UNION ALL SELECT c FROM t3))) FROM t1;
659*ce68b6bfSdrh} {5}
6600880a746Sdrh
6615cf8e8c7Sdrhfinish_test
662