diff options
| author | Tom Lane | 2010-10-15 23:53:59 +0000 |
|---|---|---|
| committer | Tom Lane | 2010-10-15 23:55:25 +0000 |
| commit | 07f1264dda0e776a7e329b091c127059bce8cc54 (patch) | |
| tree | c77493be3b7c010de069a431035b80db720b0969 /src/test | |
| parent | 6ab42ae36713b1e6f961c37e22f99d3e6267523b (diff) | |
Allow WITH clauses to be attached to INSERT, UPDATE, DELETE statements.
This is not the hoped-for facility of using INSERT/UPDATE/DELETE inside
a WITH, but rather the other way around. It seems useful in its own
right anyway.
Note: catversion bumped because, although the contents of stored rules
might look compatible, there's actually a subtle semantic change.
A single Query containing a WITH and INSERT...VALUES now represents
writing the WITH before the INSERT, not before the VALUES. While it's
not clear that that matters to anyone, it seems like a good idea to
have it cited in the git history for catversion.h.
Original patch by Marko Tiikkaja, with updating and cleanup by
Hitoshi Harada.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/with.out | 133 | ||||
| -rw-r--r-- | src/test/regress/sql/with.sql | 38 |
2 files changed, 171 insertions, 0 deletions
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out index e46ed78ae69..93b67e3b74d 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -738,6 +738,134 @@ WITH RECURSIVE (54 rows) -- +-- Test WITH attached to a DML statement +-- +CREATE TEMPORARY TABLE y (a INTEGER); +INSERT INTO y SELECT generate_series(1, 10); +WITH t AS ( + SELECT a FROM y +) +INSERT INTO y +SELECT a+20 FROM t RETURNING *; + a +---- + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 +(10 rows) + +SELECT * FROM y; + a +---- + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 +(20 rows) + +WITH t AS ( + SELECT a FROM y +) +UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a; + a +---- + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +(10 rows) + +SELECT * FROM y; + a +---- + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +(20 rows) + +WITH RECURSIVE t(a) AS ( + SELECT 11 + UNION ALL + SELECT a+1 FROM t WHERE a < 50 +) +DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a; + a +---- + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +(10 rows) + +SELECT * FROM y; + a +---- + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +(10 rows) + +DROP TABLE y; +-- -- error cases -- -- INTERSECT @@ -912,6 +1040,11 @@ ERROR: recursive query "foo" column 1 has type numeric(3,0) in non-recursive te LINE 2: (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i) ^ HINT: Cast the output of the non-recursive term to the correct type. +-- disallow OLD/NEW reference in CTE +CREATE TEMPORARY TABLE x (n integer); +CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD + WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t; +ERROR: cannot refer to OLD within WITH query -- -- test for bug #4902 -- diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index 2cbaa42492f..1878eb65b23 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -339,6 +339,39 @@ WITH RECURSIVE SELECT * FROM z; -- +-- Test WITH attached to a DML statement +-- + +CREATE TEMPORARY TABLE y (a INTEGER); +INSERT INTO y SELECT generate_series(1, 10); + +WITH t AS ( + SELECT a FROM y +) +INSERT INTO y +SELECT a+20 FROM t RETURNING *; + +SELECT * FROM y; + +WITH t AS ( + SELECT a FROM y +) +UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a; + +SELECT * FROM y; + +WITH RECURSIVE t(a) AS ( + SELECT 11 + UNION ALL + SELECT a+1 FROM t WHERE a < 50 +) +DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a; + +SELECT * FROM y; + +DROP TABLE y; + +-- -- error cases -- @@ -470,6 +503,11 @@ WITH RECURSIVE foo(i) AS SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10) SELECT * FROM foo; +-- disallow OLD/NEW reference in CTE +CREATE TEMPORARY TABLE x (n integer); +CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD + WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t; + -- -- test for bug #4902 -- |
