-/*
- * Remove all triggers for a relation that's being deleted.
- */
-void
-RelationRemoveTriggers(Relation rel)
-{
- Relation tgrel;
- SysScanDesc tgscan;
- ScanKeyData key;
- HeapTuple tup;
- bool found = false;
-
- tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_trigger_tgrelid,
- F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(rel)));
- tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
- SnapshotNow, 1, &key);
-
- while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
- {
- /* Delete any comments associated with this trigger */
- DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel));
-
- simple_heap_delete(tgrel, &tup->t_self);
-
- found = true;
- }
-
- systable_endscan(tgscan);
-
- /*
- * If we deleted any triggers, must update pg_class entry and advance
- * command counter to make the updated entry visible. This is fairly
- * annoying, since we'e just going to drop the durn thing later, but
- * it's necessary to have a consistent state in case we do
- * CommandCounterIncrement() below --- if RelationBuildTriggers()
- * runs, it will complain otherwise. Perhaps RelationBuildTriggers()
- * shouldn't be so picky...
- */
- if (found)
- {
- Relation pgrel;
- Relation ridescs[Num_pg_class_indices];
-
- pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
- tup = SearchSysCacheCopy(RELOID,
- ObjectIdGetDatum(RelationGetRelid(rel)),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
- RelationGetRelid(rel));
-
- ((Form_pg_class) GETSTRUCT(tup))->reltriggers = 0;
- simple_heap_update(pgrel, &tup->t_self, tup);
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tup);
- CatalogCloseIndices(Num_pg_class_indices, ridescs);
- heap_freetuple(tup);
- heap_close(pgrel, RowExclusiveLock);
- CommandCounterIncrement();
- }
-
- /*
- * Also drop all constraint triggers referencing this relation
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_trigger_tgconstrrelid,
- F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(rel)));
- tgscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, true,
- SnapshotNow, 1, &key);
-
- while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
- {
- Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
-
- elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"",
- get_rel_name(pg_trigger->tgrelid));
-
- DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname));
-
- /*
- * Need to do a command counter increment here to show up new
- * pg_class.reltriggers in the next loop iteration (in case there
- * are multiple referential integrity action triggers for the same
- * FK table defined on the PK table).
- */
- CommandCounterIncrement();
- }
- systable_endscan(tgscan);
-
- heap_close(tgrel, RowExclusiveLock);
-}
-