Modify ALTER TABLE OWNER to change index ownership; code cleanup.
authorBruce Momjian
Wed, 6 Mar 2002 19:58:26 +0000 (19:58 +0000)
committerBruce Momjian
Wed, 6 Mar 2002 19:58:26 +0000 (19:58 +0000)
Neil Conway

src/backend/commands/command.c
src/backend/utils/adt/ruleutils.c

index 4a2edd61bc0ed15eec6e3bba0c27a884c3a22824..b166ed539cd61239b9a0450907c15f6d86fbb584 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.159 2002/03/06 06:09:29 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.160 2002/03/06 19:58:26 momjian Exp $
  *
  * NOTES
  *   The PerformAddAttribute() code, like most of the relation
 #include "utils/relcache.h"
 #include "utils/temprel.h"
 
-
 static void drop_default(Oid relid, int16 attnum);
 static bool needs_toast_table(Relation rel);
-
+static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId);
+static void CheckTupleType(Form_pg_class tuple_class);
 
 /* --------------------------------
  *     PortalCleanup
@@ -1559,59 +1559,58 @@ AlterTableDropConstraint(const char *relationName,
        elog(NOTICE, "Multiple constraints dropped");
 }
 
-
 /*
  * ALTER TABLE OWNER
  */
 void
 AlterTableOwner(const char *relationName, const char *newOwnerName)
 {
-   Relation    class_rel;
-   HeapTuple   tuple;
-   int32       newOwnerSysid;
-   Relation    idescs[Num_pg_class_indices];
+   Oid relationOid;
+   Relation relation;
+   int32 newOwnerSysId;
 
-   /*
-    * first check that we are a superuser
-    */
+   /* check that we are the superuser */
    if (!superuser())
        elog(ERROR, "ALTER TABLE: permission denied");
 
-   /*
-    * look up the new owner in pg_shadow and get the sysid
-    */
-   newOwnerSysid = get_usesysid(newOwnerName);
+   /* lookup the OID of the target relation */
+   relation = RelationNameGetRelation(relationName);
+   relationOid = relation->rd_id;
+   RelationClose(relation);
 
-   /*
-    * find the table's entry in pg_class and make a modifiable copy
-    */
-   class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
+   /* lookup the sysid of the new owner */
+   newOwnerSysId = get_usesysid(newOwnerName);
+
+   /* do all the actual work */
+   AlterTableOwnerId(relationOid, newOwnerSysId);
+}
 
-   tuple = SearchSysCacheCopy(RELNAME,
-                              PointerGetDatum(relationName),
+static void
+AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
+{
+   Relation        class_rel;
+   HeapTuple       tuple;
+   Relation        idescs[Num_pg_class_indices];
+   Form_pg_class   tuple_class;
+
+   tuple = SearchSysCacheCopy(RELOID,
+                              ObjectIdGetDatum(relationOid),
                               0, 0, 0);
    if (!HeapTupleIsValid(tuple))
-       elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
-            relationName);
+       elog(ERROR, "ALTER TABLE: object ID %hd not found",
+               relationOid);
 
-   switch (((Form_pg_class) GETSTRUCT(tuple))->relkind)
-   {
-       case RELKIND_RELATION:
-       case RELKIND_INDEX:
-       case RELKIND_VIEW:
-       case RELKIND_SEQUENCE:
-           /* ok to change owner */
-           break;
-       default:
-           elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence",
-                relationName);
-   }
+   tuple_class = (Form_pg_class) GETSTRUCT(tuple);
+
+   /* Can we change the ownership of this tuple? */
+   CheckTupleType(tuple_class);
 
    /*
-    * modify the table's entry and write to the heap
+    * Okay, this is a valid tuple: change its ownership and
+    * write to the heap.
     */
-   ((Form_pg_class) GETSTRUCT(tuple))->relowner = newOwnerSysid;
-
+   class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
+   tuple_class->relowner = newOwnerSysId;
    simple_heap_update(class_rel, &tuple->t_self, tuple);
 
    /* Keep the catalog indices up to date */
@@ -1620,12 +1619,48 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
    CatalogCloseIndices(Num_pg_class_indices, idescs);
 
    /*
-    * unlock everything and return
+    * If we are operating on a table, also change the ownership
+    * of all of its indexes.
     */
+   if (tuple_class->relkind == RELKIND_RELATION)
+   {
+       Relation target_rel;
+       List *index_oid_list, *i;
+
+       /* Find all the indexes belonging to this relation */
+       target_rel = heap_open(relationOid, RowExclusiveLock);
+       index_oid_list = RelationGetIndexList(target_rel);
+       heap_close(target_rel, RowExclusiveLock);
+
+       /* For each index, recursively change its ownership */
+       foreach (i, index_oid_list)
+       {
+           AlterTableOwnerId(lfirsti(i), newOwnerSysId);
+       }
+
+       freeList(index_oid_list);
+   }
+
    heap_freetuple(tuple);
    heap_close(class_rel, NoLock);
 }
 
+static void
+CheckTupleType(Form_pg_class tuple_class)
+{
+   switch (tuple_class->relkind)
+   {
+       case RELKIND_RELATION:
+       case RELKIND_INDEX:
+       case RELKIND_VIEW:
+       case RELKIND_SEQUENCE:
+           /* ok to change owner */
+           break;
+       default:
+           elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence",
+                NameStr(tuple_class->relname));
+   }
+}
 
 /*
  * ALTER TABLE CREATE TOAST TABLE
index 2d14e4ff752001ec70c31834aa20d9c917008faa..169bcd23e29be6d605c8b8c635b90aa2d5c5e473 100644 (file)
@@ -3,7 +3,7 @@
  *             back to source text
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.91 2002/03/06 06:10:16 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.92 2002/03/06 19:58:26 momjian Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -141,7 +141,6 @@ static void get_opclass_name(Oid opclass, Oid actual_datatype,
                 StringInfo buf);
 static bool tleIsArrayAssign(TargetEntry *tle);
 static char *quote_identifier(char *ident);
-static char *get_relation_name(Oid relid);
 static char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
 
 #define only_marker(rte)  ((rte)->inh ? "" : "ONLY ")
@@ -752,7 +751,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
 
    /* The relation the rule is fired on */
    appendStringInfo(buf, " TO %s",
-                    quote_identifier(get_relation_name(ev_class)));
+                    quote_identifier(get_rel_name(ev_class)));
    if (ev_attr > 0)
        appendStringInfo(buf, ".%s",
                      quote_identifier(get_relid_attribute_name(ev_class,
@@ -2697,30 +2696,6 @@ quote_identifier(char *ident)
    return result;
 }
 
-/* ----------
- * get_relation_name           - Get a relation name by Oid
- * ----------
- */
-static char *
-get_relation_name(Oid relid)
-{
-   HeapTuple   classtup;
-   Form_pg_class classStruct;
-   char       *result;
-
-   classtup = SearchSysCache(RELOID,
-                             ObjectIdGetDatum(relid),
-                             0, 0, 0);
-   if (!HeapTupleIsValid(classtup))
-       elog(ERROR, "cache lookup of relation %u failed", relid);
-
-   classStruct = (Form_pg_class) GETSTRUCT(classtup);
-   result = pstrdup(NameStr(classStruct->relname));
-   ReleaseSysCache(classtup);
-   return result;
-}
-
-
 /* ----------
  * get_relid_attribute_name
  *     Get an attribute name by its relations Oid and its attnum