3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # Test cases for RANGE BETWEEN and especially with NULLS LAST
12 # and for varying separator handling by group_concat().
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set testprefix windowB
19 ifcapable !windowfunc {
25 CREATE TABLE t1(a, b);
26 INSERT INTO t1 VALUES(NULL, 1);
27 INSERT INTO t1 VALUES(NULL, 2);
28 INSERT INTO t1 VALUES(NULL, 3);
32 1 { ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
33 2 { ORDER BY a NULLS LAST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
34 3 { ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
35 4 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
37 5 { ORDER BY a NULLS LAST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }
38 6 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }
40 7 { ORDER BY a NULLS LAST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
41 8 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
43 do_execsql_test 1.$tn "
44 SELECT sum(b) OVER win FROM t1
45 WINDOW win AS ( $win )
50 SELECT sum(b) OVER win FROM t1
52 ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
56 #-------------------------------------------------------------------------
59 CREATE TABLE t1(a, b);
60 INSERT INTO t1 VALUES(1, NULL);
61 INSERT INTO t1 VALUES(2, 45);
62 INSERT INTO t1 VALUES(3, 66.2);
63 INSERT INTO t1 VALUES(4, 'hello world');
64 INSERT INTO t1 VALUES(5, 'hello world');
65 INSERT INTO t1 VALUES(6, X'1234');
66 INSERT INTO t1 VALUES(7, X'1234');
67 INSERT INTO t1 VALUES(8, NULL);
71 1 "ORDER BY b RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
72 2 "ORDER BY b RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
73 3 "ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
74 4 "ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
76 do_execsql_test 2.1.$tn "
77 SELECT a, sum(a) OVER win FROM t1
78 WINDOW win AS ( $win )
80 " {1 9 2 {} 3 {} 4 9 5 9 6 13 7 13 8 9}
83 #-------------------------------------------------------------------------
87 CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT, x TEXT);
88 INSERT INTO testjson VALUES(1, '{"a":1}', 'a');
89 INSERT INTO testjson VALUES(2, '{"b":2}', 'b');
90 INSERT INTO testjson VALUES(3, '{"c":3}', 'c');
91 INSERT INTO testjson VALUES(4, '{"d":4}', 'd');
95 SELECT json_group_array(json(j)) FROM testjson;
97 {[{"a":1},{"b":2},{"c":3},{"d":4}]}
100 do_execsql_test 3.2 {
101 SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson;
105 {[{"a":1},{"b":2},{"c":3}]}
106 {[{"a":1},{"b":2},{"c":3},{"d":4}]}
109 do_execsql_test 3.3 {
110 SELECT json_group_array(json(j)) OVER (
111 ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
117 {[{"a":1},{"b":2},{"c":3}]}
118 {[{"a":1},{"b":2},{"c":3},{"d":4}]}
121 do_execsql_test 3.4 {
122 SELECT json_group_array(json(j)) OVER (
123 ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
127 {[{"a":1},{"b":2},{"c":3}]}
128 {[{"b":2},{"c":3},{"d":4}]}
132 do_execsql_test 3.5 {
133 SELECT json_group_array(json(j)) OVER (
134 ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
143 do_execsql_test 3.5a {
144 UPDATE testjson SET j = replace(j,char(125),',"e":9'||char(125));
145 SELECT j FROM testjson;
152 do_execsql_test 3.5b {
153 SELECT group_concat(x,'') OVER (
154 ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
155 ) FROM testjson ORDER BY id;
157 do_execsql_test 3.5c {
158 SELECT json_group_array(json(j)) OVER (
159 ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
162 {[{"b":2,"e":9},{"c":3,"e":9}]}
163 {[{"c":3,"e":9},{"d":4,"e":9}]}
167 do_execsql_test 3.5d {
168 SELECT json_group_object(x,json(j)) OVER (
169 ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
172 {{"b":{"b":2,"e":9},"c":{"c":3,"e":9}}}
173 {{"c":{"c":3,"e":9},"d":{"d":4,"e":9}}}
174 {{"d":{"d":4,"e":9}}}
178 do_execsql_test 3.7b {
179 SELECT group_concat(x,'') FILTER (WHERE id!=2) OVER (
180 ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
184 do_execsql_test 3.7c {
185 SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER (
186 ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
194 do_execsql_test 3.7d {
195 SELECT json_group_object(x,json(j)) FILTER (WHERE id!=2) OVER (
196 ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
200 {{"a":{"a":1,"e":9}}}
201 {{"a":{"a":1,"e":9}}}
202 {{"c":{"c":3,"e":9}}}
206 #-------------------------------------------------------------------------
208 do_execsql_test 4.0 {
210 INSERT INTO x VALUES(1);
211 INSERT INTO x VALUES(2);
214 do_execsql_test 4.1 {
216 SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY a)
223 do_catchsql_test 4.2 {
225 SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION
228 } {1 {no such column: fake_column}}
230 do_catchsql_test 4.3 {
231 SELECT 1 WINDOW win AS (PARTITION BY fake_column);
234 #-------------------------------------------------------------------------
236 do_execsql_test 5.0 {
237 CREATE TABLE t1(a, c);
238 CREATE INDEX i1 ON t1(a);
240 INSERT INTO t1 VALUES(0, 421);
241 INSERT INTO t1 VALUES(1, 844);
242 INSERT INTO t1 VALUES(2, 1001);
245 do_execsql_test 5.1 {
246 SELECT a, sum(c) OVER (
247 ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
251 do_execsql_test 5.2 {
252 INSERT INTO t1 VALUES(NULL, 123);
253 INSERT INTO t1 VALUES(NULL, 111);
254 INSERT INTO t1 VALUES('xyz', 222);
255 INSERT INTO t1 VALUES('xyz', 333);
257 SELECT a, sum(c) OVER (
258 ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
260 } {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
262 do_execsql_test 5.3 {
263 SELECT a, sum(c) OVER (
264 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
266 } {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
268 do_execsql_test 5.4 {
269 SELECT a, sum(c) OVER (
270 ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING EXCLUDE NO OTHERS
272 } {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
274 do_execsql_test 5.5 {
275 SELECT a, sum(c) OVER (
276 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
278 } {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
280 #-------------------------------------------------------------------------
282 do_execsql_test 6.0 {
283 CREATE TABLE t1(a, c);
284 CREATE INDEX i1 ON t1(a);
286 INSERT INTO t1 VALUES(7, 997);
287 INSERT INTO t1 VALUES(8, 997);
288 INSERT INTO t1 VALUES('abc', 1001);
290 do_execsql_test 6.1 {
291 SELECT a, sum(c) OVER (
292 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
294 } {7 {} 8 {} abc 1001}
295 do_execsql_test 6.2 {
296 SELECT a, sum(c) OVER (
297 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
299 } {7 {} 8 {} abc 1001}
301 #-------------------------------------------------------------------------
303 do_execsql_test 7.0 {
304 CREATE TABLE t1(a, c);
305 CREATE INDEX i1 ON t1(a);
307 INSERT INTO t1 VALUES(NULL, 46);
308 INSERT INTO t1 VALUES(NULL, 45);
309 INSERT INTO t1 VALUES(7, 997);
310 INSERT INTO t1 VALUES(7, 1000);
311 INSERT INTO t1 VALUES(8, 997);
312 INSERT INTO t1 VALUES(8, 1000);
313 INSERT INTO t1 VALUES('abc', 1001);
314 INSERT INTO t1 VALUES('abc', 1004);
315 INSERT INTO t1 VALUES('xyz', 3333);
318 do_execsql_test 7.1 {
319 SELECT a, max(c) OVER (
320 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
322 } {{} 46 {} 46 7 {} 7 {} 8 {} 8 {} abc 1004 abc 1004 xyz 3333}
323 do_execsql_test 7.2 {
324 SELECT a, min(c) OVER (
325 ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
327 } {{} 45 {} 45 7 {} 7 {} 8 {} 8 {} abc 1001 abc 1001 xyz 3333}
329 do_execsql_test 7.3 {
330 SELECT a, max(c) OVER (
331 ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
333 } {{} 46 {} 46 7 {} 7 {} 8 {} 8 {} abc 1004 abc 1004 xyz 3333}
334 do_execsql_test 7.4 {
335 SELECT a, min(c) OVER (
336 ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
338 } {{} 45 {} 45 7 {} 7 {} 8 {} 8 {} abc 1001 abc 1001 xyz 3333}
340 #-------------------------------------------------------------------------
342 do_execsql_test 8.0 {
344 CREATE TABLE t1(a, c);
345 INSERT INTO t1 VALUES('aa', 111);
346 INSERT INTO t1 VALUES('BB', 660);
347 INSERT INTO t1 VALUES('CC', 938);
348 INSERT INTO t1 VALUES('dd', 979);
351 CREATE INDEX i1 ON t1(a COLLATE nocase);
354 do_execsql_test 8.1 {
356 (ORDER BY a COLLATE nocase RANGE BETWEEN 10.0 PRECEDING AND 5.0 PRECEDING)
360 do_execsql_test 9.0 {
361 CREATE TABLE seps(x);
362 INSERT INTO seps(x) VALUES ('1'), ('22'), ('333'), ('4444');
363 SELECT group_concat('-', x)
364 OVER ( ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING )
366 } {-22- -22-333- -333-4444- -4444-}
368 #-------------------------------------------------------------------------
370 do_execsql_test 10.1 {
371 CREATE TABLE t1(i INTEGER PRIMARY KEY, v);
372 INSERT INTO t1 VALUES( 1, 'one' );
373 INSERT INTO t1 VALUES( 2, 'two' );
376 do_execsql_test 10.2 {
378 json_group_array( v ) OVER w,
379 json_group_array( v ) OVER w
382 range between unbounded preceding and unbounded following
391 do_execsql_test 10.3 {
393 group_concat( v ) OVER w,
394 json_group_array( v ) OVER w,
395 json_group_array( v ) OVER w,
396 group_concat( v ) OVER w
399 range between unbounded preceding and unbounded following