列出PostgreSQL中物化视图的授予和权限

Luk*_*pan 12 postgresql privileges materialized-views information-schema

我需要确定当前为我的数据库中的某些物化视图授予的权限.

对表或标准视图执行此操作的查询非常简单:

SELECT grantee, string_agg(privilege_type, ', ') AS privileges
FROM information_schema.table_privileges
WHERE table_schema = 'some_schema' AND table_name = 'some_table'
GROUP by grantee;
Run Code Online (Sandbox Code Playgroud)

也就是说,物化视图似乎没有类似的表格.PostgreSQL在哪里存储这些信息?

kli*_*lin 5

在Postgres 系统目录中,是有关安装和数据库的完整信息的基本集合。系统目录是最可靠的信息源。 信息模式作为辅助功能基于系统目录,并提供其与其他RDBM的兼容性:

信息模式是在SQL标准中定义的,因此可以预期是可移植的并保持稳定-与系统目录不同,后者是PostgreSQL特有的,是根据实现问题进行建模的。但是,信息模式视图不包含有关PostgreSQL特定功能的信息。查询那些您需要查询系统目录或其他特定于PostgreSQL的视图。

物化视图不是SQL标准的对象,因此信息架构不包含有关它们的信息。

系统目录pg_class在此列中包含有关特权的所有信息relacl

如果列是null所有者,则所有者拥有所有特权。

空字符串作为用户名acl字符串手段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)
Run Code Online (Sandbox Code Playgroud)

您需要一个函数以可读格式显示特权:

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 
$$;
Run Code Online (Sandbox Code Playgroud)

使用:

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)
Run Code Online (Sandbox Code Playgroud)