Execute isso em todos os bancos de dados do mesmo cluster em que a função pode possuir qualquer coisa ou ter privilégios concedidos:
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
postgres
sendo o superusuário padrão, você pode escolher qualquer outro. Ele possuirá objetos atualmente pertencentes à função antiga. Imediatamente após REASSIGN OWNED
, não há objetos restantes que seriam propriedade pelo mesmo usuário. Pode parecer pouco intuitivo executar DROP OWNED
. A redação do comando é enganosa, pois também revoga todos os privilégios e privilégios padrão para a função no mesmo banco de dados. O manual:
A ênfase em negrito é minha.
Você ainda precisa executá-lo em todos os bancos de dados onde a função possui qualquer coisa ou tem privilégios concedidos. O manual:
Por fim, execute (uma vez):
DROP role some_role_name;
As funções são armazenadas em um catálogo do sistema em todo o cluster, enquanto a propriedade e os privilégios nos objetos são armazenados em catálogos do sistema local do banco de dados.
Explicação detalhada nesta resposta relacionada:
Há uma página relacionada no manual com instruções .
Automação total
Não existe um comando único para fazer tudo. Mas você pode deixar o Postgres gerar um script psql completo para você.
As dependências para funções são armazenadas no catálogo do sistema
pg_shdepend
:Como nós (potencialmente) precisamos nos conectar a diferentes bancos de dados, precisamos de uma combinação de meta-comandos psql (
\c my_database
) e comandos SQL DDL como mostrado acima. Crie esta função em algum lugar em seu cluster de banco de dados uma vez:CREATE OR REPLACE FUNCTION f_generate_ddl_to_remove_role(dead_role_walking regrole)
RETURNS text
LANGUAGE sql AS
$func$
SELECT concat_ws(
E'\n'
,(SELECT string_agg(format(E'\\c %I\nREASSIGN OWNED BY %2$s TO postgres; DROP OWNED BY %2$s;'
, d.datname, dead_role_walking)
, E'\n')
FROM (
SELECT DISTINCT dbid
FROM pg_shdepend
WHERE refobjid = dead_role_walking
) s
JOIN pg_database d ON d.oid = s.dbid)
, format(E'DROP role %s;\n', dead_role_walking)
)
$func$;
Ligar:
SELECT f_generate_ddl_to_remove_role('some_role_name');
Produz uma string como:
\c my_db1
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
\c my_db2
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
DROP role some_role_name;
Ou, se a função não possuir nada e não tiver privilégios, apenas:
DROP role some_role_name;
Se você fornecer um nome de função inexistente, receberá um erro.
Copie a string (sem colocar aspas simples) para uma sessão psql aberta com um superusuário como
postgres
. Ou concatene um script bash com ele. Tudo feito. Existem várias respostas relacionadas com mais explicações para SQL dinâmico: