I know, information_schema is SQL standard, and RULES are Postgres SQL extensions.
Still, is there a way to list all availible rules using information_schema?
No, according to the documentation:
The information schema views do not,
however, contain information about
PostgreSQL-specific features; to
inquire about those you need to query
the system catalogs or other
PostgreSQL-specific views.
Please try
SELECT
n.nspname AS view_schema,
c.relname AS view_name,
r.rulename AS rule_name,
pg_get_ruledef(r.oid, true) AS compiled_definition,
d.description AS full_description,
CASE ev_type::integer
WHEN 2 THEN 'update'
WHEN 3 THEN 'insert'
WHEN 4 THEN 'delete'
END AS rule_event
FROM
pg_rewrite AS r
LEFT JOIN pg_class AS c ON c.oid = r.ev_class
LEFT JOIN pg_namespace AS n ON n.oid = c.relnamespace
LEFT JOIN pg_description AS d ON r.oid = d.objoid
WHERE TRUE
AND n.nspname != 'pg_catalog'
AND r.rulename <> '_RETURN' AND relkind = 'v'
ORDER BY r.rulename
Related
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.
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 ;
I need to query Redshift metadata to get a list of table columns that includes information whether the column is part of primary key or not.
There is a post already List columns with indexes in PostgreSQL that has an answer for PostgreSQL, however unfortunately, it fails on Redshift with "ERROR: 42809: op ANY/ALL (array) requires array on right side"
I figured out how to do it with the help of this https://bitbucket.org/zzzeek/sqlalchemy/pull-request/6/sqlalchemy-to-support-postgresql-80/diff
SELECT attname column_name, attnotnull,
format_type(atttypid, atttypmod) as column_type, atttypmod,
i.indisprimary as primary_key,
col_description(attrelid, attnum) as description
FROM pg_attribute c
LEFT OUTER JOIN pg_index i
ON c.attrelid = i.indrelid AND i.indisprimary AND
c.attnum = ANY(string_to_array(textin(int2vectorout(i.indkey)), ' '))
where c.attnum > 0 AND NOT c.attisdropped AND c.attrelid = :tableOid
order by attnum
The following worked for me:
SELECT n.nspname as schema_name,
t.relname as table_name,
i.relname as index_name,
c.contype as index_type,
a.attname as column_name,
a.attnum AS column_position
FROM pg_class t
INNER JOIN pg_index AS ix ON t.oid = ix.indrelid
INNER JOIN pg_constraint AS c ON ix.indrelid = c.conrelid
INNER JOIN pg_class AS i ON i.oid = ix.indexrelid
INNER JOIN pg_attribute AS a ON a.attrelid = t.oid
AND a.attnum= ANY(string_to_array(textin(int2vectorout(ix.indkey)),' ')::int[])
INNER JOIN pg_namespace AS n ON n.oid = t.relnamespace;
You can leverage the table DDL view AWS published a few months ago (https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql) by picking out the constraint component and parsing out the key columns:
select schemaname,tablename, substring(ddl,charindex('(',ddl)+1, charindex(')',ddl)-1-charindex('(',ddl))
from
(
SELECT
n.nspname AS schemaname
,c.relname AS tablename
,200000000 + CAST(con.oid AS INT) AS seq
,'\t,' + pg_get_constraintdef(con.oid) AS ddl
FROM
pg_constraint AS con
INNER JOIN pg_class AS c
ON c.relnamespace = con.connamespace
AND c.relfilenode = con.conrelid
INNER JOIN pg_namespace AS n
ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
ORDER BY seq
)
Note that this query also gives you foreign key columns. It's easy enough to filter those out by appending the query with
where ddl like '%PRIMARY KEY%'
Use below query:
select * from pg_table_def where tablename = 'mytablename'
This will give you all columns for table along with their data type , encoding and if it has sort key or dist key.
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';
I have created a SQL SELECT to get all enums and their values in a schema:
SELECT
t.typname, array_agg(e.enumlabel)
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typtype = 'e' AND n.nspname = 'public'
GROUP BY typname
I have put the select into a view so I dont have to write it everytime I want to call it. The only thing that bothers me is that if I rename the schema or use it in another schema I have to rewrite the name of the schema manually, check line 6 of the code:
WHERE t.typtype = 'e' AND n.nspname = 'public'
Public is hardtyped there. When selecting in postgres, is there a "global" variable saying from which schema you select? I was not able to find any.
Thanks
PS: I use postgres 8.4
The current schema can be retrieved using the function current_schema()
http://www.postgresql.org/docs/current/static/functions-info.html
Alternatively to wiring the schema or looking it up with current_schema(), you could make your view group by schema as well and then select on the view.
create or replace view enum_vw as
SELECT
n.nspname, t.typname, array_agg(e.enumlabel)
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_namespace n ON t.typnamespace = n.oid
WHERE t.typtype = 'e'
GROUP BY n.nspname, t.typname;
select * from enum_vw where nspname = 'public';