From 994c36e01d19dece2b0c76fb781e1d08a6e1c814 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 3 Oct 2012 18:02:38 -0300 Subject: 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 --- src/backend/commands/functioncmds.c | 137 ------------------------------------ 1 file changed, 137 deletions(-) (limited to 'src/backend/commands/functioncmds.c') diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index ef6eadc95fd..453e33ae668 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -66,11 +66,6 @@ #include "utils/syscache.h" #include "utils/tqual.h" - -static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup, - Oid newOwnerId); - - /* * Examine the RETURNS clause of the CREATE FUNCTION statement * and return information about it as *prorettype_p and *returnsSet. @@ -1109,138 +1104,6 @@ RenameFunction(List *name, List *argtypes, const char *newname) heap_freetuple(tup); } -/* - * Change function owner by name and args - */ -void -AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) -{ - Relation rel; - Oid procOid; - HeapTuple tup; - - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - - procOid = LookupFuncNameTypeNames(name, argtypes, false); - - tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for function %u", procOid); - - if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an aggregate function", - NameListToString(name)), - errhint("Use ALTER AGGREGATE to change owner of aggregate functions."))); - - AlterFunctionOwner_internal(rel, tup, newOwnerId); - - heap_close(rel, NoLock); -} - -/* - * Change function owner by Oid - */ -void -AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId) -{ - Relation rel; - HeapTuple tup; - - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - - tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for function %u", procOid); - AlterFunctionOwner_internal(rel, tup, newOwnerId); - - heap_close(rel, NoLock); -} - -static void -AlterFunctionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) -{ - Form_pg_proc procForm; - AclResult aclresult; - Oid procOid; - - Assert(RelationGetRelid(rel) == ProcedureRelationId); - Assert(tup->t_tableOid == ProcedureRelationId); - - procForm = (Form_pg_proc) GETSTRUCT(tup); - procOid = HeapTupleGetOid(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 (procForm->proowner != newOwnerId) - { - Datum repl_val[Natts_pg_proc]; - bool repl_null[Natts_pg_proc]; - bool repl_repl[Natts_pg_proc]; - Acl *newAcl; - Datum aclDatum; - bool isNull; - HeapTuple newtuple; - - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_proc_ownercheck(procOid, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, - NameStr(procForm->proname)); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - /* New owner must have CREATE privilege on namespace */ - aclresult = pg_namespace_aclcheck(procForm->pronamespace, - newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(procForm->pronamespace)); - } - - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - repl_repl[Anum_pg_proc_proowner - 1] = true; - repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId); - - /* - * Determine the modified ACL for the new owner. This is only - * necessary when the ACL is non-null. - */ - aclDatum = SysCacheGetAttr(PROCOID, tup, - Anum_pg_proc_proacl, - &isNull); - if (!isNull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - procForm->proowner, newOwnerId); - repl_repl[Anum_pg_proc_proacl - 1] = true; - repl_val[Anum_pg_proc_proacl - 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(ProcedureRelationId, procOid, newOwnerId); - } - - ReleaseSysCache(tup); -} - /* * Implements the ALTER FUNCTION utility command (except for the * RENAME and OWNER clauses, which are handled as part of the generic -- cgit v1.2.3