Skip to content

Instantly share code, notes, and snippets.

@plockaby
Last active May 23, 2019 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plockaby/5398814a7d160a9597d5516482bf85ce to your computer and use it in GitHub Desktop.
Save plockaby/5398814a7d160a9597d5516482bf85ce to your computer and use it in GitHub Desktop.
Show ownership of everything in a PostgreSQL database except databases and "large objects".
SELECT z.schema,
z.name,
z.owner,
z.type,
z.objuser,
z.privilege_aggregate,
z.privilege,
CASE z.privilege
WHEN '*'::text THEN 'GRANT'::text
WHEN 'r'::text THEN 'SELECT'::text
WHEN 'w'::text THEN 'UPDATE'::text
WHEN 'a'::text THEN 'INSERT'::text
WHEN 'd'::text THEN 'DELETE'::text
WHEN 'D'::text THEN 'TRUNCATE'::text
WHEN 'x'::text THEN 'REFERENCES'::text
WHEN 't'::text THEN 'TRIGGER'::text
WHEN 'X'::text THEN 'EXECUTE'::text
WHEN 'U'::text THEN 'USAGE'::text
WHEN 'C'::text THEN 'CREATE'::text
WHEN 'c'::text THEN 'CONNECT'::text
WHEN 'T'::text THEN 'TEMPORARY'::text
ELSE ('Unknown: '::text || z.privilege)
END AS privilege_pretty
FROM ( SELECT y.schema,
y.name,
y.owner,
y.type,
CASE
WHEN (NOT (COALESCE(y.objuser, ''::text) IS DISTINCT FROM ''::text)) THEN 'public'::text
ELSE y.objuser
END AS objuser,
regexp_split_to_table(y.privilege_aggregate, '\s*'::text) AS privilege,
y.privilege_aggregate
FROM ( SELECT x.schema,
x.name,
x.owner,
x.type,
regexp_replace(x.privileges, '/.*'::text, ''::text) AS privileges,
(regexp_split_to_array(regexp_replace(x.privileges, '/.*'::text, ''::text), '='::text))[1] AS objuser,
(regexp_split_to_array(regexp_replace(x.privileges, '/.*'::text, ''::text), '='::text))[2] AS privilege_aggregate
FROM ( SELECT NULL::name AS schema,
(n.nspname)::text AS name,
pg_get_userbyid(n.nspowner) AS owner,
'schema'::text AS type,
regexp_split_to_table(array_to_string(n.nspacl, ','::text), ','::text) AS privileges
FROM pg_namespace n
WHERE ((n.nspname !~ '^pg_'::text) AND (n.nspname <> 'information_schema'::name))
UNION ALL
SELECT n.nspname AS schema,
((((p.proname)::text || '('::text) || pg_get_function_arguments(p.oid)) || ')'::text) AS name,
pg_get_userbyid(p.proowner) AS owner,
CASE
WHEN (p.prokind = 'a'::"char") THEN 'aggregate'::text
WHEN (p.prokind = 'w'::"char") THEN 'window'::text
WHEN (p.prorettype = ('trigger'::regtype)::oid) THEN 'function'::text
ELSE 'function'::text
END AS type,
regexp_split_to_table(array_to_string(p.proacl, ','::text), ','::text) AS privileges
FROM (pg_proc p
JOIN pg_namespace n ON ((n.oid = p.pronamespace)))
WHERE ((n.nspname <> 'pg_catalog'::name) AND (n.nspname <> 'information_schema'::name))
UNION ALL
SELECT n.nspname AS schema,
(c.relname)::text AS name,
pg_get_userbyid(c.relowner) AS owner,
CASE c.relkind
WHEN 'r'::"char" THEN 'table'::text
WHEN 'v'::"char" THEN 'view'::text
WHEN 'm'::"char" THEN 'materialized view'::text
WHEN 'i'::"char" THEN 'index'::text
WHEN 'S'::"char" THEN 'sequence'::text
WHEN 'f'::"char" THEN 'foreign table'::text
WHEN 'c'::"char" THEN 'type'::text
ELSE NULL::text
END AS type,
regexp_split_to_table(array_to_string(c.relacl, ','::text), ','::text) AS privileges
FROM (pg_class c
JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
WHERE ((n.nspname <> 'pg_catalog'::name) AND (n.nspname <> 'information_schema'::name) AND (n.nspname !~ '^pg_toast'::text))
UNION ALL
SELECT NULL::name AS schema,
(s.srvname)::text AS name,
pg_get_userbyid(s.srvowner) AS owner,
'foreign server'::text AS type,
regexp_split_to_table(array_to_string(s.srvacl, ','::text), ','::text) AS privileges
FROM pg_foreign_server s
UNION ALL
SELECT NULL::name AS schema,
(f.fdwname)::text AS name,
pg_get_userbyid(f.fdwowner) AS owner,
'foreign data wrapper'::text AS type,
regexp_split_to_table(array_to_string(f.fdwacl, ','::text), ','::text) AS privileges
FROM pg_foreign_data_wrapper f
UNION ALL
SELECT n.nspname AS schema,
t.typname AS name,
pg_get_userbyid(t.typowner) AS owner,
'domain'::text AS type,
regexp_split_to_table(array_to_string(t.typacl, ','::text), ','::text) AS privileges
FROM (pg_type t
JOIN pg_namespace n ON ((n.oid = t.typnamespace)))
WHERE ((t.typtype = 'd'::"char") AND (n.nspname <> 'pg_catalog'::name) AND (n.nspname <> 'information_schema'::name))
UNION ALL
SELECT NULL::name AS schema,
l.lanname AS name,
pg_get_userbyid(l.lanowner) AS owner,
'language'::text AS type,
regexp_split_to_table(array_to_string(l.lanacl, ','::text), ','::text) AS privileges
FROM pg_language l
WHERE (l.lanplcallfoid <> (0)::oid)
UNION ALL
SELECT NULL::name AS schema,
t.spcname AS name,
pg_get_userbyid(t.spcowner) AS owner,
'tablespace'::text AS type,
regexp_split_to_table(array_to_string(t.spcacl, ','::text), ','::text) AS privileges
FROM pg_tablespace t) x) y) z;
@plockaby
Copy link
Author

FYI this has only been tested against PostgreSQL 11.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment