假设我有两个 Postgresql 数据库组,“authors”和“editors”,以及两个用户,“maxwell”和“ernest”。
create role authors;
create role editors;
create user maxwell;
create user ernest;
grant authors to editors; --editors can do what authors can do
grant editors to maxwell; --maxwell is an editor
grant authors to ernest; --ernest is an author
我想编写一个高性能函数,它返回 maxwell 所属的角色(最好是他们的 oid)列表,如下所示:
create or replace function get_all_roles() returns oid[] ...
它应该返回 maxwell、authors 和 editors(但不是 ernest)的 oid。
但是我不确定当有继承时该怎么做。
您可以使用递归查询来查询系统目录,特别是
pg_auth_members
:关于转换为对象标识符类型的手册
regrole
。BTW 1:
INHERIT
是的默认行为,CREATE ROLE
不必详细说明。BTW 2:循环依赖是不可能的。Postgres 不允许这样做。所以我们不必检查。
这是Craig Ringer 的答案的简化版本,非超级用户可以直接使用:
pg_roles
本质上是一种pg_authid
公众可以访问的观点,因为它不会泄露密码,这与pg_authid
. 基础oid
甚至导出到视图中。当不需要密码时,创建专用的超级用户拥有的功能是没有意义的。精简版:
在这里,我们使用一个
pg_has_role
以角色名称作为主题和角色 oid 的版本来测试成员资格,通过member
模式因此我们测试继承的成员资格。使用的好处
pg_has_role
是它使用PostgreSQL内部的角色信息缓存来快速满足成员查询。您可能希望将其包装在一个
SECURITY DEFINER
函数中,因为pg_authid
访问受限。就像是:您可以使用
pg_get_userbyid(oid)
从 oid 获取角色名称而无需查询pg_authid
:这是我的看法。它适用于一个特定用户或所有用户。
我相信这会做到
如果您更喜欢获取角色名称,请将第一个替换
oid
为rolname
.如果你想知道你当前活跃角色的所有角色: