1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

refactor ALTER some-obj SET OWNER implementation

Remove duplicate implementation of catalog munging and miscellaneous
privilege and consistency checks.  Instead rely on already existing data
in objectaddress.c to do the work.

Author: KaiGai Kohei
Tweaked by me
Reviewed by Robert Haas
This commit is contained in:
Alvaro Herrera
2012-10-03 18:02:38 -03:00
parent 1f91c8ca1d
commit 994c36e01d
24 changed files with 270 additions and 1338 deletions

View File

@ -55,9 +55,6 @@ static void create_proc_lang(const char *languageName, bool replace,
Oid languageOwner, Oid handlerOid, Oid inlineOid,
Oid valOid, bool trusted);
static PLTemplate *find_language_template(const char *languageName);
static void AlterLanguageOwner_internal(HeapTuple tup, Relation rel,
Oid newOwnerId);
/* ---------------------------------------------------------------------
* CREATE PROCEDURAL LANGUAGE
@ -574,120 +571,6 @@ RenameLanguage(const char *oldname, const char *newname)
heap_freetuple(tup);
}
/*
* Change language owner
*/
void
AlterLanguageOwner(const char *name, Oid newOwnerId)
{
HeapTuple tup;
Relation rel;
rel = heap_open(LanguageRelationId, RowExclusiveLock);
tup = SearchSysCache1(LANGNAME, CStringGetDatum(name));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", name)));
AlterLanguageOwner_internal(tup, rel, newOwnerId);
ReleaseSysCache(tup);
heap_close(rel, RowExclusiveLock);
}
/*
* Change language owner, specified by OID
*/
void
AlterLanguageOwner_oid(Oid oid, Oid newOwnerId)
{
HeapTuple tup;
Relation rel;
rel = heap_open(LanguageRelationId, RowExclusiveLock);
tup = SearchSysCache1(LANGOID, ObjectIdGetDatum(oid));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for language %u", oid);
AlterLanguageOwner_internal(tup, rel, newOwnerId);
ReleaseSysCache(tup);
heap_close(rel, RowExclusiveLock);
}
/*
* Workhorse for AlterLanguageOwner variants
*/
static void
AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
{
Form_pg_language lanForm;
lanForm = (Form_pg_language) GETSTRUCT(tup);
/*
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
if (lanForm->lanowner != newOwnerId)
{
Datum repl_val[Natts_pg_language];
bool repl_null[Natts_pg_language];
bool repl_repl[Natts_pg_language];
Acl *newAcl;
Datum aclDatum;
bool isNull;
HeapTuple newtuple;
/* Otherwise, must be owner of the existing object */
if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
NameStr(lanForm->lanname));
/* Must be able to become new owner */
check_is_member_of_role(GetUserId(), newOwnerId);
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
repl_repl[Anum_pg_language_lanowner - 1] = true;
repl_val[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
* necessary when the ACL is non-null.
*/
aclDatum = SysCacheGetAttr(LANGNAME, tup,
Anum_pg_language_lanacl,
&isNull);
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
lanForm->lanowner, newOwnerId);
repl_repl[Anum_pg_language_lanacl - 1] = true;
repl_val[Anum_pg_language_lanacl - 1] = PointerGetDatum(newAcl);
}
newtuple = heap_modify_tuple(tup, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(LanguageRelationId, HeapTupleGetOid(tup),
newOwnerId);
}
}
/*
* get_language_oid - given a language name, look up the OID
*