Commit 3d9f865e authored by Bruce Momjian's avatar Bruce Momjian

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

Neil Conway
parent ade0fe5c
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment