[PATCH 1/2] Add test for a crash bug
Kyotaro Horiguchi <horikyota.ntt@gmail.com>
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
To:
Date: 2025-02-04T06:14:27Z
Lists: pgsql-hackers
---
src/test/regress/expected/triggers.out | 48 +++++++++++++++++++++++++
src/test/regress/sql/triggers.sql | 50 ++++++++++++++++++++++++++
2 files changed, 98 insertions(+)
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index d3e02ca63b3..5aed966eac3 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -2957,6 +2957,54 @@ drop trigger child_row_trig on child;
alter table parent attach partition child for values in ('AAA');
drop table child, parent;
--
+-- Verify that UPDATE triggers do not access incorrect transition
+-- tables (which leads to a crash) due to other types of triggers.
+--
+create or replace function dump_update_new() returns trigger language plpgsql as
+$$
+ begin
+ raise notice 'trigger = %, new table = %',
+ TG_NAME,
+ (select string_agg(new_table::text, ', ' order by a) from new_table);
+ return null;
+ end;
+$$;
+create or replace function dump_update_old() returns trigger language plpgsql as
+$$
+ begin
+ raise notice 'trigger = %, old table = %',
+ TG_NAME,
+ (select string_agg(old_table::text, ', ' order by a) from old_table);
+ return null;
+ end;
+$$;
+create table parent (a text) partition by list (a);
+create table child1 partition of parent for values in ('AAA');
+create table child2 partition of parent for values in ('BBB');
+create trigger parent_update_trig
+ after update on parent referencing old table as old_table
+ for each statement execute procedure dump_update_old();
+create trigger parent_insert_trig
+ after insert on parent referencing new table as new_table
+ for each statement execute procedure dump_insert();
+create trigger parent_delete_trig
+ after delete on parent referencing old table as old_table
+ for each statement execute procedure dump_delete();
+insert into parent values ('AAA');
+NOTICE: trigger = parent_insert_trig, new table = (AAA)
+update parent set a = 'BBB' where a = 'AAA'; -- should not trigger access to new
+NOTICE: trigger = parent_update_trig, old table = (AAA)
+drop trigger parent_update_trig on parent;
+create trigger parent_update_trig
+ after update on parent referencing new table as new_table
+ for each statement execute procedure dump_update_new();
+update parent set a = 'AAA' where a = 'BBB'; -- should not trigger access to old
+NOTICE: trigger = parent_update_trig, new table = (AAA)
+delete from parent;
+NOTICE: trigger = parent_delete_trig, old table = (AAA)
+drop table parent, child1, child2;
+drop function dump_update_new, dump_update_old;
+--
-- Verify behavior of statement triggers on (non-partition)
-- inheritance hierarchy with transition tables; similar to the
-- partition case, except there is no rerouting on insertion and child
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 4cc096265db..3f3e26ee1ee 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -2118,6 +2118,56 @@ alter table parent attach partition child for values in ('AAA');
drop table child, parent;
+--
+-- Verify that UPDATE triggers do not access incorrect transition
+-- tables (which leads to a crash) due to other types of triggers.
+--
+create or replace function dump_update_new() returns trigger language plpgsql as
+$$
+ begin
+ raise notice 'trigger = %, new table = %',
+ TG_NAME,
+ (select string_agg(new_table::text, ', ' order by a) from new_table);
+ return null;
+ end;
+$$;
+
+create or replace function dump_update_old() returns trigger language plpgsql as
+$$
+ begin
+ raise notice 'trigger = %, old table = %',
+ TG_NAME,
+ (select string_agg(old_table::text, ', ' order by a) from old_table);
+ return null;
+ end;
+$$;
+
+create table parent (a text) partition by list (a);
+create table child1 partition of parent for values in ('AAA');
+create table child2 partition of parent for values in ('BBB');
+create trigger parent_update_trig
+ after update on parent referencing old table as old_table
+ for each statement execute procedure dump_update_old();
+create trigger parent_insert_trig
+ after insert on parent referencing new table as new_table
+ for each statement execute procedure dump_insert();
+create trigger parent_delete_trig
+ after delete on parent referencing old table as old_table
+ for each statement execute procedure dump_delete();
+
+insert into parent values ('AAA');
+update parent set a = 'BBB' where a = 'AAA'; -- should not trigger access to new
+
+drop trigger parent_update_trig on parent;
+create trigger parent_update_trig
+ after update on parent referencing new table as new_table
+ for each statement execute procedure dump_update_new();
+update parent set a = 'AAA' where a = 'BBB'; -- should not trigger access to old
+delete from parent;
+
+drop table parent, child1, child2;
+drop function dump_update_new, dump_update_old;
+
--
-- Verify behavior of statement triggers on (non-partition)
-- inheritance hierarchy with transition tables; similar to the
--
2.43.5
----Next_Part(Fri_Feb__7_15_02_38_2025_090)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0002-Fix-MakeTransitionCaptureState-to-return-a-consisten_11-14.patch"