diff options
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r-- | src/backend/commands/trigger.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 059bc42987f..33340291e1c 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.78 2000/10/16 17:08:05 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.79 2000/11/08 22:09:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -388,6 +388,7 @@ RelationRemoveTriggers(Relation rel) HeapScanDesc tgscan; ScanKeyData key; HeapTuple tup; + bool found = false; tgrel = heap_openr(TriggerRelationName, RowExclusiveLock); ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid, @@ -403,17 +404,44 @@ RelationRemoveTriggers(Relation rel) DeleteComments(tup->t_data->t_oid); heap_delete(tgrel, &tup->t_self, NULL); + + found = true; } heap_endscan(tgscan); /* ---------- - * Need to bump it here so the following doesn't see - * the already deleted triggers again for a self-referencing - * table. + * 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... * ---------- */ - CommandCounterIncrement(); + if (found) + { + Relation pgrel; + Relation ridescs[Num_pg_class_indices]; + + pgrel = heap_openr(RelationRelationName, RowExclusiveLock); + tup = SearchSysCacheTupleCopy(RELOID, + 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; + heap_update(pgrel, &tup->t_self, tup, NULL); + 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 @@ -431,22 +459,21 @@ RelationRemoveTriggers(Relation rel) pg_trigger = (Form_pg_trigger) GETSTRUCT(tup); - refrel = heap_open(pg_trigger->tgrelid, NoLock); + stmt.trigname = pstrdup(NameStr(pg_trigger->tgname)); + + /* May as well grab AccessExclusiveLock, since DropTrigger will. */ + refrel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock); stmt.relname = pstrdup(RelationGetRelationName(refrel)); heap_close(refrel, NoLock); - stmt.trigname = DatumGetCString(DirectFunctionCall1(nameout, - NameGetDatum(&pg_trigger->tgname))); - - elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", stmt.relname); DropTrigger(&stmt); /* ---------- * Need to do a command counter increment here to show up - * new pg_class.reltriggers in the next loop invocation already - * (there are multiple referential integrity action + * 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). * ---------- */ @@ -747,9 +774,6 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2) * We need not examine the "index" data, just the trigger array * itself; if we have the same triggers with the same types, the * derived index data should match. - * - * XXX It seems possible that the same triggers could appear in different - * orders in the two trigger arrays; do we need to handle that? */ if (trigdesc1 != NULL) { |