Hi,
Currently if some one try to drop the PROCEDURE and
it don't have privilege or it's not an owner, than error message
still indicate object as FUNCTION.
Example:
postgres@37737=#drop procedure pro;
ERROR: must be owner of function pro
This doesn't look correct specially that now we have separate
object type as OBJECT_PROCEDURE. It seems like we need
to introduce new AclObjectKind for PROCEDURE and do the
necessary changes to pass the correct AclObjectKind.
PFA patch, where introduced new AclObjectKind (ACL_KIND_PROCEDURE),
msg for the new AclObjectKind, and passed it through at
appropriate places.
Also update the necessary "make check" expected output changes.
Regards,
Thanks,
Rushabh Lathia
www.EnterpriseDB.com
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index e481cf3..680ef18 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -257,6 +257,7 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
whole_mask = ACL_ALL_RIGHTS_DATABASE;
break;
case ACL_KIND_PROC:
+ case ACL_KIND_PROCEDURE:
whole_mask = ACL_ALL_RIGHTS_FUNCTION;
break;
case ACL_KIND_LANGUAGE:
@@ -2565,7 +2566,8 @@ ExecGrant_Function(InternalGrant *istmt)
this_privileges =
restrict_and_check_grant(istmt->is_grant, avail_goptions,
istmt->all_privs, istmt->privileges,
- funcId, grantorId, ACL_KIND_PROC,
+ funcId, grantorId,
+ (istmt->objtype == ACL_OBJECT_PROCEDURE) ? ACL_KIND_PROCEDURE : ACL_KIND_PROC,
NameStr(pg_proc_tuple->proname),
0, NULL);
@@ -3360,6 +3362,8 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
gettext_noop("permission denied for database %s"),
/* ACL_KIND_PROC */
gettext_noop("permission denied for function %s"),
+ /* ACL_KIND_PROCEDURE */
+ gettext_noop("permission denied for procedure %s"),
/* ACL_KIND_OPER */
gettext_noop("permission denied for operator %s"),
/* ACL_KIND_TYPE */
@@ -3412,6 +3416,8 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
gettext_noop("must be owner of database %s"),
/* ACL_KIND_PROC */
gettext_noop("must be owner of function %s"),
+ /* ACL_KIND_PROCEDURE */
+ gettext_noop("must be owner of procedure %s"),
/* ACL_KIND_OPER */
gettext_noop("must be owner of operator %s"),
/* ACL_KIND_TYPE */
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 9553675..d67a68b 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2261,7 +2261,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
case OBJECT_PROCEDURE:
case OBJECT_ROUTINE:
if (!pg_proc_ownercheck(address.objectId, roleid))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
+ aclcheck_error(ACLCHECK_NOT_OWNER, objtype == OBJECT_PROCEDURE ? ACL_KIND_PROCEDURE : ACL_KIND_PROC,
NameListToString((castNode(ObjectWithArgs, object))->objname));
break;
case OBJECT_OPERATOR:
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 2a9c901..7541146 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -2270,7 +2270,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt)
aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fexpr->funcid));
+ aclcheck_error(aclresult, ACL_KIND_PROCEDURE, get_func_name(fexpr->funcid));
InvokeFunctionExecuteHook(fexpr->funcid);
nargs = list_length(fexpr->args);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 254a811..44037a0 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -191,6 +191,7 @@ typedef enum AclObjectKind
ACL_KIND_SEQUENCE, /* pg_sequence */
ACL_KIND_DATABASE, /* pg_database */
ACL_KIND_PROC, /* pg_proc */
+ ACL_KIND_PROCEDURE, /* pg_proc procedure */
ACL_KIND_OPER, /* pg_operator */
ACL_KIND_TYPE, /* pg_type */
ACL_KIND_LANGUAGE, /* pg_language */
diff --git a/src/test/regress/expected/create_procedure.out b/src/test/regress/expected/create_procedure.out
index 5538ef2..9a5be38 100644
--- a/src/test/regress/expected/create_procedure.out
+++ b/src/test/regress/expected/create_procedure.out
@@ -73,7 +73,7 @@ GRANT INSERT ON cp_test TO regress_user1;
REVOKE EXECUTE ON PROCEDURE ptest1(text) FROM PUBLIC;
SET ROLE regress_user1;
CALL ptest1('a'); -- error
-ERROR: permission denied for function ptest1
+ERROR: permission denied for procedure ptest1
RESET ROLE;
GRANT EXECUTE ON PROCEDURE ptest1(text) TO regress_user1;
SET ROLE regress_user1;
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index e6994f0..c92993d 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -696,7 +696,7 @@ ERROR: permission denied for function testfunc1
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
ERROR: permission denied for function testagg1
CALL testproc1(6); -- fail
-ERROR: permission denied for function testproc1
+ERROR: permission denied for procedure testproc1
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
ERROR: permission denied for relation atest2
SELECT testfunc4(true); -- ok
@@ -724,7 +724,7 @@ ERROR: must be owner of function testfunc1
DROP AGGREGATE testagg1(int); -- fail
ERROR: must be owner of function testagg1
DROP PROCEDURE testproc1(int); -- fail
-ERROR: must be owner of function testproc1
+ERROR: must be owner of procedure testproc1
\c -
DROP FUNCTION testfunc1(int); -- ok
-- restore to sanity