Modify ALTER TABLE OWNER to change index ownership; code cleanup.

Neil Conway
This commit is contained in:
Bruce Momjian 2002-03-06 19:58:26 +00:00
parent ade0fe5cb4
commit 3d9f865e94
2 changed files with 81 additions and 71 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
@ -53,10 +53,10 @@
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/temprel.h" #include "utils/temprel.h"
static void drop_default(Oid relid, int16 attnum); static void drop_default(Oid relid, int16 attnum);
static bool needs_toast_table(Relation rel); static bool needs_toast_table(Relation rel);
static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId);
static void CheckTupleType(Form_pg_class tuple_class);
/* -------------------------------- /* --------------------------------
* PortalCleanup * PortalCleanup
@ -1559,42 +1559,96 @@ AlterTableDropConstraint(const char *relationName,
elog(NOTICE, "Multiple constraints dropped"); elog(NOTICE, "Multiple constraints dropped");
} }
/* /*
* ALTER TABLE OWNER * ALTER TABLE OWNER
*/ */
void void
AlterTableOwner(const char *relationName, const char *newOwnerName) AlterTableOwner(const char *relationName, const char *newOwnerName)
{ {
Relation class_rel; Oid relationOid;
HeapTuple tuple; Relation relation;
int32 newOwnerSysid; int32 newOwnerSysId;
Relation idescs[Num_pg_class_indices];
/* /* check that we are the superuser */
* first check that we are a superuser
*/
if (!superuser()) if (!superuser())
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: permission denied");
/* /* lookup the OID of the target relation */
* look up the new owner in pg_shadow and get the sysid relation = RelationNameGetRelation(relationName);
*/ relationOid = relation->rd_id;
newOwnerSysid = get_usesysid(newOwnerName); RelationClose(relation);
/* /* lookup the sysid of the new owner */
* find the table's entry in pg_class and make a modifiable copy newOwnerSysId = get_usesysid(newOwnerName);
*/
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(RELNAME, /* do all the actual work */
PointerGetDatum(relationName), AlterTableOwnerId(relationOid, newOwnerSysId);
}
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); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found", elog(ERROR, "ALTER TABLE: object ID %hd not found",
relationName); relationOid);
switch (((Form_pg_class) GETSTRUCT(tuple))->relkind) tuple_class = (Form_pg_class) GETSTRUCT(tuple);
/* Can we change the ownership of this tuple? */
CheckTupleType(tuple_class);
/*
* Okay, this is a valid tuple: change its ownership and
* write to the heap.
*/
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 */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, class_rel, tuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
/*
* 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_RELATION:
case RELKIND_INDEX: case RELKIND_INDEX:
@ -1604,29 +1658,10 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
break; break;
default: default:
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence", elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence",
relationName); NameStr(tuple_class->relname));
} }
/*
* modify the table's entry and write to the heap
*/
((Form_pg_class) GETSTRUCT(tuple))->relowner = newOwnerSysid;
simple_heap_update(class_rel, &tuple->t_self, tuple);
/* Keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, class_rel, tuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
/*
* unlock everything and return
*/
heap_freetuple(tuple);
heap_close(class_rel, NoLock);
} }
/* /*
* ALTER TABLE CREATE TOAST TABLE * ALTER TABLE CREATE TOAST TABLE
*/ */

View File

@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -141,7 +141,6 @@ static void get_opclass_name(Oid opclass, Oid actual_datatype,
StringInfo buf); StringInfo buf);
static bool tleIsArrayAssign(TargetEntry *tle); static bool tleIsArrayAssign(TargetEntry *tle);
static char *quote_identifier(char *ident); static char *quote_identifier(char *ident);
static char *get_relation_name(Oid relid);
static char *get_relid_attribute_name(Oid relid, AttrNumber attnum); static char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
#define only_marker(rte) ((rte)->inh ? "" : "ONLY ") #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 */ /* The relation the rule is fired on */
appendStringInfo(buf, " TO %s", appendStringInfo(buf, " TO %s",
quote_identifier(get_relation_name(ev_class))); quote_identifier(get_rel_name(ev_class)));
if (ev_attr > 0) if (ev_attr > 0)
appendStringInfo(buf, ".%s", appendStringInfo(buf, ".%s",
quote_identifier(get_relid_attribute_name(ev_class, quote_identifier(get_relid_attribute_name(ev_class,
@ -2697,30 +2696,6 @@ quote_identifier(char *ident)
return result; 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_relid_attribute_name
* Get an attribute name by its relations Oid and its attnum * Get an attribute name by its relations Oid and its attnum