2 -- tsrf - targetlist set returning function tests
5 SELECT generate_series(1, 3);
14 SELECT generate_series(1, 3), generate_series(3,5);
15 generate_series | generate_series
16 -----------------+-----------------
22 -- parallel iteration, different number of rows
23 SELECT generate_series(1, 2), generate_series(1,4);
24 generate_series | generate_series
25 -----------------+-----------------
32 -- srf, with SRF argument
33 SELECT generate_series(1, generate_series(1, 3));
44 -- but we've traditionally rejected the same in FROM
45 SELECT * FROM generate_series(1, generate_series(1, 3));
46 ERROR: set-returning functions must appear at top level of FROM
47 LINE 1: SELECT * FROM generate_series(1, generate_series(1, 3));
49 -- srf, with two SRF arguments
50 SELECT generate_series(generate_series(1,3), generate_series(2, 4));
61 -- check proper nesting of SRFs in different expressions
62 explain (verbose, costs off)
63 SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4);
65 --------------------------------------------------------------------------------
67 Output: generate_series(1, (generate_series(1, 3))), (generate_series(2, 4))
69 Output: generate_series(1, 3), generate_series(2, 4)
73 SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4);
74 generate_series | generate_series
75 -----------------+-----------------
84 CREATE TABLE few(id int, dataa text, datab text);
85 INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar');
86 -- SRF with a provably-dummy relation
87 explain (verbose, costs off)
88 SELECT unnest(ARRAY[1, 2]) FROM few WHERE false;
90 --------------------------------------
92 Output: unnest('{1,2}'::integer[])
94 One-Time Filter: false
97 SELECT unnest(ARRAY[1, 2]) FROM few WHERE false;
102 -- SRF shouldn't prevent upper query from recognizing lower as dummy
103 explain (verbose, costs off)
104 SELECT * FROM few f1,
105 (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss;
107 ------------------------------------------------
109 Output: f1.id, f1.dataa, f1.datab, ss.unnest
110 One-Time Filter: false
113 SELECT * FROM few f1,
114 (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss;
115 id | dataa | datab | unnest
116 ----+-------+-------+--------
119 -- SRF output order of sorting is maintained, if SRF is not referenced
120 SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC;
134 -- but SRFs can be referenced in sort
135 SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, g DESC;
149 SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, generate_series(1,3) DESC;
163 -- it's weird to have ORDER BYs that increase the number of results
164 SELECT few.id FROM few ORDER BY id, generate_series(1,3) DESC;
178 -- SRFs are computed after aggregation
179 SET enable_hashagg TO 0; -- stable output order
180 SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa;
181 dataa | count | min | max | unnest
182 -------+-------+-----+-----+--------
188 -- unless referenced in GROUP BY clause
189 SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, unnest('{1,1,3}'::int[]);
190 dataa | count | min | max | unnest
191 -------+-------+-----+-----+--------
196 SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, 5;
197 dataa | count | min | max | unnest
198 -------+-------+-----+-----+--------
203 RESET enable_hashagg;
204 -- check HAVING works when GROUP BY does [not] reference SRF output
205 SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1 HAVING count(*) > 1;
206 dataa | generate_series | count
207 -------+-----------------+-------
211 SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1, 2 HAVING count(*) > 1;
212 dataa | generate_series | count
213 -------+-----------------+-------
217 -- it's weird to have GROUP BYs that increase the number of results
218 SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa ORDER BY 2;
224 SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa, unnest('{1,1,3}'::int[]) ORDER BY 2;
231 -- SRFs are not allowed if they'd need to be conditionally executed
232 SELECT q1, case when q1 > 0 then generate_series(1,3) else 0 end FROM int8_tbl;
233 ERROR: set-returning functions are not allowed in CASE
234 LINE 1: SELECT q1, case when q1 > 0 then generate_series(1,3) else 0...
236 HINT: You might be able to move the set-returning function into a LATERAL FROM item.
237 SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl;
238 ERROR: set-returning functions are not allowed in COALESCE
239 LINE 1: SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl;
241 HINT: You might be able to move the set-returning function into a LATERAL FROM item.
242 -- SRFs are not allowed in aggregate arguments
243 SELECT min(generate_series(1, 3)) FROM few;
244 ERROR: aggregate function calls cannot contain set-returning function calls
245 LINE 1: SELECT min(generate_series(1, 3)) FROM few;
247 HINT: You might be able to move the set-returning function into a LATERAL FROM item.
248 -- ... unless they're within a sub-select
249 SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int);
255 SELECT sum((3 = ANY(SELECT lag(x) over(order by x)
256 FROM generate_series(1,4) x))::int);
262 -- SRFs are not allowed in window function arguments, either
263 SELECT min(generate_series(1, 3)) OVER() FROM few;
264 ERROR: window function calls cannot contain set-returning function calls
265 LINE 1: SELECT min(generate_series(1, 3)) OVER() FROM few;
267 HINT: You might be able to move the set-returning function into a LATERAL FROM item.
268 -- SRFs are normally computed after window functions
269 SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few;
270 id | lag | count | generate_series
271 ----+-----+-------+-----------------
283 -- unless referencing SRFs
284 SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g;
292 -- sorting + grouping
293 SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1;
294 dataa | count | min | max | generate_series
295 -------+-------+-----+-----+-----------------
304 -- grouping sets are a bit special, they produce NULLs in columns not actually NULL
305 set enable_hashagg = false;
306 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab);
307 dataa | b | g | count
308 -------+-----+---+-------
327 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY dataa;
328 dataa | b | g | count
329 -------+-----+---+-------
348 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY g;
349 dataa | b | g | count
350 -------+-----+---+-------
369 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g);
370 dataa | b | g | count
371 -------+-----+---+-------
398 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY dataa;
399 dataa | b | g | count
400 -------+-----+---+-------
427 SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY g;
428 dataa | b | g | count
429 -------+-----+---+-------
456 reset enable_hashagg;
457 -- case with degenerate ORDER BY
458 explain (verbose, costs off)
459 select 'foo' as f, generate_series(1,2) as g from few order by 1;
461 ----------------------------------------------
463 Output: 'foo'::text, generate_series(1, 2)
464 -> Seq Scan on public.few
465 Output: id, dataa, datab
468 select 'foo' as f, generate_series(1,2) as g from few order by 1;
480 CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data;
481 INSERT INTO fewmore VALUES(generate_series(4,5));
482 SELECT * FROM fewmore;
492 -- SRFs are not allowed in UPDATE (they once were, but it was nonsense)
493 UPDATE fewmore SET data = generate_series(4,9);
494 ERROR: set-returning functions are not allowed in UPDATE
495 LINE 1: UPDATE fewmore SET data = generate_series(4,9);
497 -- SRFs are not allowed in RETURNING
498 INSERT INTO fewmore VALUES(1) RETURNING generate_series(1,3);
499 ERROR: set-returning functions are not allowed in RETURNING
500 LINE 1: INSERT INTO fewmore VALUES(1) RETURNING generate_series(1,3)...
502 -- nor standalone VALUES (but surely this is a bug?)
503 VALUES(1, generate_series(1,2));
504 ERROR: set-returning functions are not allowed in VALUES
505 LINE 1: VALUES(1, generate_series(1,2));
507 -- We allow tSRFs that are not at top level
508 SELECT int4mul(generate_series(1,2), 10);
515 SELECT generate_series(1,3) IS DISTINCT FROM 2;
523 -- but SRFs in function RTEs must be at top level (annoying restriction)
524 SELECT * FROM int4mul(generate_series(1,2), 10);
525 ERROR: set-returning functions must appear at top level of FROM
526 LINE 1: SELECT * FROM int4mul(generate_series(1,2), 10);
528 -- DISTINCT ON is evaluated before tSRF evaluation if SRF is not
529 -- referenced either in ORDER BY or in the DISTINCT ON list. The ORDER
530 -- BY reference can be implicitly generated, if there's no other ORDER BY.
531 -- implicit reference (via implicit ORDER) to all columns
532 SELECT DISTINCT ON (a) a, b, generate_series(1,3) g
533 FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b);
541 -- unreferenced in DISTINCT ON or ORDER BY
542 SELECT DISTINCT ON (a) a, b, generate_series(1,3) g
543 FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b)
558 -- referenced in ORDER BY
559 SELECT DISTINCT ON (a) a, b, generate_series(1,3) g
560 FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b)
561 ORDER BY a, b DESC, g DESC;
569 -- referenced in ORDER BY and DISTINCT ON
570 SELECT DISTINCT ON (a, b, g) a, b, generate_series(1,3) g
571 FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b)
572 ORDER BY a, b DESC, g DESC;
595 -- only SRF mentioned in DISTINCT ON
596 SELECT DISTINCT ON (g) a, b, generate_series(1,3) g
597 FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b);
605 -- LIMIT / OFFSET is evaluated after SRF evaluation
606 SELECT a, generate_series(1,2) FROM (VALUES(1),(2),(3)) r(a) LIMIT 2 OFFSET 2;
608 ---+-----------------
613 -- SRFs are not allowed in LIMIT.
614 SELECT 1 LIMIT generate_series(1,3);
615 ERROR: set-returning functions are not allowed in LIMIT
616 LINE 1: SELECT 1 LIMIT generate_series(1,3);
618 -- tSRF in correlated subquery, referencing table outside
619 SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET few.id) FROM few;
627 -- tSRF in correlated subquery, referencing SRF outside
628 SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET g.i) FROM generate_series(0,3) g(i);
637 -- Operators can return sets too
638 CREATE OPERATOR |@| (PROCEDURE = unnest, RIGHTARG = ANYARRAY);
639 SELECT |@|ARRAY[1,2,3];
647 -- Some fun cases involving duplicate SRF calls
648 explain (verbose, costs off)
649 select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1;
651 ------------------------------------------------------------------
653 Output: (generate_series(1, 3)), ((generate_series(1, 3)) + 1)
655 Output: generate_series(1, 3)
659 select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1;
667 explain (verbose, costs off)
668 select generate_series(1,3)+1 order by generate_series(1,3);
670 ------------------------------------------------------------------------
672 Output: (((generate_series(1, 3)) + 1)), (generate_series(1, 3))
673 Sort Key: (generate_series(1, 3))
675 Output: ((generate_series(1, 3)) + 1), (generate_series(1, 3))
677 Output: generate_series(1, 3)
681 select generate_series(1,3)+1 order by generate_series(1,3);
689 -- Check that SRFs of same nesting level run in lockstep
690 explain (verbose, costs off)
691 select generate_series(1,3) as x, generate_series(3,6) + 1 as y;
693 ------------------------------------------------------------------
695 Output: (generate_series(1, 3)), ((generate_series(3, 6)) + 1)
697 Output: generate_series(1, 3), generate_series(3, 6)
701 select generate_series(1,3) as x, generate_series(3,6) + 1 as y;