PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Répertorier les octrois et privilèges pour une vue matérialisée dans PostgreSQL

Dans Postgres catalogues système sont l'ensemble de base d'informations complètes sur l'installation et les bases de données. Les catalogues système sont la source d'informations la plus fiable.Schéma d'informations en tant que fonctionnalité auxiliaire est basée sur les catalogues système et est fournie pour la compatibilité avec d'autres RDBM :

Les vues matérialisées ne sont pas des objets standard SQL, par conséquent, le schéma d'informations ne contient pas d'informations à leur sujet.

Le catalogue système pg_class contient toutes les informations sur les privilèges dans la colonne relacl .

Si la colonne est null alors le propriétaire a tous les privilèges.

Une chaîne vide comme nom d'utilisateur dans acl chaîne signifie public .

create materialized view test_view as select 1;
grant select on test_view to public;
grant delete on test_view to a_user;

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    s[2] as privileges
from 
    pg_class c
    join pg_namespace n on n.oid = relnamespace
    join pg_roles r on r.oid = relowner,
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s
where nspname = 'public' and relname = 'test_view';

 grantee  | privileges 
----------+------------
 postgres | arwdDxt
 public   | r
 a_user   | d
(3 rows)

Vous avez besoin d'une fonction pour afficher les privilèges en lisible format :

create or replace function priviliges_from_acl(text)
returns text language sql as $$
    select string_agg(privilege, ', ')
    from (
        select 
            case ch
                when 'r' then 'SELECT'
                when 'w' then 'UPDATE'
                when 'a' then 'INSERT'
                when 'd' then 'DELETE'
                when 'D' then 'TRUNCATE'
                when 'x' then 'REFERENCES'
                when 't' then 'TRIGGER'
            end privilege
        from
            regexp_split_to_table($1, '') ch
    ) s 
$$;

Utiliser :

select 
    coalesce(nullif(s[1], ''), 'public') as grantee, 
    priviliges_from_acl(s[2]) as privileges
from 
    pg_class c
    join pg_namespace n on n.oid = relnamespace
    join pg_roles r on r.oid = relowner,
    unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl, 
    regexp_split_to_array(acl, '=|/') s
where nspname = 'public' and relname = 'test_view';

 grantee  |                          privileges                           
----------+---------------------------------------------------------------
 postgres | INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER
 public   | SELECT
 a_user   | DELETE
(3 rows)