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:
@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user