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:
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;
GRANT'ing SELECT (or USAGE) on the sequence is not sufficient if it's contained in a schema for which the user has no permission. I believe that's the case because your schema named public
is not public. If it was, it would have permissions that would look like that:
test=> \dn+
List of schemas
Name | Owner | Access privileges | Description
--------+----------+----------------------+------------------------
public | postgres | postgres=UC/postgres+| standard public schema
| | =UC/postgres |
as opposed to the lack of access privileges shown in the question.
This is also consistent with the fact that the same commands work in you other instances: presumably the schema public of these other databases is the original, not a dropped/recreated-differently version or with its permissions removed.
As possible solutions, consider doing, as the owner of the schema:
GRANT ALL ON SCHEMA public TO public;
or the more limited
GRANT ALL ON SCHEMA public TO new_role;
or the even more limited
GRANT USAGE ON SCHEMA public TO new_role;
Best Answer
As I know there is no possibility to restrict access to the DB metadata at least for reading in PostgreSQL.
As an alternative you can to create another DB for login(s) and use foreign-data wrapper to access to the desired object(s) in the your main DB.
Here is a simple scenario (not fully tested):
Login to the main DB and create test table:
Create another DB for login(s):
Create user:
Now login to the newely created DB with user
postgres
and create FDW:Theoretically thats all. You can use
testrole
to connect to thelogindb
and to insert data into the tablet
in the main DBpostgres
. And 'testrole' can not to connect to the main DB and see anything in it.