diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-11-08 22:10:03 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-11-08 22:10:03 +0000 |
commit | 3908473c809d5c24940faebfabdad673f4302178 (patch) | |
tree | 6a1989499ee61771c7764afd2b24d12ebd25b8fb /src/backend/commands/trigger.c | |
parent | ebe0b236909732c75d665c73363bd4ac7a7aa138 (diff) | |
download | postgresql-3908473c809d5c24940faebfabdad673f4302178.tar.gz postgresql-3908473c809d5c24940faebfabdad673f4302178.zip |
Make DROP TABLE rollback-able: postpone physical file delete until commit.
(WAL logging for this is not done yet, however.) Clean up a number of really
crufty things that are no longer needed now that DROP behaves nicely. Make
temp table mapper do the right things when drop or rename affecting a temp
table is rolled back. Also, remove "relation modified while in use" error
check, in favor of locking tables at first reference and holding that lock
throughout the statement.
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) { |