From 3d9f865e94b2e7b926ef083dd555ecc7d33bccf9 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 6 Mar 2002 19:58:26 +0000 Subject: [PATCH] Modify ALTER TABLE OWNER to change index ownership; code cleanup. Neil Conway --- src/backend/commands/command.c | 113 +++++++++++++++++++----------- src/backend/utils/adt/ruleutils.c | 29 +------- 2 files changed, 76 insertions(+), 66 deletions(-) diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 4a2edd61bc..b166ed539c 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -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 @@ -53,10 +53,10 @@ #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 diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 2d14e4ff75..169bcd23e2 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -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 -- 2.40.0