列出 PostgreSQL 中物化视图的授权和权限
List grants and privileges for a materialized view in PostgreSQL
我需要确定我的数据库中的某些具体化视图当前被授予了哪些权限。
为 table 或标准视图执行此操作的查询非常简单:
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;
就是说,对于物化视图似乎没有类似的 table。 PostgreSQL 在哪里存储这些信息?
在 Postgres system catalogs 中是关于安装和数据库的基本完整信息集。系统目录是最可靠的信息来源。
Information schema 作为一项基于系统目录的辅助功能,提供它是为了与其他 RDBM 兼容:
The information schema is defined in the SQL standard and can therefore be expected to be portable and remain stable — unlike the system catalogs, which are specific to PostgreSQL and are modeled after implementation concerns. The information schema views do not, however, contain information about PostgreSQL-specific features; to inquire about those you need to query the system catalogs or other PostgreSQL-specific views.
物化视图不是 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(, '') 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)
根据 klin 的有用回答,我想出了一个视图,列出了 pg_class
中出现的所有关系的所有权限的摘要(表、视图、m.views、索引、序列、外部所有角色的表、复合类型):
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
);
我需要确定我的数据库中的某些具体化视图当前被授予了哪些权限。
为 table 或标准视图执行此操作的查询非常简单:
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;
就是说,对于物化视图似乎没有类似的 table。 PostgreSQL 在哪里存储这些信息?
在 Postgres system catalogs 中是关于安装和数据库的基本完整信息集。系统目录是最可靠的信息来源。 Information schema 作为一项基于系统目录的辅助功能,提供它是为了与其他 RDBM 兼容:
The information schema is defined in the SQL standard and can therefore be expected to be portable and remain stable — unlike the system catalogs, which are specific to PostgreSQL and are modeled after implementation concerns. The information schema views do not, however, contain information about PostgreSQL-specific features; to inquire about those you need to query the system catalogs or other PostgreSQL-specific views.
物化视图不是 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(, '') 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)
根据 klin 的有用回答,我想出了一个视图,列出了 pg_class
中出现的所有关系的所有权限的摘要(表、视图、m.views、索引、序列、外部所有角色的表、复合类型):
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
);