Find objects linked to a PostgreSQL role
Answer to question asked
To look for the function in the error message and its owner:
SELECT oid::regprocedure AS function
, pg_get_userbyid(proowner) AS owner
FROM pg_proc
WHERE oid = 'text(boolean)'::regprocedure;
Related:
- DROP FUNCTION without knowing the number/type of parameters?
Actual problem
The error message says:
DETAIL: privileges for function text(boolean)
It's not about ownership but about privileges.
The manual for DROP ROLE
:
Before dropping the role, you must drop all the objects it owns (or reassign their ownership) and revoke any privileges the role has been granted on other objects.
And for ALTER DEFAULT PRIVILEGES
:
If you wish to drop a role for which the default privileges have been altered, it is necessary to reverse the changes in its default privileges or use
DROP OWNED
BY to get rid of the default privileges entry for the role.
It also looks like you only executed REASSIGN OWNED
in one DB, but the manual instructs:
Because
REASSIGN OWNED
does not affect objects within other databases, it is usually necessary to execute this command in each database that contains objects owned by a role that is to be removed.
Bold emphasis mine.
And you restricted your commands with IN SCHEMA public
. Drop that clause to target the whole DB. But don't bother, there is a ...
Simple solution with DROP OWNED
REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;
All the role's objects changed ownership to postgres
with the first command and are safe now. The wording of DROP OWNED
is a bit misleading, since it also gets rid of all privileges and default privileges. The manual for DROP OWNED
:
DROP OWNED
drops all the objects within the current database that are owned by one of the specified roles. Any privileges granted to the given roles on objects in the current database and on shared objects (databases, tablespaces) will also be revoked.
Repeat in all relevant DBs, then you can move in for the kill:
DROP ROLE user1;
The query below lists objects with owners. For all privileges we actually need more.
--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT
n.nspname AS schema_name,
c.relname AS rel_name,
c.relkind AS rel_kind,
pg_get_userbyid(c.relowner) AS owner_name
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
UNION ALL
-- functions (or procedures)
SELECT
n.nspname AS schema_name,
p.proname,
'p',
pg_get_userbyid(p.proowner)
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace