在PostgreSQL中列出实体化视图的授予和权限

kuuvgm7e  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(396)

我需要确定当前为数据库中的某些示例化视图授予了哪些特权。
对表或标准视图执行此操作的查询非常简单:

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;

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

ujv3wf0j

ujv3wf0j1#

在Postgres中,system catalogs是关于安装和数据库的完整信息的基本集合。系统目录是最可靠的信息来源。Information schema作为辅助功能基于系统目录,并与其他RDBMS兼容:
信息模式是在SQL标准中定义的,因此可以预期是可移植的,并且保持稳定-不像系统目录,它是特定于PostgreSQL的,并且在实现关注点之后建模。然而,信息模式视图不包含关于PostgreSQL特定特性的信息;查询那些你需要查询的系统目录或其他PostgreSQL特定的视图。
物化视图不是SQL标准对象,因此信息模式不包含有关它们的信息。
系统目录pg_classrelacl列中包含有关权限的所有信息。
如果列是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)

你需要一个函数以 * 可读 * 格式显示权限:

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 
$$;

用途:

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)
rbl8hiat

rbl8hiat2#

根据klin的有益回答,我提出了一个视图,它列出了pg_class中出现的所有关系(表、视图、m)的所有特权的摘要。视图、索引、序列、外部表、复合类型):

CREATE VIEW show_privileges AS (
    SELECT
        grantee,
        string_agg(relname, ', ' ORDER BY relname) AS rel_names,
        privileges
    FROM (
        SELECT 
            relname,
            coalesce(nullif(s[1], ''), 'public') grantee, 
            (SELECT string_agg(privilege, ', ' ORDER BY privilege ASC)
                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 AS privilege
                    FROM regexp_split_to_table(s[2], '') ch
                ) s
            ) AS privileges
        FROM 
            pg_class
            JOIN pg_namespace ON pg_namespace.oid = relnamespace
            JOIN pg_roles ON pg_roles.oid = relowner,
            unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) AS acl,
            regexp_split_to_array(acl, '=|/') AS s
        WHERE nspname = 'public'
    ) AS t
    GROUP BY grantee, privileges
    ORDER BY grantee, privileges, rel_names
);

相关问题