Modify ALTER TABLE OWNER to change index ownership; code cleanup.
Neil Conway
This commit is contained in:
parent
ade0fe5cb4
commit
3d9f865e94
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user