Postgresql - Select all tables from a specific user - postgresql

I have to list all the tables from a specific user.
When I query:
select * from pg_user;
I get all the users in my database. I want to check which tables one of those specific users can see.

pg_tables makes it really simple.
All tables:
select * from pg_tables where schemaname !~ '^pg_|^information_schema'
Or for a specific user/role:
select * from pg_tables where tableowner = 'specificuser'

user privilege on table:
select * from dba_tab_privs where GRANTEE ='username'
or
select *
from dba_tab_privs
where GRANTEE ='put user name'
and privilege = 'SELECT';
Note: In place of username you to have to replace with the user id.
In case of PostgreSQL:
select has_table_privilege('postgres','table1','select');

Related

How to check if Redshift user can alter table

In Redshift, I am checking Users' grants. How do I know if they can alter tables?
I can know if they can drop tables because "Only the owner of the table, the schema owner, or a superuser can drop a table." - https://docs.aws.amazon.com/redshift/latest/dg/r_DROP_TABLE.html No such qualification exists for alter table: https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
HAS_TABLE_PRIVILEGE provides info about other privileges, but not alter table: https://docs.aws.amazon.com/redshift/latest/dg/r_HAS_TABLE_PRIVILEGE.html
I got a response from AWS Support. tl;dr: alter table can be run by those, and only those, who can drop table.
"""
This is because, determining whether or not a user can alter a table, works in a similar way to that were one determines whether or not a given user can drop a table. That is, only the owner of the table, the schema owner, or a superuser can Alter a table. According to our documentation, "The right to modify or destroy an object is always the privilege of the owner only." [1].
[1] Default database user privileges - https://docs.aws.amazon.com/redshift/latest/dg/r_Privileges.html
Therefore, to see the users with alter table permissions for a specific table, there is need to determine the owner of that specific table by running the following command:
Kindly note that in this example, the 'sales' table is used. You can edit this as you see fit. To see all the table owners, the AND section of the WHERE clause can be removed.
====Query to see table owners====
SELECT n.nspname AS schema_name
, pg_get_userbyid(c.relowner) AS table_owner
, c.relname AS table_name
, CASE WHEN c.relkind = 'v' THEN 'view' ELSE 'table' END
AS table_type
, d.description AS table_description
FROM pg_class As c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_tablespace t ON t.oid = c.reltablespace
LEFT JOIN pg_description As d
ON (d.objoid = c.oid AND d.objsubid = 0)
WHERE c.relkind IN('r', 'v')
AND c.relname = 'sales'
ORDER BY n.nspname, c.relname;
You can also see all the superusers who have permissions to Alter table by running the following query:
====Query to see superusers====
SELECT usename FROM pg_user WHERE usesuper = 'true';
The combination of both results will enable you to see all the users which have alter table permissions.
"""

Get the list of users who are using database/schema/table

There is one use case in my project where i want to show the user who has got the access to use that database/schema/table in postgresql. Suppose I have created a database employee. So I want list the users who are accessing this database. Same for schema and tables. I tried this:
SELECT
*
FROM
information_schema.tables
WHERE
table_schema not in ('pg_catalog', 'information_schema') AND
table_schema not like 'pg_toast%'
But it gives information about current user has access to. I want the list of accessing users that are using that database/table/schema/column.
You can use the function has_table_privilege() to achieve what you want.
select has_table_privilege('user_name', 'schema.table', 'select');
More info here.
I suppose you need to be a superuser to get all results. Below shows all the users who have privileges, not necessarily whether they are accessing the tables.
Now you can tweak the query to join all users with list of tables -
SET search_path TO public,
schema1;
SELECT *,
usename,
has_table_privilege(usename, table_schema||'.'||table_name, 'select') as has_privilege
FROM SVV_TABLES
JOIN PG_USER
ON 1=1
WHERE table_schema = 'schema1';

Dropping a User, Handling Blank Default Privileges in Redshift, pg_default_acl

