]> granicus.if.org Git - postgresql/commitdiff
Attached is a patch for ALTER TRIGGER RENAME per the above thread. I
authorBruce Momjian <bruce@momjian.us>
Wed, 24 Apr 2002 02:48:55 +0000 (02:48 +0000)
committerBruce Momjian <bruce@momjian.us>
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 952496fc1df9986bc169763c4dd6e3b55370bcee..e8b0d8bc013b3b527394e080a70069e220064d3c 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 d9d5d13d8d46ef89c4639ccf8efe11ae404c6bde..ac25cd522956a0a34939aed7f362cff2947c72a8 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.180 2002/04/18 20:01:09 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.181 2002/04/24 02:48:54 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 42030b272684e54c4628ae3ae41f0cb392f6b8a9..3deb6207c3e43927732ddbbfcfa177a3dd80bfc0 100644 (file)
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.128 2002/04/18 20:01:09 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.129 2002/04/24 02:48:54 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 a7cae5b116fec5002b308b9963546e347439c408..6e768c5bc4196a268d3f266b81b7f93b504c49b1 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.309 2002/04/21 21:53:23 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.310 2002/04/24 02:48:54 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -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 24a1e3d2964133cfa0bacca89f22e531cfdb7b75..d1d670228ffe3b22bc674f7d7afb83e18bfacb70 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.150 2002/04/18 20:01:09 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.151 2002/04/24 02:48:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 5d895972f5b069fbabcbf521ff366a594ecdb906..f3dfcd6b9b1af0c6c5afbb14725e36b6ceb618e1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: tablecmds.h,v 1.1 2002/04/15 05:22:04 tgl Exp $
+ * $Id: tablecmds.h,v 1.2 2002/04/24 02:48:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 1433083b2fba9354832dad97df79de7b4563ebca..60703a06dccfd7c0897e85ba08048bbbd435f95e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.173 2002/04/21 00:26:43 tgl Exp $
+ * $Id: parsenodes.h,v 1.174 2002/04/24 02:48:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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;
 
 /* ----------------------