diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-02-10 10:00:11 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-02-10 10:00:11 -0300 |
commit | cb90de1aac18f8d9d89af8a3c2286aa0691c8214 (patch) | |
tree | 4a6909ae6c818877c1220bd9ae989c0ce061727a /src/backend/commands/tablecmds.c | |
parent | 068503c76511cdb0080bab689662a20e86b9c845 (diff) | |
download | postgresql-cb90de1aac18f8d9d89af8a3c2286aa0691c8214.tar.gz postgresql-cb90de1aac18f8d9d89af8a3c2286aa0691c8214.zip |
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
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 35a9ade0590..b66d194b80d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -7919,10 +7919,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, @@ -7935,17 +7937,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, - trgform->oid, - 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, + trgform->oid, + false); + /* make dependency deletion visible to performDeletion */ + CommandCounterIncrement(); + ObjectAddressSet(trigger, TriggerRelationId, + trgform->oid); + performDeletion(&trigger, DROP_RESTRICT, 0); + /* make trigger drop visible, in case the loop iterates */ + CommandCounterIncrement(); } systable_endscan(scan); |