]> granicus.if.org Git - postgresql/commitdiff
Modify ALTER TABLE OWNER to change index ownership; code cleanup.
authorBruce Momjian <bruce@momjian.us>
Wed, 6 Mar 2002 19:58:26 +0000 (19:58 +0000)
committerBruce Momjian <bruce@momjian.us>
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