Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6342d49

Browse files
committed
Fix MakeTransitionCaptureState() to return a consistent result
When an UPDATE trigger referencing a new table and a DELETE triggerreferencing an old table are both present, MakeTransitionCaptureState()returns an inconsistent result for UPDATE commands in its set of flagsand tuplestores holding the TransitionCaptureState for transitiontables.As proved by the test added here, this issue causes a crash in v14 andearlier versions (down to 11, actually, older versions do not supporttriggers on partitioned tables) during cross-partition updates on apartitioned table. v15 and newer versions are safe thanks to7103ebb.This commit fixes the function so that it returns a consistent stateby using portions of the changes made in commit7103ebb for v13 andv14. v15 and newer versions are slightly tweaked to match with theolder versions, mainly for consistency across branches.Author: Kyotaro HoriguchiDiscussion:https://postgr.es/m/20250207.150238.968446820828052276.horikyota.ntt@gmail.comBackpatch-through: 13
1 parentc9a1d21 commit6342d49

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

‎src/backend/commands/trigger.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4964,10 +4964,10 @@ MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType)
49644964

49654965
/* Now build the TransitionCaptureState struct, in caller's context */
49664966
state= (TransitionCaptureState*)palloc0(sizeof(TransitionCaptureState));
4967-
state->tcs_delete_old_table=trigdesc->trig_delete_old_table;
4968-
state->tcs_update_old_table=trigdesc->trig_update_old_table;
4969-
state->tcs_update_new_table=trigdesc->trig_update_new_table;
4970-
state->tcs_insert_new_table=trigdesc->trig_insert_new_table;
4967+
state->tcs_delete_old_table=need_old_del;
4968+
state->tcs_update_old_table=need_old_upd;
4969+
state->tcs_update_new_table=need_new_upd;
4970+
state->tcs_insert_new_table=need_new_ins;
49714971
state->tcs_private=table;
49724972

49734973
returnstate;

‎src/test/regress/expected/triggers.out

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3074,6 +3074,55 @@ drop trigger child_row_trig on child;
30743074
alter table parent attach partition child for values in ('AAA');
30753075
drop table child, parent;
30763076
--
3077+
-- Verify access of transition tables with UPDATE triggers and tuples
3078+
-- moved across partitions.
3079+
--
3080+
create or replace function dump_update_new() returns trigger language plpgsql as
3081+
$$
3082+
begin
3083+
raise notice 'trigger = %, new table = %', TG_NAME,
3084+
(select string_agg(new_table::text, ', ' order by a) from new_table);
3085+
return null;
3086+
end;
3087+
$$;
3088+
create or replace function dump_update_old() returns trigger language plpgsql as
3089+
$$
3090+
begin
3091+
raise notice 'trigger = %, old table = %', TG_NAME,
3092+
(select string_agg(old_table::text, ', ' order by a) from old_table);
3093+
return null;
3094+
end;
3095+
$$;
3096+
create table trans_tab_parent (a text) partition by list (a);
3097+
create table trans_tab_child1 partition of trans_tab_parent for values in ('AAA1', 'AAA2');
3098+
create table trans_tab_child2 partition of trans_tab_parent for values in ('BBB1', 'BBB2');
3099+
create trigger trans_tab_parent_update_trig
3100+
after update on trans_tab_parent referencing old table as old_table
3101+
for each statement execute procedure dump_update_old();
3102+
create trigger trans_tab_parent_insert_trig
3103+
after insert on trans_tab_parent referencing new table as new_table
3104+
for each statement execute procedure dump_insert();
3105+
create trigger trans_tab_parent_delete_trig
3106+
after delete on trans_tab_parent referencing old table as old_table
3107+
for each statement execute procedure dump_delete();
3108+
insert into trans_tab_parent values ('AAA1'), ('BBB1');
3109+
NOTICE: trigger = trans_tab_parent_insert_trig, new table = (AAA1), (BBB1)
3110+
-- should not trigger access to new table when moving across partitions.
3111+
update trans_tab_parent set a = 'BBB2' where a = 'AAA1';
3112+
NOTICE: trigger = trans_tab_parent_update_trig, old table = (AAA1)
3113+
drop trigger trans_tab_parent_update_trig on trans_tab_parent;
3114+
create trigger trans_tab_parent_update_trig
3115+
after update on trans_tab_parent referencing new table as new_table
3116+
for each statement execute procedure dump_update_new();
3117+
-- should not trigger access to old table when moving across partitions.
3118+
update trans_tab_parent set a = 'AAA2' where a = 'BBB1';
3119+
NOTICE: trigger = trans_tab_parent_update_trig, new table = (AAA2)
3120+
delete from trans_tab_parent;
3121+
NOTICE: trigger = trans_tab_parent_delete_trig, old table = (AAA2), (BBB2)
3122+
-- clean up
3123+
drop table trans_tab_parent, trans_tab_child1, trans_tab_child2;
3124+
drop function dump_update_new, dump_update_old;
3125+
--
30773126
-- Verify behavior of statement triggers on (non-partition)
30783127
-- inheritance hierarchy with transition tables; similar to the
30793128
-- partition case, except there is no rerouting on insertion and child

