W Postgresie system catalogs to podstawowy zestaw kompletnych informacji o instalacji i bazach danych. Katalogi systemowe są najbardziej wiarygodnym źródłem informacji. Information schema jako funkcji pomocniczej jest na podstawie katalogów systemowych i jest udostępniona dla zgodności z innymi RDBMS:
Schemat informacje są zdefiniowane w standardzie SQL, a zatem można oczekiwać, aby być przenośne i pozostają stabilne - w odróżnieniu od systemu katalogi, które są specyficzne dla PostgreSQL i są wzorowane na problemach implementacji. Widoki schematów informacji nie zawierają jednak informacji o funkcjach specyficznych dla PostgreSQL; zapytać o te, których potrzebujesz, aby zapytać o katalogi systemowe lub inne widoki specyficzne dla PostgreSQL.
Materializowane widoki nie są obiektami standardowymi SQL, dlatego schemat informacji nie zawiera informacji na ich temat.
Katalog systemowy pg_class
zawiera wszystkie informacje na temat uprawnień w kolumnie relacl
.
Jeśli kolumna jest null
, wówczas właściciel ma wszystkie uprawnienia.
Pusty ciąg znaków jako nazwa użytkownika w acl
ciąg oznacza 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)
Trzeba funkcję pokazać przywileje w czytelnej formacie:
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
$$;
Zastosowanie:
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)
Twoje zapytanie działa dla zwykłych widoków, ale nie dla zmaterializowanych widoków. –