xref: /sqlite-3.40.0/test/limit.test (revision c023e03e)
1# 2001 November 6
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 the LIMIT ... OFFSET ... clause
13#  of SELECT statements.
14#
15# $Id: limit.test,v 1.10 2003/07/20 01:16:48 drh Exp $
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20# Build some test data
21#
22set fd [open data1.txt w]
23for {set i 1} {$i<=32} {incr i} {
24  for {set j 0} {pow(2,$j)<$i} {incr j} {}
25  puts $fd "[expr {32-$i}]\t[expr {10-$j}]"
26}
27close $fd
28execsql {
29  CREATE TABLE t1(x int, y int);
30  COPY t1 FROM 'data1.txt'
31}
32file delete data1.txt
33
34do_test limit-1.0 {
35  execsql {SELECT count(*) FROM t1}
36} {32}
37do_test limit-1.1 {
38  execsql {SELECT count(*) FROM t1 LIMIT  5}
39} {32}
40do_test limit-1.2.1 {
41  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5}
42} {0 1 2 3 4}
43do_test limit-1.2.2 {
44  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 2}
45} {2 3 4 5 6}
46do_test limit-1.2.3 {
47  execsql {SELECT x FROM t1 ORDER BY x LIMIT 2, 5}
48} {2 3 4 5 6}
49do_test limit-1.3 {
50  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 5}
51} {5 6 7 8 9}
52do_test limit-1.4.1 {
53  execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 30}
54} {30 31}
55do_test limit-1.4.2 {
56  execsql {SELECT x FROM t1 ORDER BY x LIMIT 30, 50}
57} {30 31}
58do_test limit-1.5 {
59  execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 50}
60} {}
61do_test limit-1.6 {
62  execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5}
63} {0 5 0 5 0 5 1 5 0 5 2 5 0 5 3 5 0 5 4 5}
64do_test limit-1.7 {
65  execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5 OFFSET 32}
66} {1 5 0 5 1 5 1 5 1 5 2 5 1 5 3 5 1 5 4 5}
67
68do_test limit-2.1 {
69  execsql {
70    CREATE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
71    SELECT count(*) FROM (SELECT * FROM v1);
72  }
73} 2
74do_test limit-2.2 {
75  execsql {
76    CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 2;
77    SELECT count(*) FROM t2;
78  }
79} 2
80do_test limit-2.3 {
81  execsql {
82    SELECT count(*) FROM t1 WHERE rowid IN (SELECT rowid FROM t1 LIMIT 2);
83  }
84} 2
85
86do_test limit-3.1 {
87  execsql {
88    SELECT z FROM (SELECT y*10+x AS z FROM t1 ORDER BY x LIMIT 10)
89    ORDER BY z LIMIT 5;
90  }
91} {50 51 52 53 54}
92
93do_test limit-4.1 {
94  execsql {
95    BEGIN;
96    CREATE TABLE t3 AS SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1;
97    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
98    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
99    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
100    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
101    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
102    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
103    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
104    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
105    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
106    INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
107    END;
108    SELECT count(*) FROM t3;
109  }
110} {10240}
111do_test limit-4.2 {
112  execsql {
113    SELECT x FROM t3 LIMIT 2 OFFSET 10000
114  }
115} {10001 10002}
116do_test limit-4.3 {
117  execsql {
118    CREATE TABLE t4 AS SELECT x,
119       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
120       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
121       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
122       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
123       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x AS y
124    FROM t3 LIMIT 1000;
125    SELECT x FROM t4 ORDER BY y DESC LIMIT 1 OFFSET 999;
126  }
127} {1000}
128
129do_test limit-5.1 {
130  execsql {
131    CREATE TABLE t5(x,y);
132    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
133        ORDER BY x LIMIT 2;
134    SELECT * FROM t5 ORDER BY x;
135  }
136} {5 15 6 16}
137do_test limit-5.2 {
138  execsql {
139    DELETE FROM t5;
140    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
141        ORDER BY x DESC LIMIT 2;
142    SELECT * FROM t5 ORDER BY x;
143  }
144} {9 19 10 20}
145do_test limit-5.3 {
146  execsql {
147    DELETE FROM t5;
148    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x ORDER BY x DESC LIMIT 31;
149    SELECT * FROM t5 ORDER BY x LIMIT 2;
150  }
151} {-4 6 -3 7}
152do_test limit-5.4 {
153  execsql {
154    SELECT * FROM t5 ORDER BY x DESC, y DESC LIMIT 2;
155  }
156} {21 41 21 39}
157do_test limit-5.5 {
158  execsql {
159    DELETE FROM t5;
160    INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b
161                   ORDER BY 1, 2 LIMIT 1000;
162    SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5;
163  }
164} {1000 1528204 593161 0 3107 505 1005}
165
166# There is some contraversy about whether LIMIT 0 should be the same as
167# no limit at all or if LIMIT 0 should result in zero output rows.
168#
169do_test limit-6.1 {
170  execsql {
171    BEGIN;
172    CREATE TABLE t6(a);
173    INSERT INTO t6 VALUES(1);
174    INSERT INTO t6 VALUES(2);
175    INSERT INTO t6 SELECT a+2 FROM t6;
176    COMMIT;
177    SELECT * FROM t6;
178  }
179} {1 2 3 4}
180do_test limit-6.2 {
181  execsql {
182    SELECT * FROM t6 LIMIT -1 OFFSET -1;
183  }
184} {1 2 3 4}
185do_test limit-6.3 {
186  execsql {
187    SELECT * FROM t6 LIMIT 2 OFFSET -123;
188  }
189} {1 2}
190do_test limit-6.4 {
191  execsql {
192    SELECT * FROM t6 LIMIT -432 OFFSET 2;
193  }
194} {3 4}
195do_test limit-6.5 {
196  execsql {
197    SELECT * FROM t6 LIMIT -1
198  }
199} {1 2 3 4}
200do_test limit-6.6 {
201  execsql {
202    SELECT * FROM t6 LIMIT -1 OFFSET 1
203  }
204} {2 3 4}
205do_test limit-6.7 {
206  execsql {
207    SELECT * FROM t6 LIMIT 0
208  }
209} {}
210do_test limit-6.8 {
211  execsql {
212    SELECT * FROM t6 LIMIT 0 OFFSET 1
213  }
214} {}
215
216# Make sure LIMIT works well with compound SELECT statements.
217# Ticket #393
218#
219do_test limit-7.1.1 {
220  catchsql {
221    SELECT x FROM t2 LIMIT 5 UNION ALL SELECT a FROM t6;
222  }
223} {1 {LIMIT clause should come after UNION ALL not before}}
224do_test limit-7.1.2 {
225  catchsql {
226    SELECT x FROM t2 LIMIT 5 UNION SELECT a FROM t6;
227  }
228} {1 {LIMIT clause should come after UNION not before}}
229do_test limit-7.1.3 {
230  catchsql {
231    SELECT x FROM t2 LIMIT 5 EXCEPT SELECT a FROM t6 LIMIT 3;
232  }
233} {1 {LIMIT clause should come after EXCEPT not before}}
234do_test limit-7.1.4 {
235  catchsql {
236    SELECT x FROM t2 LIMIT 0,5 INTERSECT SELECT a FROM t6;
237  }
238} {1 {LIMIT clause should come after INTERSECT not before}}
239do_test limit-7.2 {
240  execsql {
241    SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 5;
242  }
243} {31 30 1 2 3}
244do_test limit-7.3 {
245  execsql {
246    SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 3 OFFSET 1;
247  }
248} {30 1 2}
249do_test limit-7.4 {
250  execsql {
251    SELECT x FROM t2 UNION ALL SELECT a FROM t6 ORDER BY 1 LIMIT 3 OFFSET 1;
252  }
253} {2 3 4}
254do_test limit-7.5 {
255  execsql {
256    SELECT x FROM t2 UNION SELECT x+2 FROM t2 LIMIT 2 OFFSET 1;
257  }
258} {31 32}
259do_test limit-7.6 {
260  execsql {
261    SELECT x FROM t2 UNION SELECT x+2 FROM t2 ORDER BY 1 DESC LIMIT 2 OFFSET 1;
262  }
263} {32 31}
264do_test limit-7.7 {
265  execsql {
266    SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 LIMIT 2;
267  }
268} {11 12}
269do_test limit-7.8 {
270  execsql {
271    SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 ORDER BY 1 DESC LIMIT 2;
272  }
273} {13 12}
274do_test limit-7.9 {
275  execsql {
276    SELECT a+26 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
277  }
278} {30}
279do_test limit-7.10 {
280  execsql {
281    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
282  }
283} {30}
284do_test limit-7.11 {
285  execsql {
286    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1 OFFSET 1;
287  }
288} {31}
289do_test limit-7.12 {
290  execsql {
291    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2
292       ORDER BY 1 DESC LIMIT 1 OFFSET 1;
293  }
294} {30}
295
296finish_test
297