‎src/test/regress/sql/triggers.sql

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,52 @@ alter table parent attach partition child for values in ('AAA');
21872187

21882188
droptable child, parent;
21892189

2190+
--
2191+
-- Verify access of transition tables with UPDATE triggers and tuples
2192+
-- moved across partitions.
2193+
--
2194+
create or replacefunctiondump_update_new() returns trigger language plpgsqlas
2195+
$$
2196+
begin
2197+
raise notice'trigger = %, new table = %', TG_NAME,
2198+
(select string_agg(new_table::text,','order by a)from new_table);
2199+
returnnull;
2200+
end;
2201+
$$;
2202+
create or replacefunctiondump_update_old() returns trigger language plpgsqlas
2203+
$$
2204+
begin
2205+
raise notice'trigger = %, old table = %', TG_NAME,
2206+
(select string_agg(old_table::text,','order by a)from old_table);
2207+
returnnull;
2208+
end;
2209+
$$;
2210+
createtabletrans_tab_parent (atext) partition by list (a);
2211+
createtabletrans_tab_child1 partition of trans_tab_parent forvaluesin ('AAA1','AAA2');
2212+
createtabletrans_tab_child2 partition of trans_tab_parent forvaluesin ('BBB1','BBB2');
2213+
createtriggertrans_tab_parent_update_trig
2214+
afterupdateon trans_tab_parent referencing old tableas old_table
2215+
for each statement execute procedure dump_update_old();
2216+
createtriggertrans_tab_parent_insert_trig
2217+
after inserton trans_tab_parent referencing new tableas new_table
2218+
for each statement execute procedure dump_insert();
2219+
createtriggertrans_tab_parent_delete_trig
2220+
afterdeleteon trans_tab_parent referencing old tableas old_table
2221+
for each statement execute procedure dump_delete();
2222+
insert into trans_tab_parentvalues ('AAA1'), ('BBB1');
2223+
-- should not trigger access to new table when moving across partitions.
2224+
update trans_tab_parentset a='BBB2'where a='AAA1';
2225+
droptrigger trans_tab_parent_update_trigon trans_tab_parent;
2226+
createtriggertrans_tab_parent_update_trig
2227+
afterupdateon trans_tab_parent referencing new tableas new_table
2228+
for each statement execute procedure dump_update_new();
2229+
-- should not trigger access to old table when moving across partitions.
2230+
update trans_tab_parentset a='AAA2'where a='BBB1';
2231+
deletefrom trans_tab_parent;
2232+
-- clean up
2233+
droptable trans_tab_parent, trans_tab_child1, trans_tab_child2;
2234+
dropfunction dump_update_new, dump_update_old;
2235+
21902236
--
21912237
-- Verify behavior of statement triggers on (non-partition)
21922238
-- inheritance hierarchy with transition tables; similar to the

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp