postgres select all tables in the current search path? - postgresql

I need to find all the visible tables in my current schema search path. I tried:
SELECT *
FROM pg_tables
AND schemaname IN (SHOW search_path)
but it errors with:
PGError: ERROR: syntax error at or near "search_path"
LINE 3: AND schemaname IN (SHOW search_path)

The pg_*_is_visible() set of functions is provided for this purpose. Here is one way to use them:
SELECT * FROM pg_class WHERE relkind IN ('r', 'v') AND pg_table_is_visible(oid);

You can get the current schemas using CURRENT_SCHEMAS() function. It will resolve any references in the search path for you (e.g. $user)
SELECT * FROM pg_tables WHERE schemaname = ANY (CURRENT_SCHEMAS(false));
You could also use the more standard information_schema pseudo-schema.
SELECT * FROM information_schema.tables WHERE table_schema = ANY (CURRENT_SCHEMAS(false));

Related

Redshift - How to display dependencies that CASCADE will delete?

When deleting table in Redshift I get an error message :
Amazon Invalid operation: cannot drop table
rawdata.bss_edw_customer_account because other objects depend on it;
I don't want to use CASCADE because I don't know which other tables/views it will kill. How do I find out which tables or views are dependent on the table I want to drop? I want to make sure I don't step on somebody else's work.
Thanks
Redshift Admin Views for object [1] and constraint [2] dependencies can help in identifying dependent objects. You can also create the find_depend view as described in the DROP table documentation [3] to view any dependencies.
I also found that these views may not always list materialized views as dependent objects. If you have created any MV in the past, then you might want to check for dependencies using the view DDLs. The following query could help:
select schemaname, viewname from pg_views where schemaname not like 'pg_catalog' and schemaname not like 'information_schema' and definition like '%<tablename>%';
[1] https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_object_dependency.sql
[2] https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_constraint_dependency.sql
[3] https://docs.aws.amazon.com/redshift/latest/dg/r_DROP_TABLE.html
If you need a more general overview of the (materialized) view dependencies in a schema you can use the following snippit. Just replace schema_name with the name of the schema. If you need to display dependencies across schemas this should be easily doable by adapting the regex or by doing a union.
create view admin.v_view_dependencies_fixed as (
with h1 as (
select generate_series as i
from generate_series(1, 100) -- we can use this since the query only touches the leader node
),
h2 as (
select schemaname as dependent_schema,
viewname as dependent_view,
schemaname || '.' || viewname as dependent_full,
regexp_substr(definition, 'schema_name\\.\\w+', 1, i) as dependency
from pg_views
cross join h1
where schemaname = 'schema_name'
and dependency is not null
and dependency != ''
)
select distinct
dependent_full,
dependent_schema,
dependent_view,
dependency as source_full,
split_part(dependency, '.', 1) as source_schema,
split_part(dependency, '.', 2) as source_object
from h2
where dependent_full != source_full
);

Phantom Postgres table exists but can't be dropped?

I seem to have some sort of phantom table in Postgres.
Suppose I do the following:
select * from information_schema.tables where table_schema = 'public';
I get:
table_name | table_type | ...
phantom_table BASE TABLE
...
So, I run:
drop table phantom_table cascade;
And I get:
ERROR: table "phantom_table" does not exist
Things I've tried:
Checking for spelling errors and making sure the schema is correct (I've even copied/pasted table name out of information schema query results).
vacuum
Reconnecting.
Killing other running processes from my user (nobody else is using the DB).
Checking for active locks on the table (there aren't any).
Anybody have any other ideas for things I should try?
You probably have some white space at the end of the name.
The easiest way is to let the format() function generate you the correct table name and statement:
select format('drop table %I.%I;', table_schema, table_name) as drop_statement
from information_schema.tables
where table_schema = 'public'
and table_name like '%phantom%';
Edit: it seems that psql on Windows isn't able to handle an identifier with a new line in a drop statement (it does when creating the table however).
To workaround that, you can use a DO block:
do
$$
declare
l_stmt text;
begin
select format('drop table %I.%I;', table_schema, table_name) as drop_statement
into l_stmt
from information_schema.tables
where table_schema = 'public'
and table_name like '%phantom%';
execute l_stmt;
end;
$$
;
Note this code assumes that only a single table with that name exists.

PostgreSQL check if table exist throwing "relation does not exist" error

In PostgreSQL I try to check if table exist:
SELECT EXISTS (SELECT * FROM table_name);
And it throwing an error. How can I check if table already exists so the result will be boolean? Because currently I can achieve the same with try-catch (enters to catch if not exist) instead of if-else on the result...
Thanks,
Either of these should work, though depending on how your permissions are set up you may not have access to the tables:
SELECT EXISTS (SELECT relname FROM pg_class WHERE relname = 'table_name');
SELECT EXISTS (SELECT table_name FROM information_schema.tables WHERE table_name = 'table_name');

postgresql error when attempting to do a select all from table

I am trying to do the postgresql equivalent of mysql select * from table on a postgresql specific database. I can find the name of the table I need within that database when I do:
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
But when I try a select all on the table, I get:
SELECT * from Sample;
SELECT * from Sample;
ERROR: relation "sample" does not exist
LINE 1: SELECT * from Sample;
^
Any ideas?
Postgresql is case sensitive.
I usually use all lower char for field, tables and functions.
Anyway, you can double quote them.
To full answer your question and see why and when useing quote, i suggest to read this specific section:
http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
The manes of the tables are stored in information_schema.tables so you have to see your table by using select * from information_schema.tables. IF your table_schema is "public"
try for a table select select * from public.sample, is your table_schema a differed schema chance it to the right one.
this link will help you Psotgresql doc
I tried single-quoting 'Sample' and it didn't work. Fixed by double-quoting "Sample".

PostgreSQL query to list all table names?

Is there any query available to list all tables in my Postgres DB.
I tried out one query like:
SELECT table_name FROM information_schema.tables
WHERE table_schema='public'
But this query returns views also.
How can i get only table names only, not views?
What bout this query (based on the description from manual)?
SELECT table_name
FROM information_schema.tables
WHERE table_schema='public'
AND table_type='BASE TABLE';
If you want list of database
SELECT datname FROM pg_database WHERE datistemplate = false;
If you want list of tables from current pg installation of all databases
SELECT table_schema,table_name FROM information_schema.tables
ORDER BY table_schema,table_name;
Open up the postgres terminal with the databse you would like:
psql dbname (run this line in a terminal)
then, run this command in the postgres environment
\d
This will describe all tables by name. Basically a list of tables by name ascending.
Then you can try this to describe a table by fields:
\d tablename.
Hope this helps.
Try this:
SELECT table_name
FROM information_schema.tables
WHERE table_schema='public' AND table_type='BASE TABLE'
this one works!
SELECT table_name
FROM information_schema.tables
WHERE table_type='BASE TABLE'
AND table_schema='public';
For MySQL you would need table_schema='dbName' and for MSSQL remove that condition.
Notice that "only those tables and views are shown that the current user has access to". Also, if you have access to many databases and want to limit the result to a certain database, you can achieve that by adding condition AND table_catalog='yourDatabase' (in PostgreSQL).
If you'd also like to get rid of the header showing row names and footer showing row count, you could either start the psql with command line option -t (short for --tuples-only) or you can toggle the setting in psql's command line by \t (short for \pset tuples_only). This could be useful for example when piping output to another command with \g [ |command ].
How about giving just \dt in psql? See https://www.postgresql.org/docs/current/static/app-psql.html.
select
relname as table
from
pg_stat_user_tables
where schemaname = 'public'
This will not work if track_activities is disabled
select
tablename as table
from
pg_tables
where schemaname = 'public'
Read more about pg_tables