aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-04-24 02:48:55 +0000
committerBruce Momjian <bruce@momjian.us>2002-04-24 02:48:55 +0000
commit3a96b6cdeb6ea526de8759dd138c5985437c0260 (patch)
treecf2b1a95e59779679314a9207be42824e2fe9fac /src/backend/commands/tablecmds.c
parentfbc4b7110fc9cd7096a248e257086974ffeadcc2 (diff)
downloadpostgresql-3a96b6cdeb6ea526de8759dd138c5985437c0260.tar.gz
postgresql-3a96b6cdeb6ea526de8759dd138c5985437c0260.zip
Attached is a patch for ALTER TRIGGER RENAME per the above thread. I
left a stub for a future "ALTER RULE RENAME" but did not write that one yet. Bruce, if you want to add my name for for that I'll take it and do it later. Joe Conway
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 952496fc1df..e8b0d8bc013 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.8 2002/04/24 02:38:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.9 2002/04/24 02:48:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2847,6 +2847,123 @@ renamerel(Oid relid, const char *newrelname)
}
/*
+ * renametrig - changes the name of a trigger on a relation
+ *
+ * trigger name is changed in trigger catalog.
+ * No record of the previous name is kept.
+ *
+ * get proper relrelation from relation catalog (if not arg)
+ * scan trigger catalog
+ * for name conflict (within rel)
+ * for original trigger (if not arg)
+ * modify tgname in trigger tuple
+ * insert modified trigger in trigger catalog
+ * delete original trigger from trigger catalog
+ */
+extern void renametrig(Oid relid,
+ const char *oldname,
+ const char *newname)
+{
+ Relation targetrel;
+ Relation tgrel;
+ HeapTuple tuple;
+ SysScanDesc tgscan;
+ ScanKeyData key;
+ bool found = FALSE;
+ Relation idescs[Num_pg_trigger_indices];
+
+ /*
+ * Grab an exclusive lock on the target table, which we will NOT
+ * release until end of transaction.
+ */
+ targetrel = heap_open(relid, AccessExclusiveLock);
+
+ /*
+ * Scan pg_trigger twice for existing triggers on relation. We do this in
+ * order to ensure a trigger does not exist with newname (The unique index
+ * on tgrelid/tgname would complain anyway) and to ensure a trigger does
+ * exist with oldname.
+ *
+ * NOTE that this is cool only because we have AccessExclusiveLock on the
+ * relation, so the trigger set won't be changing underneath us.
+ */
+ tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
+
+ /*
+ * First pass -- look for name conflict
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_trigger_tgrelid,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+ tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
+ SnapshotNow, 1, &key);
+ while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), newname) == 0)
+ elog(ERROR, "renametrig: trigger %s already defined on relation %s",
+ newname, RelationGetRelationName(targetrel));
+ }
+ systable_endscan(tgscan);
+
+ /*
+ * Second pass -- look for trigger existing with oldname and update
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_trigger_tgrelid,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+ tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
+ SnapshotNow, 1, &key);
+ while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), oldname) == 0)
+ {
+ /*
+ * Update pg_trigger tuple with new tgname.
+ * (Scribbling on tuple is OK because it's a copy...)
+ */
+ namestrcpy(&(pg_trigger->tgname), newname);
+ simple_heap_update(tgrel, &tuple->t_self, tuple);
+
+ /*
+ * keep system catalog indices current
+ */
+ CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
+ CatalogCloseIndices(Num_pg_trigger_indices, idescs);
+
+ /*
+ * Invalidate relation's relcache entry so that other
+ * backends (and this one too!) are sent SI message to make them
+ * rebuild relcache entries.
+ */
+ CacheInvalidateRelcache(relid);
+
+ found = TRUE;
+ break;
+ }
+ }
+ systable_endscan(tgscan);
+
+ heap_close(tgrel, RowExclusiveLock);
+
+ if (!found)
+ elog(ERROR, "renametrig: trigger %s not defined on relation %s",
+ oldname, RelationGetRelationName(targetrel));
+
+ /*
+ * Close rel, but keep exclusive lock!
+ */
+ heap_close(targetrel, NoLock);
+}
+
+
+/*
* Given a trigger function OID, determine whether it is an RI trigger,
* and if so whether it is attached to PK or FK relation.
*