我需要确定在我的数据库中为某些物化视图授予的特权.
为表或标准视图执行此操作的查询非常简单:
- 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在哪里存储这些信息?
Postgres
system catalogs是有关安装和数据库的完整信息的基本信息.
Information schema作为辅助功能是基于系统目录,并提供与其他RDBM的兼容性.
系统目录是最可靠的信息来源.
Information schema作为辅助功能是基于系统目录,并提供与其他RDBM的兼容性.
系统目录是最可靠的信息来源.
您可以将information_schema.table_privileges视为基于pg_class和pg_roles的特定视图.
显然,在执行中必须有一个小错误(这是在正确的地方缺少一个字母的问题).
系统目录pg_class包含关于列relacl中所有权限的所有信息.
如果列为空,则所有者具有所有权限.
在acl字符串中用作用户名的空字符串表示公开.
- 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],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,'=|/') 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)