equivalent to `pg_rules` in `information_schema` - postgresql

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

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.

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 ;

List columns with indexes in Amazon Redshift

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.

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';

Postgres: variable saying from which schema I select

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';