summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2023-02-17 21:40:34 +0000
committerTom Lane2023-02-17 21:40:34 +0000
commit393430f57544dfd550135e0191cc91139926b682 (patch)
tree7ab03d4fa7ee463c00003501f5b6558b789b214f /src/test
parent881a91781f49b6116ee6ce49b5bcc03da7200423 (diff)
Print the correct aliases for DML target tables in ruleutils.
ruleutils.c blindly printed the user-given alias (or nothing if there hadn't been one) for the target table of INSERT/UPDATE/DELETE queries. That works a large percentage of the time, but not always: for queries appearing in WITH, it's possible that we chose a different alias to avoid conflict with outer-scope names. Since the chosen alias would be used in any Var references to the target table, this'd lead to an inconsistent printout with consequences such as dump/restore failures. The correct logic for printing (or not) a relation alias was embedded in get_from_clause_item. Factor it out to a separate function so that we don't need a jointree node to use it. (Only a limited part of that function can be reached from these new call sites, but this seems like the cleanest non-duplicative factorization.) In passing, I got rid of a redundant "\d+ rules_src" step in rules.sql. Initial report from Jonathan Katz; thanks to Vignesh C for analysis. This has been broken for a long time, so back-patch to all supported branches. Discussion: https://postgr.es/m/e947fa21-24b2-f922-375a-d4f763ef3e4b@postgresql.org Discussion: https://postgr.es/m/CALDaNm1MMntjmT_NJGp-Z=xbF02qHGAyuSHfYHias3TqQbPF2w@mail.gmail.com
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/rules.out47
-rw-r--r--src/test/regress/sql/rules.sql13
2 files changed, 42 insertions, 18 deletions
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 174b725fff..a3a5a62329 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2998,28 +2998,21 @@ select * from rules_log;
(16 rows)
create rule r4 as on delete to rules_src do notify rules_src_deletion;
-\d+ rules_src
- Table "public.rules_src"
- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
---------+---------+-----------+----------+---------+---------+--------------+-------------
- f1 | integer | | | | plain | |
- f2 | integer | | | 0 | plain | |
-Rules:
- r1 AS
- ON UPDATE TO rules_src DO INSERT INTO rules_log (f1, f2, tag, id) VALUES (old.f1,old.f2,'old'::text,DEFAULT), (new.f1,new.f2,'new'::text,DEFAULT)
- r2 AS
- ON UPDATE TO rules_src DO VALUES (old.f1,old.f2,'old'::text), (new.f1,new.f2,'new'::text)
- r3 AS
- ON INSERT TO rules_src DO INSERT INTO rules_log (f1, f2, tag, id) VALUES (NULL::integer,NULL::integer,'-'::text,DEFAULT), (new.f1,new.f2,'new'::text,DEFAULT)
- r4 AS
- ON DELETE TO rules_src DO
- NOTIFY rules_src_deletion
-
--
-- Ensure an aliased target relation for insert is correctly deparsed.
--
create rule r5 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2;
create rule r6 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1;
+--
+-- Check deparse disambiguation of INSERT/UPDATE/DELETE targets.
+--
+create rule r7 as on delete to rules_src do instead
+ with wins as (insert into int4_tbl as trgt values (0) returning *),
+ wupd as (update int4_tbl trgt set f1 = f1+1 returning *),
+ wdel as (delete from int4_tbl trgt where f1 = 0 returning *)
+ insert into rules_log AS trgt select old.* from wins, wupd, wdel
+ returning trgt.f1, trgt.f2;
+-- check display of all rules added above
\d+ rules_src
Table "public.rules_src"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
@@ -3044,6 +3037,26 @@ Rules:
r6 AS
ON UPDATE TO rules_src DO INSTEAD UPDATE rules_log trgt SET tag = 'updated'::text
WHERE trgt.f1 = new.f1
+ r7 AS
+ ON DELETE TO rules_src DO INSTEAD WITH wins AS (
+ INSERT INTO int4_tbl AS trgt_1 (f1)
+ VALUES (0)
+ RETURNING trgt_1.f1
+ ), wupd AS (
+ UPDATE int4_tbl trgt_1 SET f1 = trgt_1.f1 + 1
+ RETURNING trgt_1.f1
+ ), wdel AS (
+ DELETE FROM int4_tbl trgt_1
+ WHERE trgt_1.f1 = 0
+ RETURNING trgt_1.f1
+ )
+ INSERT INTO rules_log AS trgt (f1, f2) SELECT old.f1,
+ old.f2
+ FROM wins,
+ wupd,
+ wdel
+ RETURNING trgt.f1,
+ trgt.f2
--
-- Also check multiassignment deparsing.
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
index 1f858129b8..ac1a4ce554 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -1015,13 +1015,24 @@ insert into rules_src values(22,23), (33,default);
select * from rules_src;
select * from rules_log;
create rule r4 as on delete to rules_src do notify rules_src_deletion;
-\d+ rules_src
--
-- Ensure an aliased target relation for insert is correctly deparsed.
--
create rule r5 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2;
create rule r6 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1;
+
+--
+-- Check deparse disambiguation of INSERT/UPDATE/DELETE targets.
+--
+create rule r7 as on delete to rules_src do instead
+ with wins as (insert into int4_tbl as trgt values (0) returning *),
+ wupd as (update int4_tbl trgt set f1 = f1+1 returning *),
+ wdel as (delete from int4_tbl trgt where f1 = 0 returning *)
+ insert into rules_log AS trgt select old.* from wins, wupd, wdel
+ returning trgt.f1, trgt.f2;
+
+-- check display of all rules added above
\d+ rules_src
--