1--
2-- Tests for common table expressions (WITH query, ... SELECT ...)
3--
4
5-- Basic WITH
6WITH q1(x,y) AS (SELECT 1,2)
7SELECT * FROM q1, q1 AS q2;
8
9-- Multiple uses are evaluated only once
10SELECT count(*) FROM (
11  WITH q1(x) AS (SELECT random() FROM generate_series(1, 5))
12    SELECT * FROM q1
13  UNION
14    SELECT * FROM q1
15) ss;
16
17-- WITH RECURSIVE
18
19-- sum of 1..100
20WITH RECURSIVE t(n) AS (
21    VALUES (1)
22UNION ALL
23    SELECT n+1 FROM t WHERE n < 100
24)
25SELECT sum(n) FROM t;
26
27WITH RECURSIVE t(n) AS (
28    SELECT (VALUES(1))
29UNION ALL
30    SELECT n+1 FROM t WHERE n < 5
31)
32SELECT * FROM t;
33
34-- recursive view
35CREATE RECURSIVE VIEW nums (n) AS
36    VALUES (1)
37UNION ALL
38    SELECT n+1 FROM nums WHERE n < 5;
39
40SELECT * FROM nums;
41
42CREATE OR REPLACE RECURSIVE VIEW nums (n) AS
43    VALUES (1)
44UNION ALL
45    SELECT n+1 FROM nums WHERE n < 6;
46
47SELECT * FROM nums;
48
49-- This is an infinite loop with UNION ALL, but not with UNION
50WITH RECURSIVE t(n) AS (
51    SELECT 1
52UNION
53    SELECT 10-n FROM t)
54SELECT * FROM t;
55
56-- This'd be an infinite loop, but outside query reads only as much as needed
57WITH RECURSIVE t(n) AS (
58    VALUES (1)
59UNION ALL
60    SELECT n+1 FROM t)
61SELECT * FROM t LIMIT 10;
62
63-- UNION case should have same property
64WITH RECURSIVE t(n) AS (
65    SELECT 1
66UNION
67    SELECT n+1 FROM t)
68SELECT * FROM t LIMIT 10;
69
70-- Test behavior with an unknown-type literal in the WITH
71WITH q AS (SELECT 'foo' AS x)
72SELECT x, x IS OF (text) AS is_text FROM q;
73
74WITH RECURSIVE t(n) AS (
75    SELECT 'foo'
76UNION ALL
77    SELECT n || ' bar' FROM t WHERE length(n) < 20
78)
79SELECT n, n IS OF (text) AS is_text FROM t;
80
81-- In a perfect world, this would work and resolve the literal as int ...
82-- but for now, we have to be content with resolving to text too soon.
83WITH RECURSIVE t(n) AS (
84    SELECT '7'
85UNION ALL
86    SELECT n+1 FROM t WHERE n < 10
87)
88SELECT n, n IS OF (int) AS is_int FROM t;
89
90--
91-- Some examples with a tree
92--
93-- department structure represented here is as follows:
94--
95-- ROOT-+->A-+->B-+->C
96--      |         |
97--      |         +->D-+->F
98--      +->E-+->G
99
100CREATE TEMP TABLE department (
101	id INTEGER PRIMARY KEY,  -- department ID
102	parent_department INTEGER REFERENCES department, -- upper department ID
103	name TEXT -- department name
104);
105
106INSERT INTO department VALUES (0, NULL, 'ROOT');
107INSERT INTO department VALUES (1, 0, 'A');
108INSERT INTO department VALUES (2, 1, 'B');
109INSERT INTO department VALUES (3, 2, 'C');
110INSERT INTO department VALUES (4, 2, 'D');
111INSERT INTO department VALUES (5, 0, 'E');
112INSERT INTO department VALUES (6, 4, 'F');
113INSERT INTO department VALUES (7, 5, 'G');
114
115
116-- extract all departments under 'A'. Result should be A, B, C, D and F
117WITH RECURSIVE subdepartment AS
118(
119	-- non recursive term
120	SELECT name as root_name, * FROM department WHERE name = 'A'
121
122	UNION ALL
123
124	-- recursive term
125	SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd
126		WHERE d.parent_department = sd.id
127)
128SELECT * FROM subdepartment ORDER BY name;
129
130-- extract all departments under 'A' with "level" number
131WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
132(
133	-- non recursive term
134	SELECT 1, * FROM department WHERE name = 'A'
135
136	UNION ALL
137
138	-- recursive term
139	SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
140		WHERE d.parent_department = sd.id
141)
142SELECT * FROM subdepartment ORDER BY name;
143
144-- extract all departments under 'A' with "level" number.
145-- Only shows level 2 or more
146WITH RECURSIVE subdepartment(level, id, parent_department, name) AS
147(
148	-- non recursive term
149	SELECT 1, * FROM department WHERE name = 'A'
150
151	UNION ALL
152
153	-- recursive term
154	SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd
155		WHERE d.parent_department = sd.id
156)
157SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name;
158
159-- "RECURSIVE" is ignored if the query has no self-reference
160WITH RECURSIVE subdepartment AS
161(
162	-- note lack of recursive UNION structure
163	SELECT * FROM department WHERE name = 'A'
164)
165SELECT * FROM subdepartment ORDER BY name;
166
167-- inside subqueries
168SELECT count(*) FROM (
169    WITH RECURSIVE t(n) AS (
170        SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500
171    )
172    SELECT * FROM t) AS t WHERE n < (
173        SELECT count(*) FROM (
174            WITH RECURSIVE t(n) AS (
175                   SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100
176                )
177            SELECT * FROM t WHERE n < 50000
178         ) AS t WHERE n < 100);
179
180-- use same CTE twice at different subquery levels
181WITH q1(x,y) AS (
182    SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred
183  )
184SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub);
185
186-- via a VIEW
187CREATE TEMPORARY VIEW vsubdepartment AS
188	WITH RECURSIVE subdepartment AS
189	(
190		 -- non recursive term
191		SELECT * FROM department WHERE name = 'A'
192		UNION ALL
193		-- recursive term
194		SELECT d.* FROM department AS d, subdepartment AS sd
195			WHERE d.parent_department = sd.id
196	)
197	SELECT * FROM subdepartment;
198
199SELECT * FROM vsubdepartment ORDER BY name;
200
201-- Check reverse listing
202SELECT pg_get_viewdef('vsubdepartment'::regclass);
203SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
204
205-- Another reverse-listing example
206CREATE VIEW sums_1_100 AS
207WITH RECURSIVE t(n) AS (
208    VALUES (1)
209UNION ALL
210    SELECT n+1 FROM t WHERE n < 100
211)
212SELECT sum(n) FROM t;
213
214\d+ sums_1_100
215
216-- corner case in which sub-WITH gets initialized first
217with recursive q as (
218      select * from department
219    union all
220      (with x as (select * from q)
221       select * from x)
222    )
223select * from q limit 24;
224
225with recursive q as (
226      select * from department
227    union all
228      (with recursive x as (
229           select * from department
230         union all
231           (select * from q union all select * from x)
232        )
233       select * from x)
234    )
235select * from q limit 32;
236
237-- recursive term has sub-UNION
238WITH RECURSIVE t(i,j) AS (
239	VALUES (1,2)
240	UNION ALL
241	SELECT t2.i, t.j+1 FROM
242		(SELECT 2 AS i UNION ALL SELECT 3 AS i) AS t2
243		JOIN t ON (t2.i = t.i+1))
244
245	SELECT * FROM t;
246
247--
248-- different tree example
249--
250CREATE TEMPORARY TABLE tree(
251    id INTEGER PRIMARY KEY,
252    parent_id INTEGER REFERENCES tree(id)
253);
254
255INSERT INTO tree
256VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3),
257       (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11);
258
259--
260-- get all paths from "second level" nodes to leaf nodes
261--
262WITH RECURSIVE t(id, path) AS (
263    VALUES(1,ARRAY[]::integer[])
264UNION ALL
265    SELECT tree.id, t.path || tree.id
266    FROM tree JOIN t ON (tree.parent_id = t.id)
267)
268SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON
269	(t1.path[1] = t2.path[1] AND
270	array_upper(t1.path,1) = 1 AND
271	array_upper(t2.path,1) > 1)
272	ORDER BY t1.id, t2.id;
273
274-- just count 'em
275WITH RECURSIVE t(id, path) AS (
276    VALUES(1,ARRAY[]::integer[])
277UNION ALL
278    SELECT tree.id, t.path || tree.id
279    FROM tree JOIN t ON (tree.parent_id = t.id)
280)
281SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON
282	(t1.path[1] = t2.path[1] AND
283	array_upper(t1.path,1) = 1 AND
284	array_upper(t2.path,1) > 1)
285	GROUP BY t1.id
286	ORDER BY t1.id;
287
288-- this variant tickled a whole-row-variable bug in 8.4devel
289WITH RECURSIVE t(id, path) AS (
290    VALUES(1,ARRAY[]::integer[])
291UNION ALL
292    SELECT tree.id, t.path || tree.id
293    FROM tree JOIN t ON (tree.parent_id = t.id)
294)
295SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON
296(t1.id=t2.id);
297
298--
299-- test cycle detection
300--
301create temp table graph( f int, t int, label text );
302
303insert into graph values
304	(1, 2, 'arc 1 -> 2'),
305	(1, 3, 'arc 1 -> 3'),
306	(2, 3, 'arc 2 -> 3'),
307	(1, 4, 'arc 1 -> 4'),
308	(4, 5, 'arc 4 -> 5'),
309	(5, 1, 'arc 5 -> 1');
310
311with recursive search_graph(f, t, label, path, cycle) as (
312	select *, array[row(g.f, g.t)], false from graph g
313	union all
314	select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
315	from graph g, search_graph sg
316	where g.f = sg.t and not cycle
317)
318select * from search_graph;
319
320-- ordering by the path column has same effect as SEARCH DEPTH FIRST
321with recursive search_graph(f, t, label, path, cycle) as (
322	select *, array[row(g.f, g.t)], false from graph g
323	union all
324	select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
325	from graph g, search_graph sg
326	where g.f = sg.t and not cycle
327)
328select * from search_graph order by path;
329
330--
331-- test multiple WITH queries
332--
333WITH RECURSIVE
334  y (id) AS (VALUES (1)),
335  x (id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5)
336SELECT * FROM x;
337
338-- forward reference OK
339WITH RECURSIVE
340    x(id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5),
341    y(id) AS (values (1))
342 SELECT * FROM x;
343
344WITH RECURSIVE
345   x(id) AS
346     (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
347   y(id) AS
348     (VALUES (1) UNION ALL SELECT id+1 FROM y WHERE id < 10)
349 SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
350
351WITH RECURSIVE
352   x(id) AS
353     (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5),
354   y(id) AS
355     (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 10)
356 SELECT y.*, x.* FROM y LEFT JOIN x USING (id);
357
358WITH RECURSIVE
359   x(id) AS
360     (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
361   y(id) AS
362     (SELECT * FROM x UNION ALL SELECT * FROM x),
363   z(id) AS
364     (SELECT * FROM x UNION ALL SELECT id+1 FROM z WHERE id < 10)
365 SELECT * FROM z;
366
367WITH RECURSIVE
368   x(id) AS
369     (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ),
370   y(id) AS
371     (SELECT * FROM x UNION ALL SELECT * FROM x),
372   z(id) AS
373     (SELECT * FROM y UNION ALL SELECT id+1 FROM z WHERE id < 10)
374 SELECT * FROM z;
375
376--
377-- Test WITH attached to a data-modifying statement
378--
379
380CREATE TEMPORARY TABLE y (a INTEGER);
381INSERT INTO y SELECT generate_series(1, 10);
382
383WITH t AS (
384	SELECT a FROM y
385)
386INSERT INTO y
387SELECT a+20 FROM t RETURNING *;
388
389SELECT * FROM y;
390
391WITH t AS (
392	SELECT a FROM y
393)
394UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a;
395
396SELECT * FROM y;
397
398WITH RECURSIVE t(a) AS (
399	SELECT 11
400	UNION ALL
401	SELECT a+1 FROM t WHERE a < 50
402)
403DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a;
404
405SELECT * FROM y;
406
407DROP TABLE y;
408
409--
410-- error cases
411--
412
413-- INTERSECT
414WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
415	SELECT * FROM x;
416
417WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x)
418	SELECT * FROM x;
419
420-- EXCEPT
421WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x)
422	SELECT * FROM x;
423
424WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x)
425	SELECT * FROM x;
426
427-- no non-recursive term
428WITH RECURSIVE x(n) AS (SELECT n FROM x)
429	SELECT * FROM x;
430
431-- recursive term in the left hand side (strictly speaking, should allow this)
432WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
433	SELECT * FROM x;
434
435CREATE TEMPORARY TABLE y (a INTEGER);
436INSERT INTO y SELECT generate_series(1, 10);
437
438-- LEFT JOIN
439
440WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
441	UNION ALL
442	SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10)
443SELECT * FROM x;
444
445-- RIGHT JOIN
446WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
447	UNION ALL
448	SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10)
449SELECT * FROM x;
450
451-- FULL JOIN
452WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1
453	UNION ALL
454	SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10)
455SELECT * FROM x;
456
457-- subquery
458WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x
459                          WHERE n IN (SELECT * FROM x))
460  SELECT * FROM x;
461
462-- aggregate functions
463WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x)
464  SELECT * FROM x;
465
466WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x)
467  SELECT * FROM x;
468
469-- ORDER BY
470WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1)
471  SELECT * FROM x;
472
473-- LIMIT/OFFSET
474WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1)
475  SELECT * FROM x;
476
477-- FOR UPDATE
478WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE)
479  SELECT * FROM x;
480
481-- target list has a recursive query name
482WITH RECURSIVE x(id) AS (values (1)
483    UNION ALL
484    SELECT (SELECT * FROM x) FROM x WHERE id < 5
485) SELECT * FROM x;
486
487-- mutual recursive query (not implemented)
488WITH RECURSIVE
489  x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5),
490  y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5)
491SELECT * FROM x;
492
493-- non-linear recursion is not allowed
494WITH RECURSIVE foo(i) AS
495    (values (1)
496    UNION ALL
497       (SELECT i+1 FROM foo WHERE i < 10
498          UNION ALL
499       SELECT i+1 FROM foo WHERE i < 5)
500) SELECT * FROM foo;
501
502WITH RECURSIVE foo(i) AS
503    (values (1)
504    UNION ALL
505	   SELECT * FROM
506       (SELECT i+1 FROM foo WHERE i < 10
507          UNION ALL
508       SELECT i+1 FROM foo WHERE i < 5) AS t
509) SELECT * FROM foo;
510
511WITH RECURSIVE foo(i) AS
512    (values (1)
513    UNION ALL
514       (SELECT i+1 FROM foo WHERE i < 10
515          EXCEPT
516       SELECT i+1 FROM foo WHERE i < 5)
517) SELECT * FROM foo;
518
519WITH RECURSIVE foo(i) AS
520    (values (1)
521    UNION ALL
522       (SELECT i+1 FROM foo WHERE i < 10
523          INTERSECT
524       SELECT i+1 FROM foo WHERE i < 5)
525) SELECT * FROM foo;
526
527-- Wrong type induced from non-recursive term
528WITH RECURSIVE foo(i) AS
529   (SELECT i FROM (VALUES(1),(2)) t(i)
530   UNION ALL
531   SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
532SELECT * FROM foo;
533
534-- rejects different typmod, too (should we allow this?)
535WITH RECURSIVE foo(i) AS
536   (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i)
537   UNION ALL
538   SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10)
539SELECT * FROM foo;
540
541-- disallow OLD/NEW reference in CTE
542CREATE TEMPORARY TABLE x (n integer);
543CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD
544    WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t;
545
546--
547-- test for bug #4902
548--
549with cte(foo) as ( values(42) ) values((select foo from cte));
550with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q;
551
552-- test CTE referencing an outer-level variable (to see that changed-parameter
553-- signaling still works properly after fixing this bug)
554select ( with cte(foo) as ( values(f1) )
555         select (select foo from cte) )
556from int4_tbl;
557
558select ( with cte(foo) as ( values(f1) )
559          values((select foo from cte)) )
560from int4_tbl;
561
562--
563-- test for nested-recursive-WITH bug
564--
565WITH RECURSIVE t(j) AS (
566    WITH RECURSIVE s(i) AS (
567        VALUES (1)
568        UNION ALL
569        SELECT i+1 FROM s WHERE i < 10
570    )
571    SELECT i FROM s
572    UNION ALL
573    SELECT j+1 FROM t WHERE j < 10
574)
575SELECT * FROM t;
576
577--
578-- test WITH attached to intermediate-level set operation
579--
580
581WITH outermost(x) AS (
582  SELECT 1
583  UNION (WITH innermost as (SELECT 2)
584         SELECT * FROM innermost
585         UNION SELECT 3)
586)
587SELECT * FROM outermost ORDER BY 1;
588
589WITH outermost(x) AS (
590  SELECT 1
591  UNION (WITH innermost as (SELECT 2)
592         SELECT * FROM outermost  -- fail
593         UNION SELECT * FROM innermost)
594)
595SELECT * FROM outermost ORDER BY 1;
596
597WITH RECURSIVE outermost(x) AS (
598  SELECT 1
599  UNION (WITH innermost as (SELECT 2)
600         SELECT * FROM outermost
601         UNION SELECT * FROM innermost)
602)
603SELECT * FROM outermost ORDER BY 1;
604
605WITH RECURSIVE outermost(x) AS (
606  WITH innermost as (SELECT 2 FROM outermost) -- fail
607    SELECT * FROM innermost
608    UNION SELECT * from outermost
609)
610SELECT * FROM outermost ORDER BY 1;
611
612--
613-- This test will fail with the old implementation of PARAM_EXEC parameter
614-- assignment, because the "q1" Var passed down to A's targetlist subselect
615-- looks exactly like the "A.id" Var passed down to C's subselect, causing
616-- the old code to give them the same runtime PARAM_EXEC slot.  But the
617-- lifespans of the two parameters overlap, thanks to B also reading A.
618--
619
620with
621A as ( select q2 as id, (select q1) as x from int8_tbl ),
622B as ( select id, row_number() over (partition by id) as r from A ),
623C as ( select A.id, array(select B.id from B where B.id = A.id) from A )
624select * from C;
625
626--
627-- Test CTEs read in non-initialization orders
628--
629
630WITH RECURSIVE
631  tab(id_key,link) AS (VALUES (1,17), (2,17), (3,17), (4,17), (6,17), (5,17)),
632  iter (id_key, row_type, link) AS (
633      SELECT 0, 'base', 17
634    UNION ALL (
635      WITH remaining(id_key, row_type, link, min) AS (
636        SELECT tab.id_key, 'true'::text, iter.link, MIN(tab.id_key) OVER ()
637        FROM tab INNER JOIN iter USING (link)
638        WHERE tab.id_key > iter.id_key
639      ),
640      first_remaining AS (
641        SELECT id_key, row_type, link
642        FROM remaining
643        WHERE id_key=min
644      ),
645      effect AS (
646        SELECT tab.id_key, 'new'::text, tab.link
647        FROM first_remaining e INNER JOIN tab ON e.id_key=tab.id_key
648        WHERE e.row_type = 'false'
649      )
650      SELECT * FROM first_remaining
651      UNION ALL SELECT * FROM effect
652    )
653  )
654SELECT * FROM iter;
655
656WITH RECURSIVE
657  tab(id_key,link) AS (VALUES (1,17), (2,17), (3,17), (4,17), (6,17), (5,17)),
658  iter (id_key, row_type, link) AS (
659      SELECT 0, 'base', 17
660    UNION (
661      WITH remaining(id_key, row_type, link, min) AS (
662        SELECT tab.id_key, 'true'::text, iter.link, MIN(tab.id_key) OVER ()
663        FROM tab INNER JOIN iter USING (link)
664        WHERE tab.id_key > iter.id_key
665      ),
666      first_remaining AS (
667        SELECT id_key, row_type, link
668        FROM remaining
669        WHERE id_key=min
670      ),
671      effect AS (
672        SELECT tab.id_key, 'new'::text, tab.link
673        FROM first_remaining e INNER JOIN tab ON e.id_key=tab.id_key
674        WHERE e.row_type = 'false'
675      )
676      SELECT * FROM first_remaining
677      UNION ALL SELECT * FROM effect
678    )
679  )
680SELECT * FROM iter;
681
682--
683-- Data-modifying statements in WITH
684--
685
686-- INSERT ... RETURNING
687WITH t AS (
688    INSERT INTO y
689    VALUES
690        (11),
691        (12),
692        (13),
693        (14),
694        (15),
695        (16),
696        (17),
697        (18),
698        (19),
699        (20)
700    RETURNING *
701)
702SELECT * FROM t;
703
704SELECT * FROM y;
705
706-- UPDATE ... RETURNING
707WITH t AS (
708    UPDATE y
709    SET a=a+1
710    RETURNING *
711)
712SELECT * FROM t;
713
714SELECT * FROM y;
715
716-- DELETE ... RETURNING
717WITH t AS (
718    DELETE FROM y
719    WHERE a <= 10
720    RETURNING *
721)
722SELECT * FROM t;
723
724SELECT * FROM y;
725
726-- forward reference
727WITH RECURSIVE t AS (
728	INSERT INTO y
729		SELECT a+5 FROM t2 WHERE a > 5
730	RETURNING *
731), t2 AS (
732	UPDATE y SET a=a-11 RETURNING *
733)
734SELECT * FROM t
735UNION ALL
736SELECT * FROM t2;
737
738SELECT * FROM y;
739
740-- unconditional DO INSTEAD rule
741CREATE RULE y_rule AS ON DELETE TO y DO INSTEAD
742  INSERT INTO y VALUES(42) RETURNING *;
743
744WITH t AS (
745	DELETE FROM y RETURNING *
746)
747SELECT * FROM t;
748
749SELECT * FROM y;
750
751DROP RULE y_rule ON y;
752
753-- check merging of outer CTE with CTE in a rule action
754CREATE TEMP TABLE bug6051 AS
755  select i from generate_series(1,3) as t(i);
756
757SELECT * FROM bug6051;
758
759WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
760INSERT INTO bug6051 SELECT * FROM t1;
761
762SELECT * FROM bug6051;
763
764CREATE TEMP TABLE bug6051_2 (i int);
765
766CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD
767 INSERT INTO bug6051_2
768 SELECT NEW.i;
769
770WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
771INSERT INTO bug6051 SELECT * FROM t1;
772
773SELECT * FROM bug6051;
774SELECT * FROM bug6051_2;
775
776-- a truly recursive CTE in the same list
777WITH RECURSIVE t(a) AS (
778	SELECT 0
779		UNION ALL
780	SELECT a+1 FROM t WHERE a+1 < 5
781), t2 as (
782	INSERT INTO y
783		SELECT * FROM t RETURNING *
784)
785SELECT * FROM t2 JOIN y USING (a) ORDER BY a;
786
787SELECT * FROM y;
788
789-- data-modifying WITH in a modifying statement
790WITH t AS (
791    DELETE FROM y
792    WHERE a <= 10
793    RETURNING *
794)
795INSERT INTO y SELECT -a FROM t RETURNING *;
796
797SELECT * FROM y;
798
799-- check that WITH query is run to completion even if outer query isn't
800WITH t AS (
801    UPDATE y SET a = a * 100 RETURNING *
802)
803SELECT * FROM t LIMIT 10;
804
805SELECT * FROM y;
806
807-- data-modifying WITH containing INSERT...ON CONFLICT DO UPDATE
808CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i;
809ALTER TABLE withz ADD UNIQUE (k);
810
811WITH t AS (
812    INSERT INTO withz SELECT i, 'insert'
813    FROM generate_series(0, 16) i
814    ON CONFLICT (k) DO UPDATE SET v = withz.v || ', now update'
815    RETURNING *
816)
817SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k;
818
819-- Test EXCLUDED.* reference within CTE
820WITH aa AS (
821    INSERT INTO withz VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v
822    WHERE withz.k != EXCLUDED.k
823    RETURNING *
824)
825SELECT * FROM aa;
826
827-- New query/snapshot demonstrates side-effects of previous query.
828SELECT * FROM withz ORDER BY k;
829
830--
831-- Ensure subqueries within the update clause work, even if they
832-- reference outside values
833--
834WITH aa AS (SELECT 1 a, 2 b)
835INSERT INTO withz VALUES(1, 'insert')
836ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
837WITH aa AS (SELECT 1 a, 2 b)
838INSERT INTO withz VALUES(1, 'insert')
839ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE withz.k = (SELECT a FROM aa);
840WITH aa AS (SELECT 1 a, 2 b)
841INSERT INTO withz VALUES(1, 'insert')
842ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
843WITH aa AS (SELECT 'a' a, 'b' b UNION ALL SELECT 'a' a, 'b' b)
844INSERT INTO withz VALUES(1, 'insert')
845ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 'a' LIMIT 1);
846WITH aa AS (SELECT 1 a, 2 b)
847INSERT INTO withz VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 ))
848ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
849
850-- Update a row more than once, in different parts of a wCTE. That is
851-- an allowed, presumably very rare, edge case, but since it was
852-- broken in the past, having a test seems worthwhile.
853WITH simpletup AS (
854  SELECT 2 k, 'Green' v),
855upsert_cte AS (
856  INSERT INTO withz VALUES(2, 'Blue') ON CONFLICT (k) DO
857    UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = withz.k)
858    RETURNING k, v)
859INSERT INTO withz VALUES(2, 'Red') ON CONFLICT (k) DO
860UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = withz.k)
861RETURNING k, v;
862
863DROP TABLE withz;
864
865-- check that run to completion happens in proper ordering
866
867TRUNCATE TABLE y;
868INSERT INTO y SELECT generate_series(1, 3);
869CREATE TEMPORARY TABLE yy (a INTEGER);
870
871WITH RECURSIVE t1 AS (
872  INSERT INTO y SELECT * FROM y RETURNING *
873), t2 AS (
874  INSERT INTO yy SELECT * FROM t1 RETURNING *
875)
876SELECT 1;
877
878SELECT * FROM y;
879SELECT * FROM yy;
880
881WITH RECURSIVE t1 AS (
882  INSERT INTO yy SELECT * FROM t2 RETURNING *
883), t2 AS (
884  INSERT INTO y SELECT * FROM y RETURNING *
885)
886SELECT 1;
887
888SELECT * FROM y;
889SELECT * FROM yy;
890
891-- triggers
892
893TRUNCATE TABLE y;
894INSERT INTO y SELECT generate_series(1, 10);
895
896CREATE FUNCTION y_trigger() RETURNS trigger AS $$
897begin
898  raise notice 'y_trigger: a = %', new.a;
899  return new;
900end;
901$$ LANGUAGE plpgsql;
902
903CREATE TRIGGER y_trig BEFORE INSERT ON y FOR EACH ROW
904    EXECUTE PROCEDURE y_trigger();
905
906WITH t AS (
907    INSERT INTO y
908    VALUES
909        (21),
910        (22),
911        (23)
912    RETURNING *
913)
914SELECT * FROM t;
915
916SELECT * FROM y;
917
918DROP TRIGGER y_trig ON y;
919
920CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH ROW
921    EXECUTE PROCEDURE y_trigger();
922
923WITH t AS (
924    INSERT INTO y
925    VALUES
926        (31),
927        (32),
928        (33)
929    RETURNING *
930)
931SELECT * FROM t LIMIT 1;
932
933SELECT * FROM y;
934
935DROP TRIGGER y_trig ON y;
936
937CREATE OR REPLACE FUNCTION y_trigger() RETURNS trigger AS $$
938begin
939  raise notice 'y_trigger';
940  return null;
941end;
942$$ LANGUAGE plpgsql;
943
944CREATE TRIGGER y_trig AFTER INSERT ON y FOR EACH STATEMENT
945    EXECUTE PROCEDURE y_trigger();
946
947WITH t AS (
948    INSERT INTO y
949    VALUES
950        (41),
951        (42),
952        (43)
953    RETURNING *
954)
955SELECT * FROM t;
956
957SELECT * FROM y;
958
959DROP TRIGGER y_trig ON y;
960DROP FUNCTION y_trigger();
961
962-- WITH attached to inherited UPDATE or DELETE
963
964CREATE TEMP TABLE parent ( id int, val text );
965CREATE TEMP TABLE child1 ( ) INHERITS ( parent );
966CREATE TEMP TABLE child2 ( ) INHERITS ( parent );
967
968INSERT INTO parent VALUES ( 1, 'p1' );
969INSERT INTO child1 VALUES ( 11, 'c11' ),( 12, 'c12' );
970INSERT INTO child2 VALUES ( 23, 'c21' ),( 24, 'c22' );
971
972WITH rcte AS ( SELECT sum(id) AS totalid FROM parent )
973UPDATE parent SET id = id + totalid FROM rcte;
974
975SELECT * FROM parent;
976
977WITH wcte AS ( INSERT INTO child1 VALUES ( 42, 'new' ) RETURNING id AS newid )
978UPDATE parent SET id = id + newid FROM wcte;
979
980SELECT * FROM parent;
981
982WITH rcte AS ( SELECT max(id) AS maxid FROM parent )
983DELETE FROM parent USING rcte WHERE id = maxid;
984
985SELECT * FROM parent;
986
987WITH wcte AS ( INSERT INTO child2 VALUES ( 42, 'new2' ) RETURNING id AS newid )
988DELETE FROM parent USING wcte WHERE id = newid;
989
990SELECT * FROM parent;
991
992-- check EXPLAIN VERBOSE for a wCTE with RETURNING
993
994EXPLAIN (VERBOSE, COSTS OFF)
995WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 )
996DELETE FROM a USING wcte WHERE aa = q2;
997
998-- error cases
999
1000-- data-modifying WITH tries to use its own output
1001WITH RECURSIVE t AS (
1002	INSERT INTO y
1003		SELECT * FROM t
1004)
1005VALUES(FALSE);
1006
1007-- no RETURNING in a referenced data-modifying WITH
1008WITH t AS (
1009	INSERT INTO y VALUES(0)
1010)
1011SELECT * FROM t;
1012
1013-- data-modifying WITH allowed only at the top level
1014SELECT * FROM (
1015	WITH t AS (UPDATE y SET a=a+1 RETURNING *)
1016	SELECT * FROM t
1017) ss;
1018
1019-- most variants of rules aren't allowed
1020CREATE RULE y_rule AS ON INSERT TO y WHERE a=0 DO INSTEAD DELETE FROM y;
1021WITH t AS (
1022	INSERT INTO y VALUES(0)
1023)
1024VALUES(FALSE);
1025DROP RULE y_rule ON y;
1026
1027-- check that parser lookahead for WITH doesn't cause any odd behavior
1028create table foo (with baz);  -- fail, WITH is a reserved word
1029create table foo (with ordinality);  -- fail, WITH is a reserved word
1030with ordinality as (select 1 as x) select * from ordinality;
1031
1032-- check sane response to attempt to modify CTE relation
1033WITH test AS (SELECT 42) INSERT INTO test VALUES (1);
1034
1035-- check response to attempt to modify table with same name as a CTE (perhaps
1036-- surprisingly it works, because CTEs don't hide tables from data-modifying
1037-- statements)
1038create temp table test (i int);
1039with test as (select 42) insert into test select * from test;
1040select * from test;
1041drop table test;
1042