Get tables from schema - amazon-redshift

I have one database named dev. Inside it I have schema named test_spect. The schema consists of some tables. The test_spect is not public. How to get the table name and its data from test_spect. When I run
\dt test_spect.*
It says
No matching relations found.
How to solve this?

Have you tried with a query on the system tables?
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i' AND nspname !~ '^pg_toast'
--## change here your schema
AND nspname = 'public'
--##
ORDER BY pg_total_relation_size(C.oid) DESC;
EDIT
The same query without the pg_total_relation_size function:
SELECT nspname || '.' || relname AS "relation"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind = 'r' AND nspname !~ '^pg_toast'
AND nspname = 'public'
ORDER BY relname

By default you're in the public schema. You need to navigate to your schema using
set SEARCH_PATH to test_spect;
try \d after that.

Related

Connecting Microstrategy Cube to a Postgres Materialized View

I have created a Materialized View in a Postgres Database. When I am creating my microstrategy cube connection to this Postgres Database, I am unable to see this Materialized View.
Can anyone help me to understand why I am unable to see this?
Thanks
You need to edit the read settings for your Warehouse Catalog.
Location: Schema->Warehouse Catalog Options->Catalog->Read Settings
Query for tables:
SELECT n.nspname as NAME_SPACE,
c.relname as TAB_NAME
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind in ('v', 'm', 'r', 'p', '')
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
ORDER BY 1,2
Column Query:
hanged to LEFT JOIN in on table INFORMATION_SCHEMA.COLUMNS (no issues for me so far)
SELECT DISTINCT
nspname AS NAME_SPACE,
relname AS TAB_NAME,
attname AS COL_NAME,
typname AS DATA_TYPE,
COALESCE(B.CHARACTER_MAXIMUM_LENGTH, attlen) AS DATA_LEN,
NUMERIC_PRECISION AS DATA_PREC,
NUMERIC_SCALE AS DATA_SCALE
FROM
pg_attribute A
JOIN
pg_class C
ON
A.attrelid = C.oid
JOIN
pg_namespace N
ON
C.relnamespace = N.oid
JOIN
pg_type T
ON
A.atttypid = T.oid
LEFT OUTER JOIN
INFORMATION_SCHEMA.COLUMNS B
ON
A.attname = B.COLUMN_NAME
AND C.relname = B.TABLE_NAME
AND N.nspname = B.TABLE_SCHEMA
WHERE
relname IN (#TABLE_LIST#)
AND attnum > 0
ORDER BY
1,
2,
3
Especially the columns query could be improved but until now I haven't looked back at this as it works fine.
Reason for all of this can be found in the following discussion: Materialized views don't show up in information_schema.
Found a workaround for this...
You can create the view as a standard view, connect this to Microstrategy, and then delete the view and created as a Materialized View. This will then pick up the newly created Materialized view as long as you keep the same name.

Get information about table partitions

I have a partitioned table out of main table using range.
CREATE TABLE public.partition1 PARTITION OF public.maintable
FOR VALUES FROM ('2017-01-01 00:00:00') TO ('2050-01-01 00:00:00')
How can i get the Values range information using a query to postgres.
I have used a query that at least gives me information for the main and partitioned tables, but i cannot seem to find a way to access the value range
FROM ('2017-01-01 00:00:00') TO ('2050-01-01 00:00:00')
assigned to table partition1
Query used to get partition table information
WITH RECURSIVE partition_info
(relid,
relname,
relsize,
relispartition,
relkind) AS
(
(SELECT oid AS relid,
relname,
pg_relation_size(oid) AS relsize,
relispartition,
relkind
FROM pg_catalog.pg_class
WHERE relname = 'completedorders' AND
relkind = 'p')
UNION ALL
(SELECT
c.oid AS relid,
c.relname AS relname,
pg_relation_size(c.oid) AS relsize,
c.relispartition AS relispartition,
c.relkind AS relkind
FROM partition_info AS p,
pg_catalog.pg_inherits AS i,
pg_catalog.pg_class AS c
WHERE p.relid = i.inhparent AND
c.oid = i.inhrelid AND
c.relispartition = true)
)
SELECT * FROM partition_info;
The following query provides the information about partitions as well. From there on its just string manipulation in order to get further information.
Note: you will have to change the name of the table in the query.
with recursive inh as (
select i.inhrelid, null::text as parent
from pg_catalog.pg_inherits i
join pg_catalog.pg_class cl on i.inhparent = cl.oid
join pg_catalog.pg_namespace nsp on cl.relnamespace = nsp.oid
where nsp.nspname = 'public' ---<< change table schema here
and cl.relname = 'tablename' ---<< change table name here
union all
select i.inhrelid, (i.inhparent::regclass)::text
from inh
join pg_catalog.pg_inherits i on (inh.inhrelid = i.inhparent)
)
select c.relname as partition_name,
n.nspname as partition_schema,
pg_get_expr(c.relpartbound, c.oid, true) as partition_expression,
pg_get_expr(p.partexprs, c.oid, true) as sub_partition,
parent,
case p.partstrat
when 'l' then 'LIST'
when 'r' then 'RANGE'
end as sub_partition_strategy
from inh
join pg_catalog.pg_class c on inh.inhrelid = c.oid
join pg_catalog.pg_namespace n on c.relnamespace = n.oid
left join pg_partitioned_table p on p.partrelid = c.oid
order by n.nspname, c.relname

How to list all tables and their creators (or owners) in Redshift

I thought it is straightforward but I couldn't find a way to list all tables and their creators (or owners) in Redshift. Any help/insight is welcome.
It was pg_tables table and here is the SQL:
select tablename, tableowner From pg_tables
You can list Redshift tables, views and their owners by running this script:
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')
ORDER BY n.nspname, c.relname ;

Using default sql tables to find columns present in a table

I have a postgresql database set up with clients data split by schema.
Within sql I would like to identify for the table products which columns containing the string "id" exist
I'm trying to use the pg_... tables to identify these columns, but the below query appears to be bringing back results from across schemas despite the restriction on table_schema
SELECT *
FROM pg_class c
INNER JOIN pg_attribute a ON a.attrelid = c.oid
INNER JOIN pg_type t ON a.atttypid = t.oid
INNER JOIN information_schema.tables sch ON c.relname = sch.table_name
WHERE c.relname = 'products'
AND a.attnum > 0
AND a.attname LIKE '%id%'
AND table_schema = 'schema001'
I guess the schemas could be set up incorrectly or the where clause is incorrect - any help would be appreciated
Use pg_namespace and drop the information_schema:
SELECT nspname, relname, attname
FROM pg_class c
INNER JOIN pg_namespace n ON n.oid = c.relnamespace
INNER JOIN pg_attribute a ON a.attrelid = c.oid
INNER JOIN pg_type t ON a.atttypid = t.oid
WHERE c.relname = 'products'
AND a.attnum > 0
AND a.attname LIKE '%id%'
AND n.nspname = 'schema001';

Get table and column "owning" a sequence

I can run the following line:
ALTER SEQUENCE seqName OWNED BY table.id;
How can I get the 'owner' set by OWNED BY for a sequence (in this case: table.id)?
You may use following query:
select s.relname as seq, n.nspname as sch, t.relname as tab, a.attname as col
from pg_class s
join pg_depend d on d.objid=s.oid and d.classid='pg_class'::regclass and d.refclassid='pg_class'::regclass
join pg_class t on t.oid=d.refobjid
join pg_namespace n on n.oid=t.relnamespace
join pg_attribute a on a.attrelid=t.oid and a.attnum=d.refobjsubid
where s.relkind='S' and d.deptype='a'
It returns all sequences with owner information. Just filter them in WHERE clause and that's it.
Get the "owning" table and column
ALTER SEQUENCE seqName OWNED BY table.id;
Your ALTER SEQUENCE statement causes an entry in the system catalog pg_depend with the dependency type (deptype) 'a' and a refobjsubid greater than 0, pointing to the attribute number (attnum) in pg_attribute. With that knowledge you can devise a simple query:
SELECT d.refobjid::regclass, a.attname
FROM pg_depend d
JOIN pg_attribute a ON a.attrelid = d.refobjid
AND a.attnum = d.refobjsubid
WHERE d.objid = 'public."seqName"'::regclass -- your sequence here
AND d.refobjsubid > 0
AND d.classid = 'pg_class'::regclass;
Double quotes ("") are only needed for otherwise illegal names (mixed case, reserved words, ...).
No need to assert that refclassid is of type regclass since the join to pg_attribute does that automatically.
No need to assert that the sequence is a sequence since schema-qualified object names are unique across the database.
No need to join to pg_class or pg_namespace at all.
The schema name is only needed to disambiguate or if it's not in the search_path.
The same table name (or sequence name for that matter) can be used in multiple schemas. A cast to the object identifier type regclass observes the current search_path to pick the best match if you omit the schema qualification. If the table is not visible, you get an error message.
What's more, a regclass type is displayed as text to the user automatically. (If not, cast to text.) The schema-name is prepended automatically where necessary to be unambiguous in your session.
Get the actual "owner" (the role)
To get the role owning a specific sequence, as requested:
SELECT c.relname, u.usename
FROM pg_class c
JOIN pg_user u ON u.usesysid = c.relowner
WHERE c.oid = '"seqName"'::regclass; -- your sequence here
I was able to list the table and corresponding sequence for a particular column using the following SQL statement:
SELECT table_schema
, table_name
, column_name
, LTRIM(RTRIM(RTRIM(column_default, '::regclass)'),''''),'nextval(''') AS SEQUENCE_NAME
FROM information_schema.columns
WHERE column_default like '%nextval%';
SELECT c.relname,u.usename
FROM pg_class c, pg_user u
WHERE c.relowner = u.usesysid and c.relkind = 'S'
AND relnamespace IN (
SELECT oid
FROM pg_namespace
WHERE nspname NOT LIKE 'pg_%'
AND nspname != 'information_schema'
);
I use that query for get all queries.
Change CTE to filter the result
WITH table_with_sequence as (
SELECT
d.refobjid::regclass::text tablename,
c.relname::text sequencename,
np.nspname::text schemaname,
a.attname::text attname,
u.usename::text
FROM
pg_depend d
INNER JOIN pg_class c ON c.oid = d.objid
AND c.relkind = 'S'
INNER JOIN pg_namespace np ON np.oid = c.relnamespace
AND (np.nspname NOT LIKE 'pg_%'
AND np.nspname != 'information_schema')
INNER JOIN pg_user u ON u.usesysid = c.relowner
INNER JOIN pg_attribute a ON a.attrelid = d.refobjid
AND a.attnum = d.refobjsubid
)
SELECT
'ALTER SEQUENCE '|| QUOTE_LITERAL(QUOTE_IDENT(schemaname) || '.' || QUOTE_IDENT(sequencename)) ||' OWNED BY ' || tablename || '.' || QUOTE_IDENT(attname)
FROM table_with_sequence