summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2019-02-10 10:00:11 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2019-02-10 10:00:11 -0300
commitcc126b45ea5c5e408b01ff4fb09a974450e11025 (patch)
tree35ce6bd34bb9c79efeae23d459679d222187b4ca
parentee6370978fd921c22ec8bf2239ad4d30ae126fed (diff)
Fix trigger drop procedure
After commit 123cc697a8eb, we remove redundant FK action triggers during partition ATTACH by merely deleting the catalog tuple, but that's wrong: it should use performDeletion() instead. Repair, and make the comments more explicit. Per code review from Tom Lane. Discussion: https://postgr.es/m/18885.1549642539@sss.pgh.pa.us
-rw-r--r--src/backend/commands/tablecmds.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 910e5deaa3f..0f72f51d372 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8008,10 +8008,12 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
ReleaseSysCache(partcontup);
/*
- * Looks good! Attach this constraint. Note that the action
- * triggers are no longer needed, so remove them. We identify
- * them because they have our constraint OID, as well as being
- * on the referenced rel.
+ * Looks good! Attach this constraint. The action triggers in
+ * the new partition become redundant -- the parent table already
+ * has equivalent ones, and those will be able to reach the
+ * partition. Remove the ones in the partition. We identify them
+ * because they have our constraint OID, as well as being on the
+ * referenced rel.
*/
trigrel = heap_open(TriggerRelationId, RowExclusiveLock);
ScanKeyInit(&key,
@@ -8024,17 +8026,30 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
while ((trigtup = systable_getnext(scan)) != NULL)
{
Form_pg_trigger trgform = (Form_pg_trigger) GETSTRUCT(trigtup);
+ ObjectAddress trigger;
if (trgform->tgconstrrelid != fk->conrelid)
continue;
if (trgform->tgrelid != fk->confrelid)
continue;
- deleteDependencyRecordsForClass(TriggerRelationId,
- HeapTupleGetOid(trigtup),
- ConstraintRelationId,
- DEPENDENCY_INTERNAL);
- CatalogTupleDelete(trigrel, &trigtup->t_self);
+ /*
+ * The constraint is originally set up to contain this trigger
+ * as an implementation object, so there's a dependency record
+ * that links the two; however, since the trigger is no longer
+ * needed, we remove the dependency link in order to be able
+ * to drop the trigger while keeping the constraint intact.
+ */
+ deleteDependencyRecordsFor(TriggerRelationId,
+ HeapTupleGetOid(trigtup),
+ false);
+ /* make dependency deletion visible to performDeletion */
+ CommandCounterIncrement();
+ ObjectAddressSet(trigger, TriggerRelationId,
+ HeapTupleGetOid(trigtup));
+ performDeletion(&trigger, DROP_RESTRICT, 0);
+ /* make trigger drop visible, in case the loop iterates */
+ CommandCounterIncrement();
}
systable_endscan(scan);