Attached is a patch for ALTER TRIGGER RENAME per the above thread. I
authorBruce Momjian <[email protected]>
Wed, 24 Apr 2002 02:48:55 +0000 (02:48 +0000)
committerBruce Momjian <[email protected]>
Wed, 24 Apr 2002 02:48:55 +0000 (02:48 +0000)
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

src/backend/commands/tablecmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/tablecmds.h
src/include/nodes/parsenodes.h

index d0cdacc92e7a895b9ceb1949cbe1ad9f63ae054c..5abe8f129bbbe2704f1ee59bb458a1a85c216da2 100644 (file)
@@ -2846,6 +2846,123 @@ renamerel(Oid relid, const char *newrelname)
        relation_close(targetrelation, NoLock);
 }
 
+/*
+ *             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.
index 8c73b9ecb2309f1c4aa06a8089425c2d6a7724f3..ed48c18da0c7d8b6604afc128a8d576b28468997 100644 (file)
@@ -2137,10 +2137,11 @@ _copyRenameStmt(RenameStmt *from)
        RenameStmt *newnode = makeNode(RenameStmt);
 
        Node_Copy(from, newnode, relation);
-       if (from->column)
-               newnode->column = pstrdup(from->column);
+       if (from->oldname)
+               newnode->oldname = pstrdup(from->oldname);
        if (from->newname)
                newnode->newname = pstrdup(from->newname);
+       newnode->renameType = from->renameType;
 
        return newnode;
 }
index c9f761980b076f16cf4ea575c565916292b9c72a..1ea36c43f1e41fb08afe3b899f18b424d4569e2a 100644 (file)
@@ -983,10 +983,12 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b)
 {
        if (!equal(a->relation, b->relation))
                return false;
-       if (!equalstr(a->column, b->column))
+       if (!equalstr(a->oldname, b->oldname))
                return false;
        if (!equalstr(a->newname, b->newname))
                return false;
+       if (a->renameType != b->renameType)
+               return false;
 
        return true;
 }
index 13234c06ee9b421e6c0b076a33bdfb59123df57b..bcc8db75c1b5d3f264b9a1a6df3911e7e41d7699 100644 (file)
@@ -2919,8 +2919,21 @@ RenameStmt:  ALTER TABLE relation_expr RENAME opt_column opt_name TO name
                                {
                                        RenameStmt *n = makeNode(RenameStmt);
                                        n->relation = $3;
-                                       n->column = $6;
+                                       n->oldname = $6;
                                        n->newname = $8;
+                                       if ($6 == NULL)
+                                               n->renameType = RENAME_TABLE;
+                                       else
+                                               n->renameType = RENAME_COLUMN;
+                                       $$ = (Node *)n;
+                               }
+               | ALTER TRIGGER name ON relation_expr RENAME TO name
+                               {
+                                       RenameStmt *n = makeNode(RenameStmt);
+                                       n->relation = $5;
+                                       n->oldname = $3;
+                                       n->newname = $8;
+                                       n->renameType = RENAME_TRIGGER;
                                        $$ = (Node *)n;
                                }
                ;
index cd27865385f440ea4a21d0807901a3514784a6da..6b625c4e1745f239ee590c7374fff958a162d418 100644 (file)
@@ -377,23 +377,30 @@ ProcessUtility(Node *parsetree,
 
                                CheckOwnership(stmt->relation, true);
 
-                               if (stmt->column == NULL)
+                               switch (stmt->renameType)
                                {
-                                       /*
-                                        * rename relation
-                                        */
-                                       renamerel(RangeVarGetRelid(stmt->relation, false),
-                                                         stmt->newname);
-                               }
-                               else
-                               {
-                                       /*
-                                        * rename attribute
-                                        */
-                                       renameatt(RangeVarGetRelid(stmt->relation, false),
-                                                         stmt->column,         /* old att name */
+                                       case RENAME_TABLE:
+                                               renamerel(RangeVarGetRelid(stmt->relation, false),
+                                                                 stmt->newname);
+                                               break;
+                                       case RENAME_COLUMN:
+                                               renameatt(RangeVarGetRelid(stmt->relation, false),
+                                                         stmt->oldname,        /* old att name */
                                                          stmt->newname,        /* new att name */
-                                                         interpretInhOption(stmt->relation->inhOpt));          /* recursive? */
+                                                         interpretInhOption(stmt->relation->inhOpt));  /* recursive? */
+                                               break;
+                                       case RENAME_TRIGGER:
+                                               renametrig(RangeVarGetRelid(stmt->relation, false),
+                                                         stmt->oldname,        /* old att name */
+                                                         stmt->newname);       /* new att name */
+                                               break;
+                                       case RENAME_RULE:
+                                               elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
+                                                               stmt->renameType);
+                                               break;
+                                       default:
+                                               elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
+                                                               stmt->renameType);
                                }
                        }
                        break;
index cb41938241985d996679597f293b7f4ce6ab3bab..9bc71f643742e9cd7e64fe56cddd3213344c522d 100644 (file)
@@ -15,6 +15,7 @@
 #define TABLECMDS_H
 
 #include "nodes/parsenodes.h"
+#include "utils/inval.h"
 
 extern void AlterTableAddColumn(Oid myrelid, bool inherits,
                                                                ColumnDef *colDef);
@@ -60,4 +61,8 @@ extern void renameatt(Oid relid,
 extern void renamerel(Oid relid,
                  const char *newrelname);
 
+extern void renametrig(Oid relid,
+                 const char *oldname,
+                 const char *newname);
+
 #endif   /* TABLECMDS_H */
index cdb9e8b29a240865bae6b4920becab49c705f5ae..42be9031db756c2a5fdeede5add0d1f57e2113e7 100644 (file)
@@ -1233,17 +1233,23 @@ typedef struct RemoveOperStmt
 } RemoveOperStmt;
 
 /* ----------------------
- *             Alter Table Rename Statement
+ *             Alter Object Rename Statement
  * ----------------------
+ * Currently supports renaming tables, table columns, and triggers.
+ * If renaming a table, oldname is ignored.
  */
+#define RENAME_TABLE   110
+#define RENAME_COLUMN  111
+#define RENAME_TRIGGER 112
+#define RENAME_RULE            113
+
 typedef struct RenameStmt
 {
        NodeTag         type;
-       RangeVar   *relation;           /* relation to be altered */
-       char       *column;                     /* if NULL, rename the relation name to
-                                                                * the new name. Otherwise, rename this
-                                                                * column name. */
+       RangeVar   *relation;           /* owning relation */
+       char       *oldname;            /* name of rule, trigger, etc */
        char       *newname;            /* the new name */
+       int                     renameType;             /* RENAME_TABLE, RENAME_COLUMN, etc */
 } RenameStmt;
 
 /* ----------------------