aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/tablecmds.c5
-rw-r--r--src/backend/commands/trigger.c38
-rw-r--r--src/include/commands/trigger.h3
-rw-r--r--src/test/regress/expected/triggers.out34
-rw-r--r--src/test/regress/sql/triggers.sql15
5 files changed, 82 insertions, 13 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b59cc96719e..ce32c79ae06 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -14768,8 +14768,9 @@ ATExecEnableDisableTrigger(Relation rel, const char *trigname,
char fires_when, bool skip_system, bool recurse,
LOCKMODE lockmode)
{
- EnableDisableTriggerNew(rel, trigname, fires_when, skip_system, recurse,
- lockmode);
+ EnableDisableTriggerNew2(rel, trigname, InvalidOid,
+ fires_when, skip_system, recurse,
+ lockmode);
}
/*
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 36f10824077..d9d9201ac38 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1754,7 +1754,8 @@ renametrig_partition(Relation tgrel, Oid partitionId, Oid parentTriggerOid,
* to change 'tgenabled' field for the specified trigger(s)
*
* rel: relation to process (caller must hold suitable lock on it)
- * tgname: trigger to process, or NULL to scan all triggers
+ * tgname: name of trigger to process, or NULL to scan all triggers
+ * tgparent: if not zero, process only triggers with this tgparentid
* fires_when: new value for tgenabled field. In addition to generic
* enablement/disablement, this also defines when the trigger
* should be fired in session replication roles.
@@ -1766,9 +1767,9 @@ renametrig_partition(Relation tgrel, Oid partitionId, Oid parentTriggerOid,
* system triggers
*/
void
-EnableDisableTriggerNew(Relation rel, const char *tgname,
- char fires_when, bool skip_system, bool recurse,
- LOCKMODE lockmode)
+EnableDisableTriggerNew2(Relation rel, const char *tgname, Oid tgparent,
+ char fires_when, bool skip_system, bool recurse,
+ LOCKMODE lockmode)
{
Relation tgrel;
int nkeys;
@@ -1805,6 +1806,9 @@ EnableDisableTriggerNew(Relation rel, const char *tgname,
{
Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
+ if (OidIsValid(tgparent) && tgparent != oldtrig->tgparentid)
+ continue;
+
if (oldtrig->tgisinternal)
{
/* system trigger ... ok to process? */
@@ -1855,9 +1859,10 @@ EnableDisableTriggerNew(Relation rel, const char *tgname,
Relation part;
part = relation_open(partdesc->oids[i], lockmode);
- EnableDisableTriggerNew(part, NameStr(oldtrig->tgname),
- fires_when, skip_system, recurse,
- lockmode);
+ /* Match on child triggers' tgparentid, not their name */
+ EnableDisableTriggerNew2(part, NULL, oldtrig->oid,
+ fires_when, skip_system, recurse,
+ lockmode);
table_close(part, NoLock); /* keep lock till commit */
}
}
@@ -1886,16 +1891,27 @@ EnableDisableTriggerNew(Relation rel, const char *tgname,
}
/*
- * ABI-compatible wrapper for the above. To keep as close possible to the old
- * behavior, this never recurses. Do not call this function in new code.
+ * ABI-compatible wrappers to emulate old versions of the above function.
+ * Do not call these versions in new code.
*/
void
+EnableDisableTriggerNew(Relation rel, const char *tgname,
+ char fires_when, bool skip_system, bool recurse,
+ LOCKMODE lockmode)
+{
+ EnableDisableTriggerNew2(rel, tgname, InvalidOid,
+ fires_when, skip_system,
+ recurse, lockmode);
+}
+
+void
EnableDisableTrigger(Relation rel, const char *tgname,
char fires_when, bool skip_system,
LOCKMODE lockmode)
{
- EnableDisableTriggerNew(rel, tgname, fires_when, skip_system,
- true, lockmode);
+ EnableDisableTriggerNew2(rel, tgname, InvalidOid,
+ fires_when, skip_system,
+ true, lockmode);
}
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 0377438861c..0d7558ee6ef 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -170,6 +170,9 @@ extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
extern ObjectAddress renametrig(RenameStmt *stmt);
+extern void EnableDisableTriggerNew2(Relation rel, const char *tgname, Oid tgparent,
+ char fires_when, bool skip_system, bool recurse,
+ LOCKMODE lockmode);
extern void EnableDisableTriggerNew(Relation rel, const char *tgname,
char fires_when, bool skip_system, bool recurse,
LOCKMODE lockmode);
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index 6d80ab1a6d8..66d473ab031 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -2719,6 +2719,40 @@ select tgrelid::regclass, tgname, tgenabled from pg_trigger
(3 rows)
drop table parent, child1;
+-- Check processing of foreign key triggers
+create table parent (a int primary key, f int references parent)
+ partition by list (a);
+create table child1 partition of parent for values in (1);
+select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname,
+ tgfoid::regproc, tgenabled
+ from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass)
+ order by tgrelid::regclass::text, tgfoid;
+ tgrelid | tgname | tgfoid | tgenabled
+---------+-------------------------+------------------------+-----------
+ child1 | RI_ConstraintTrigger_c_ | "RI_FKey_check_ins" | O
+ child1 | RI_ConstraintTrigger_c_ | "RI_FKey_check_upd" | O
+ parent | RI_ConstraintTrigger_c_ | "RI_FKey_check_ins" | O
+ parent | RI_ConstraintTrigger_c_ | "RI_FKey_check_upd" | O
+ parent | RI_ConstraintTrigger_a_ | "RI_FKey_noaction_del" | O
+ parent | RI_ConstraintTrigger_a_ | "RI_FKey_noaction_upd" | O
+(6 rows)
+
+alter table parent disable trigger all;
+select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname,
+ tgfoid::regproc, tgenabled
+ from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass)
+ order by tgrelid::regclass::text, tgfoid;
+ tgrelid | tgname | tgfoid | tgenabled
+---------+-------------------------+------------------------+-----------
+ child1 | RI_ConstraintTrigger_c_ | "RI_FKey_check_ins" | D
+ child1 | RI_ConstraintTrigger_c_ | "RI_FKey_check_upd" | D
+ parent | RI_ConstraintTrigger_c_ | "RI_FKey_check_ins" | D
+ parent | RI_ConstraintTrigger_c_ | "RI_FKey_check_upd" | D
+ parent | RI_ConstraintTrigger_a_ | "RI_FKey_noaction_del" | D
+ parent | RI_ConstraintTrigger_a_ | "RI_FKey_noaction_upd" | D
+(6 rows)
+
+drop table parent, child1;
-- Verify that firing state propagates correctly on creation, too
CREATE TABLE trgfire (i int) PARTITION BY RANGE (i);
CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10);
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 4d8504fb246..4222a8500b4 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -1883,6 +1883,21 @@ select tgrelid::regclass, tgname, tgenabled from pg_trigger
order by tgrelid::regclass::text, tgname;
drop table parent, child1;
+-- Check processing of foreign key triggers
+create table parent (a int primary key, f int references parent)
+ partition by list (a);
+create table child1 partition of parent for values in (1);
+select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname,
+ tgfoid::regproc, tgenabled
+ from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass)
+ order by tgrelid::regclass::text, tgfoid;
+alter table parent disable trigger all;
+select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname,
+ tgfoid::regproc, tgenabled
+ from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass)
+ order by tgrelid::regclass::text, tgfoid;
+drop table parent, child1;
+
-- Verify that firing state propagates correctly on creation, too
CREATE TABLE trgfire (i int) PARTITION BY RANGE (i);
CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10);