Thread

  1. [PATCH 1/2] Add test for a crash bug

    Kyotaro Horiguchi <horikyota.ntt@gmail.com> — 2025-02-04T06:14:27Z

    ---
     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"