PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Descarte uma função com privilégios


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: