diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2005-11-21 12:49:33 +0000 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2005-11-21 12:49:33 +0000 |
commit | cec3b0a9e63fd94b05dac894cca8bfa51358afec (patch) | |
tree | 464377c39a1b3f42b4d2ab82a261e9a603fa1220 /src/backend/commands/functioncmds.c | |
parent | c52795d18a698d25b9cd7cd1ca9318a42b08fdb9 (diff) | |
download | postgresql-cec3b0a9e63fd94b05dac894cca8bfa51358afec.tar.gz postgresql-cec3b0a9e63fd94b05dac894cca8bfa51358afec.zip |
Implement DROP OWNED and REASSIGN OWNED. These new commands facilitate the
process of dropping roles by dropping objects owned by them and privileges
granted to them, or giving the owned objects to someone else, through the
use of the data stored in the new pg_shdepend catalog.
Some refactoring of the GRANT/REVOKE code was needed, as well as ALTER OWNER
code. Further cleanup of code duplication in the GRANT code seems necessary.
Implemented by me after an idea from Tom Lane, who also provided various kind
of implementation advice.
Regression tests pass. Some tests for the new functionality are also added,
as well as rudimentary documentation.
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index f4d6164775e..77f892fe501 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.69 2005/10/15 02:49:15 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.70 2005/11/21 12:49:31 alvherre Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -55,6 +55,7 @@ #include "utils/lsyscache.h" #include "utils/syscache.h" +static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId); /* * Examine the RETURNS clause of the CREATE FUNCTION statement @@ -853,16 +854,14 @@ RenameFunction(List *name, List *argtypes, const char *newname) } /* - * Change function owner + * Change function owner by name and args */ void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) { + Relation rel; Oid procOid; HeapTuple tup; - Form_pg_proc procForm; - Relation rel; - AclResult aclresult; rel = heap_open(ProcedureRelationId, RowExclusiveLock); @@ -873,15 +872,53 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for function %u", procOid); - procForm = (Form_pg_proc) GETSTRUCT(tup); - if (procForm->proisagg) + 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 = SearchSysCache(PROCOID, + ObjectIdGetDatum(procOid), + 0, 0, 0); + 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. @@ -902,7 +939,7 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) /* Otherwise, must be owner of the existing object */ if (!pg_proc_ownercheck(procOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, - NameListToString(name)); + NameStr(procForm->proname)); /* Must be able to become new owner */ check_is_member_of_role(GetUserId(), newOwnerId); @@ -937,7 +974,8 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl); } - newtuple = heap_modifytuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl); + newtuple = heap_modifytuple(tup, RelationGetDescr(rel), repl_val, + repl_null, repl_repl); simple_heap_update(rel, &newtuple->t_self, newtuple); CatalogUpdateIndexes(rel, newtuple); @@ -949,7 +987,6 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) } ReleaseSysCache(tup); - heap_close(rel, NoLock); } /* |