diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3aee2d82ce..0f1a9f0e54 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15915,6 +15915,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) Datum value; bool isnull; List *cols = NIL; + List *trigargs = NIL; MemoryContext oldcxt; /* @@ -15979,11 +15980,31 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) } } + /* Reconstruct trigger arguments list. */ + if (trigForm->tgnargs > 0) + { + char *p; + + value = heap_getattr(tuple, Anum_pg_trigger_tgargs, + RelationGetDescr(pg_trigger), &isnull); + if (isnull) + elog(ERROR, "tgargs is null for trigger \"%s\" in partition \"%s\"", + NameStr(trigForm->tgname), RelationGetRelationName(partition)); + + p = (char *) VARDATA_ANY(DatumGetByteaPP(value)); + + for (int i = 0; i < trigForm->tgnargs; i++) + { + trigargs = lappend(trigargs, makeString(pstrdup(p))); + p += strlen(p) + 1; + } + } + trigStmt = makeNode(CreateTrigStmt); trigStmt->trigname = NameStr(trigForm->tgname); trigStmt->relation = NULL; trigStmt->funcname = NULL; /* passed separately */ - trigStmt->args = NULL; /* passed separately */ + trigStmt->args = trigargs; trigStmt->row = true; trigStmt->timing = trigForm->tgtype & TRIGGER_TYPE_TIMING_MASK; trigStmt->events = trigForm->tgtype & TRIGGER_TYPE_EVENT_MASK; diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 316692b7c2..ee878d70a9 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -1172,7 +1172,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, */ childStmt = (CreateTrigStmt *) copyObject(stmt); childStmt->funcname = NIL; - childStmt->args = NIL; childStmt->whenClause = NULL; /* If there is a WHEN clause, create a modified copy of it */ diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index cd2b550c14..c64151ba09 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -2094,6 +2094,30 @@ NOTICE: trigger zzz on parted_trig_1_1 AFTER INSERT for ROW NOTICE: trigger bbb on parted_trig_2 AFTER INSERT for ROW NOTICE: trigger zzz on parted_trig_2 AFTER INSERT for ROW drop table parted_trig; +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a); +create table parted_trig1 partition of parted_trig for values in (1); +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql; +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1); +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2); +create table parted_trig3 (like parted_trig); +alter table parted_trig attach partition parted_trig3 for values in (3); +insert into parted_trig values (1), (2), (3); +NOTICE: trigger aaa on parted_trig1 AFTER INSERT for ROW args quirky 1 +NOTICE: trigger aaa on parted_trig2 AFTER INSERT for ROW args quirky 1 +NOTICE: trigger aaa on parted_trig3 AFTER INSERT for ROW args quirky 1 +drop table parted_trig; -- test irregular partitions (i.e., different column definitions), -- including that the WHEN clause works create function bark(text) returns bool language plpgsql immutable diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql index 8f833b7d10..4534dc9ebe 100644 --- a/src/test/regress/sql/triggers.sql +++ b/src/test/regress/sql/triggers.sql @@ -1460,6 +1460,29 @@ create trigger qqq after insert on parted_trig_1_1 for each row execute procedur insert into parted_trig values (50), (1500); drop table parted_trig; +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a); +create table parted_trig1 partition of parted_trig for values in (1); +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql; +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1); + +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2); +create table parted_trig3 (like parted_trig); +alter table parted_trig attach partition parted_trig3 for values in (3); +insert into parted_trig values (1), (2), (3); +drop table parted_trig; + -- test irregular partitions (i.e., different column definitions), -- including that the WHEN clause works create function bark(text) returns bool language plpgsql immutable