Digamos que eu tenha dois grupos de banco de dados Postgresql, "autores" e "editores", e dois usuários, "maxwell" e "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
Eu gostaria de escrever uma função performante que retornasse uma lista dos papéis (de preferência seus oid's) aos quais o maxwell pertence, algo assim:
create or replace function get_all_roles() returns oid[] ...
Deve retornar os oids para maxwell, autores e editores (mas não ernest).
Mas não tenho certeza de como fazê-lo quando há herança.
Você pode consultar o catálogo do sistema com uma consulta recursiva , em particular
pg_auth_members
:O manual sobre o tipo de identificador de conversão para objeto
regrole
.BTW 1:
INHERIT
é o comportamento padrãoCREATE ROLE
e não precisa ser explicado.BTW 2: dependências circulares não são possíveis. O Postgres não permite isso. Então não temos que verificar isso.
Esta é uma versão simplificada da resposta de Craig Ringer que um não superusuário pode usar diretamente:
pg_roles
é essencialmente uma visãopg_authid
acessível ao público, pois não revela senhas, ao contrário dopg_authid
. A baseoid
é mesmo exportada para a vista. Quando não precisa de senhas, não faz sentido criar a função dedicada de propriedade do superusuário.Versão curta:
Aqui usamos uma versão de
pg_has_role
que leva um nome de função como assunto e função oid para testar a associação , passandomember
o modo para que testamos associações herdadas.A vantagem de usar
pg_has_role
é que ele usa os caches internos de informações de função do PostgreSQL para atender rapidamente às consultas de associação.Você pode querer envolver isso em uma
SECURITY DEFINER
função, poispg_authid
tem acesso restrito. Algo como:Você pode usar
pg_get_userbyid(oid)
para obter o nome da função do oid sem a necessidade de consultarpg_authid
:Aqui está a minha opinião sobre isso. Funciona para um usuário específico ou para todos os usuários.
Eu acredito que isso vai fazer isso
Se você preferir obter os nomes das funções, substitua o primeiro
oid
porrolname
.se você quiser saber todas as funções da sua função atualmente ativa: