summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2011-06-07 04:08:31 +0000
committerTom Lane2011-06-07 04:08:31 +0000
commitfc1286d3cb92adad2eae69924bead12cfeea5cc6 (patch)
tree5fa7930bd065c9f6f4f831598465be1f8c6cf8e6 /src/test
parentdccfb72892acabd25568539ec882cc44c57c25bd (diff)
Fix rewriter to cope (more or less) with CTEs in the query being rewritten.
Since the original implementation of CTEs only allowed them in SELECT queries, the rule rewriter did not expect to find any CTEs in statements being rewritten by ON INSERT/UPDATE/DELETE rules. We had dealt with this to some extent but the code was still several bricks shy of a load, as illustrated in bug #6051 from Jehan-Guillaume de Rorthais. In particular, we have to be able to copy CTEs from the original query's cteList into that of a rule action, in case the rule action references the CTE (which it pretty much always will). This also implies we were doing things in the wrong order in RewriteQuery: we have to recursively rewrite the CTE queries before expanding the main query, so that we have the rewritten queries available to copy. There are unpleasant limitations yet to resolve here, but at least we now throw understandable FEATURE_NOT_SUPPORTED errors for them instead of just failing with bizarre implementation-dependent errors. In particular, we can't handle propagating the same CTE into multiple post-rewrite queries (because then the CTE would be evaluated multiple times), and we can't cope with conflicts between CTE names in the original query and in the rule actions.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/with.out40
-rw-r--r--src/test/regress/sql/with.sql23
2 files changed, 63 insertions, 0 deletions
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index b31d58f816f..a1b089921d3 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -1397,6 +1397,46 @@ SELECT * FROM y;
(17 rows)
DROP RULE y_rule ON y;
+-- check merging of outer CTE with CTE in a rule action
+CREATE TEMP TABLE bug6051 AS
+ select i from generate_series(1,3) as t(i);
+SELECT * FROM bug6051;
+ i
+---
+ 1
+ 2
+ 3
+(3 rows)
+
+WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
+INSERT INTO bug6051 SELECT * FROM t1;
+SELECT * FROM bug6051;
+ i
+---
+ 1
+ 2
+ 3
+(3 rows)
+
+CREATE TEMP TABLE bug6051_2 (i int);
+CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD
+ INSERT INTO bug6051_2
+ SELECT NEW.i;
+WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
+INSERT INTO bug6051 SELECT * FROM t1;
+SELECT * FROM bug6051;
+ i
+---
+(0 rows)
+
+SELECT * FROM bug6051_2;
+ i
+---
+ 1
+ 2
+ 3
+(3 rows)
+
-- a truly recursive CTE in the same list
WITH RECURSIVE t(a) AS (
SELECT 0
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index 4f6b5171033..bc340e4543f 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -610,6 +610,29 @@ SELECT * FROM y;
DROP RULE y_rule ON y;
+-- check merging of outer CTE with CTE in a rule action
+CREATE TEMP TABLE bug6051 AS
+ select i from generate_series(1,3) as t(i);
+
+SELECT * FROM bug6051;
+
+WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
+INSERT INTO bug6051 SELECT * FROM t1;
+
+SELECT * FROM bug6051;
+
+CREATE TEMP TABLE bug6051_2 (i int);
+
+CREATE RULE bug6051_ins AS ON INSERT TO bug6051 DO INSTEAD
+ INSERT INTO bug6051_2
+ SELECT NEW.i;
+
+WITH t1 AS ( DELETE FROM bug6051 RETURNING * )
+INSERT INTO bug6051 SELECT * FROM t1;
+
+SELECT * FROM bug6051;
+SELECT * FROM bug6051_2;
+
-- a truly recursive CTE in the same list
WITH RECURSIVE t(a) AS (
SELECT 0