Fix trigger drop procedure

After commit 123cc697a8, 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
This commit is contained in:
Alvaro Herrera 2019-02-10 10:00:11 -03:00
parent ee6370978f
commit cc126b45ea

View File

@ -8008,10 +8008,12 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
ReleaseSysCache(partcontup); ReleaseSysCache(partcontup);
/* /*
* Looks good! Attach this constraint. Note that the action * Looks good! Attach this constraint. The action triggers in
* triggers are no longer needed, so remove them. We identify * the new partition become redundant -- the parent table already
* them because they have our constraint OID, as well as being * has equivalent ones, and those will be able to reach the
* on the referenced rel. * 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); trigrel = heap_open(TriggerRelationId, RowExclusiveLock);
ScanKeyInit(&key, ScanKeyInit(&key,
@ -8024,17 +8026,30 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
while ((trigtup = systable_getnext(scan)) != NULL) while ((trigtup = systable_getnext(scan)) != NULL)
{ {
Form_pg_trigger trgform = (Form_pg_trigger) GETSTRUCT(trigtup); Form_pg_trigger trgform = (Form_pg_trigger) GETSTRUCT(trigtup);
ObjectAddress trigger;
if (trgform->tgconstrrelid != fk->conrelid) if (trgform->tgconstrrelid != fk->conrelid)
continue; continue;
if (trgform->tgrelid != fk->confrelid) if (trgform->tgrelid != fk->confrelid)
continue; continue;
deleteDependencyRecordsForClass(TriggerRelationId, /*
* 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), HeapTupleGetOid(trigtup),
ConstraintRelationId, false);
DEPENDENCY_INTERNAL); /* make dependency deletion visible to performDeletion */
CatalogTupleDelete(trigrel, &trigtup->t_self); CommandCounterIncrement();
ObjectAddressSet(trigger, TriggerRelationId,
HeapTupleGetOid(trigtup));
performDeletion(&trigger, DROP_RESTRICT, 0);
/* make trigger drop visible, in case the loop iterates */
CommandCounterIncrement();
} }
systable_endscan(scan); systable_endscan(scan);