I am looking to reset permissions in a Development environment and I noticed two users I could not drop. I checked all of the permissions etc and the only reference to these users I found was in pg_default_acl.
select * from pg_default_acl;
Returns:
defacluser | defaclnamespace | defaclobjtype | defaclacl
----------------------------------------------------------------------
101 | 0 | r | {}
122 | 0 | r | {}
Are these empty permissions preventing me from dropping these users?
I ended up finding a resolution when I came across these admin scripts on github:
awslabs/amazon-redshift-utils
The issue ended up being default privileges that were granted to other users.
What is the exact error with which the drop fails? These users could be owning tables or views or functions.
You can find the tables with select * from pg_tables where tableowner in ('one', 'two');
The views with: select * from pg_views where viewowner in ('one', 'two');
The functions with: select * from pg_proc where proowner in (select usesysid from pg_user where usename in ('one', 'two'));
And then your users may own schemas too:
select * from pg_namespace where nspowner in (select usesysid from pg_user where usename in ('one', 'two'));

How to list indexes created for table in postgres

Could you tell me how to check what indexes are created for some table in postgresql ?
The view pg_indexes provides access to useful information about each index in the database, eg.
select *
from pg_indexes
where tablename not like 'pg%';
if you're in psql, then:
\d tablename
show Indexes, Foreign Keys and references...
You can use this query:
select tablename,indexname,tablespace,indexdef from pg_indexes where tablename = 'your_table_name';
where has tablename is a field in pg_indexes ,you an get an accurate indices by matching user defined table at 'your_table_name' at WHERE clause . This will give you the desired details.
You can find all the index related information inside the pg_indexes view. Sometimes, a table may be part of some schema ("owner") or might have had a different name in the past (see: PostgreSQL Rename Table).
So first find out what is the schema ("owner") of the table:
SELECT schemaname, tablename FROM pg_tables WHERE tablename='table_name';
and then query indexes on the table with either of these queries:
SELECT tablename, indexname FROM pg_indexes WHERE tablename='table_name';
-- or
SELECT * FROM pg_indexes WHERE tablename='schema_name.table_name';
As an alternative to all the above, you can also use \d:
\d table_name;
The command
\di
will list all indexes for the current schema.

Get DB owner's name in PostgreSql

I have DB "test" in PostgreSql. I want to write sql to get owner my database.
You can find such things in the system catalog
SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner"
FROM pg_catalog.pg_database d
WHERE d.datname = 'database_name'
ORDER BY 1;
If you use the psql command-line tool, you can simply use \l
You can use the combination of pg_database, pg_users system tables and current_database() function in this way:
SELECT u.usename
FROM pg_database d
JOIN pg_user u ON (d.datdba = u.usesysid)
WHERE d.datname = (SELECT current_database());
can just cast the role OID with magic ::regrole to give the role name of owner:
SELECT datdba::regrole FROM pg_database WHERE datname = 'test' ;
This work with database owned by group role:
SELECT
U.rolname
,D.datname
FROM
pg_roles AS U JOIN pg_database AS D ON (D.datdba = U.oid)
WHERE
D.datname = current_database();
Using pg_authid (as I did in my previous version) instead of pg_roles is limited to SuperUser because it holds password (see documentation):
Since this catalog contains passwords, it must not be publicly
readable. pg_roles is a publicly readable view on pg_authid that
blanks out the password field.
The follwing query displays info for all tables in the public schema:
select t.table_name, t.table_type, c.relname, c.relowner, u.usename
from information_schema.tables t
join pg_catalog.pg_class c on (t.table_name = c.relname)
join pg_catalog.pg_user u on (c.relowner = u.usesysid)
where t.table_schema='public';
source :http://cully.biz/2013/12/11/postgresql-getting-the-owner-of-tables/
Remember in SQL including postgres that you have a heirarchy within a given sql server instance: catalog/db > schema > tables
When looking for perms/metadata for within a catalog you want to look at information_schema
Example: information_schema.role_table_grants for table perms
Example: information_schema.role_usage_grants for SEQUENCE/schema perms
https://www.postgresql.org/docs/current/information-schema.html
For catalog/db-level config/meta, you need to look another level up in pg_catalog.
https://www.postgresql.org/docs/current/catalogs.html
Example:
SELECT dbs.datname, roles.rolname
FROM pg_catalog.pg_database dbs, pg_catalog.pg_roles roles
WHERE dbs.datdba = roles.oid;
pg_catalog.pg_database.datdba has ID of owner role.
pg_catalog.pg_roles.oid has ID of owner role (join)
pg_catalog.pg_roles.rolname has name/string of owner role