列出 PostgreSQL 中物化视图的授权和权限
Posted
技术标签:
【中文标题】列出 PostgreSQL 中物化视图的授权和权限【英文标题】:List grants and privileges for a materialized view in PostgreSQL 【发布时间】:2016-12-08 06:53:23 【问题描述】:我需要确定当前为我的数据库中的某些物化视图授予了哪些权限。
对表或标准视图执行此操作的查询非常简单:
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 在哪里存储这些信息?
【问题讨论】:
您的查询确实适用于常规视图,但不适用于物化视图。 【参考方案1】:在 Postgres 中 system catalogs 是有关安装和数据库的完整信息的基本集合。系统目录是最可靠的信息来源。 Information schema 作为辅助功能基于系统目录并提供与其他 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)
您需要一个函数以可读格式显示权限:
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)
【讨论】:
非常感谢,这对您有很大帮助。我发现 PostgreSQL 允许您在物化视图上授予诸如 UPDATE、INSERT 和 DELETE 之类的权限非常有趣。仅仅是因为他们计划在未来支持这些行动吗? 这是 Postgres 特权系统的一个特点。通常,即使对象不适用,也可以授予特权。 “系统目录是最可靠的信息来源。” PostgreSQL 的信息模式视图在哪里返回不可靠的信息? 呼应@MikeSherrill'CatRecall 的观点,也许更准确地说系统目录是最权威的信息来源,或者最完整的 i> 信息来源?信息模式同样准确,只是不完整。对吗? @Wildcard - 正是这一点。我已经删除了我之前的评论,因为它有些误导。【参考方案2】:根据 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
);
【讨论】:
以上是关于列出 PostgreSQL 中物化视图的授权和权限的主要内容,如果未能解决你的问题,请参考以下文章