Redshift option for Information_Schema - sql

Just moved from SSMS to Redshift (using DBeaver) and am wondering if there's a good option for getting table descriptions. In SQL server you could write a great query against information_schema to pull column names, datatypes, etc. Any similar options in Redshift?

The INFORMATION_SCHEMA tables are available in Redshift.
It may be that your chosen query tool (DBeaver) is hiding the schema in the GUI. However you should still be able to query them as normal.
This is certainly the case for me when I'm using Navicat. If you want to see the schema then it is visible when using SQL Workbench or SQuirreL.
2016-04-04: AWS have created a much simpler view that provides complete CREATE TABLE statements including all the Redshift specific stuff. Get them from here: https://github.com/awslabs/amazon-redshift-utils/tree/master/src/AdminViews

Looks like you are looking for something like this : http://rocky-says.blogspot.com/2015/01/amazon-redshift-generate-table-ddl.html
Here is the query that will help you : Just replace the < TABLE > and < SCHEMA> with your table name and Schema
SELECT DISTINCT n.nspname AS schemaname
,c.relname AS tablename
,a.attname AS COLUMN
,a.attnum AS column_position
,pg_catalog.format_type(a.atttypid, a.atttypmod) AS TYPE
,pg_catalog.format_encoding(a.attencodingtype) AS encoding
,a.attisdistkey AS distkey
,a.attsortkeyord AS sortkey
,a.attnotnull AS notnull
,a.attencodingtype AS compression
,con.conkey AS primary_key_column_ids
,con.contype AS con_type
FROM pg_catalog.pg_namespace n
,pg_catalog.pg_class c
,pg_catalog.pg_attribute a
,pg_constraint con
,pg_catalog.pg_stats stats
WHERE n.oid = c.relnamespace
AND c.oid = a.attrelid
AND a.attnum > 0
AND c.relname NOT LIKE '%pkey'
AND lower(c.relname) = ''
AND n.nspname = ''
AND c.oid = con.conrelid(+)
ORDER BY A.ATTNUM
;

Related

How can I query for the definitions of all domains in the database?

I'm trying to find a way to run a SELECT query (not some admin command) that returns the definition for every domain type in a Postgres database. Specifically, I'd like to know:
Schema
Name
Underlying type
Null/not null
Trying to Google this is tricky, because searching for information about querying the definitions of custom types in Postgres gives tons of results about enums for some reason, but nothing useful about domains. Does anyone know how to retrieve domain definitions from Postgres metadata?
This returns what you ask for, plus some more columns that may be relevant:
SELECT n.nspname AS schema
, t.typname AS name
, pg_catalog.format_type(t.typbasetype, t.typtypmod) AS underlying_type
, t.typnotnull AS not_null
, (SELECT c.collname
FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt
WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) AS collation
, t.typdefault AS default
, pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.pg_get_constraintdef(r.oid, TRUE) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid), ' ') AS check_constraints
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE t.typtype = 'd' -- domains
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND pg_catalog.pg_type_is_visible(t.oid)
ORDER BY 1, 2;
db<>fiddle here
To get every domain type in a Postgres database remove the added filters:
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND pg_catalog.pg_type_is_visible(t.oid)
But you'll probably just want visible user-domains.
Read the manual about pg_type.
In psql use \dD. And if you do that after setting \set ECHO_HIDDEN on, you'll also see the query used to generate that output. You'll find similarities to my query above (hint!).

How to list the columns of a view in Postgres?

For a physical table, I have been using the following SQL:
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS
where table_name = 'a_table_name'
I found that this doesn't work for a view. Is there a way to get the schema of a view by running a SQL command (not via psql).
Postgres has dedicated System Catalog Information Functions to help with that.
To get the full view definition:
SELECT pg_get_viewdef('public.view_name');
Schema-qualification is optional. If no schema is prefixed, the current search_path setting decides visibility.
A quick hack would be to just:
SELECT * FROM public.view_name LIMIT 0;
Depending on your client, column names and types should still be displayed. Or LIMIT n to get some sample values, too. The underlying query is actually executed then (unlike with LIMIT 0).
To list columns and their data type, in order, you might base the query on pg_attribute:
SELECT attname AS column_name, format_type(atttypid, atttypmod) AS data_type
FROM pg_attribute
WHERE attrelid = 'public.view_name'::regclass
-- AND NOT attisdropped
-- AND attnum > 0
ORDER BY attnum;
Type modifiers like maximum length are included in data_type this way.
Internally, a VIEW is implemented as special table with a rewrite rule. Details in the manual here. The table is saved in the system catalogs much like any regular table.
About the cast to regclass:
How to check if a table exists in a given schema
The same query works for tables or materialized views as well. Uncomment the additional filters above to only get visible user columns for tables.
SELECT
a.attname,
t.typname,
a.atttypmod
FROM pg_class c
INNER JOIN pg_attribute a ON a.attrelid = c.oid
INNER JOIN pg_type t ON t.oid = a.atttypid
WHERE c.relkind = 'v'
AND c.relname = 'put_viewname_here';
ATTENTION: Since the viewname is unique only in the schema, you might also want to add an INNER JOIN to pg_namespace and add a condition to the where-clause.
For the first version of your question:
SELECT n.nspname
FROM pg_class c
INNER JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'v'
AND c.relname = 'put_viewname_here';
ATTENTION: This might give you multiple schemas, since a viewname is only unique inside a schema and thus a viewname does not always identify one view.

Translating query from Firebird to PostgreSQL

I have a Firebird query which I should rewrite into PostgreSQL code.
SELECT TRIM(RL.RDB$RELATION_NAME), TRIM(FR.RDB$FIELD_NAME), FS.RDB$FIELD_TYPE
FROM RDB$RELATIONS RL
LEFT OUTER JOIN RDB$RELATION_FIELDS FR ON FR.RDB$RELATION_NAME = RL.RDB$RELATION_NAME
LEFT OUTER JOIN RDB$FIELDS FS ON FS.RDB$FIELD_NAME = FR.RDB$FIELD_SOURCE
WHERE (RL.RDB$VIEW_BLR IS NULL)
ORDER BY RL.RDB$RELATION_NAME, FR.RDB$FIELD_NAME
I understand SQL, but have no idea, how to work with this system tables like RDB$RELATIONS etc. It would be really great if someone helped me with this, but even some links with this tables explanation will be OK.
This piece of query is in C++ code, and when I'm trying to do this :
pqxx::connection conn(serverAddress.str());
pqxx::work trans(conn);
pqxx::result res(trans.exec(/*there is this SQL query*/));//and there is a mistake
it writes that:
RDB$RELATIONS doesn't exist.
Postgres has another way of storing information about system content. This is called System Catalogs.
In Firebird your query basically returns a row for every column of a table in every schema with an additional Integer column that maps to a field datatype.
In Postgres using system tables in pg_catalog schema something similar can be achieved using this query:
SELECT
TRIM(c.relname) AS table_name, TRIM(a.attname) AS column_name, a.atttypid AS field_type
FROM pg_class c
LEFT JOIN pg_attribute a ON
c.oid = a.attrelid
AND a.attnum > 0 -- only ordinary columns, without system ones
WHERE c.relkind = 'r' -- only tables
ORDER BY 1,2
Above query does return system catalogs as well. If you'd like to exclude them you need to add another JOIN to pg_namespace and a where clause with pg_namespace.nspname <> 'pg_catalog', because this is the schema where system catalogs are stored.
If you'd also like to see datatype names instead of their representative numbers add a JOIN to pg_type.
Information schema consists of collection of views. In most cases you don't need the entire SQL query that stands behind the view, so using system tables will give you better performance. You can inspect views definition though, just to get you started on the tables and conditions used to form an output.
I think you are looking for the information_schema.
The tables are listed here: https://www.postgresql.org/docs/current/static/information-schema.html
So for example you can use:
select * from information_schema.tables;
select * from information_schema.columns;

Get definition of function, sequence, type etc. in Postgresql with SQL query

I need the create scripts for PostgreSQL database objects.
I have not access to pg_dump. So I have to get everything with SQL queries. How could I do this?
To get the definition of a function use pg_get_functiondef():
select pg_get_functiondef(oid)
from pg_proc
where proname = 'foo';
There are similar functions to retrieve the definition of an index, a view, a rule and so on. For details see the manual: http://www.postgresql.org/docs/current/static/functions-info.html
Getting the definition of a user type is a bit more tricky. You will need to query information_schema.attributes for that:
select attribute_name, data_type
from information_schema.attributes
where udt_schema = 'public'
and udt_name = 'footype'
order by ordinal_position;
From that you need to re-assemble the create type statement.
For more details you will need to read through the documentation of the system catalog: http://www.postgresql.org/docs/current/static/catalogs.html
But you should prefer information_schema views if they return the same information.
You will find psql -E instrumental in your quest for those queries.
It displays the queries psql uses when executing its backslash-commands - like \df+ myfunc for details about this function.
Here is a complete sample query using pg_get_functiondef:
WITH funcs AS (
SELECT
n.nspname AS schema
,proname AS sproc_name
,proargnames AS arg_names
,t.typname AS return_type
,d.description
,pg_get_functiondef(p.oid) as definition
FROM pg_proc p
JOIN pg_type t on p.prorettype = t.oid
JOIN pg_description d on p.oid = d.objoid
JOIN pg_namespace n on n.oid = p.pronamespace
WHERE n.nspname = 'some_schema_name_here'
)
SELECT *
FROM funcs
;;
Note, you should obviously specify the schema name, (or "public" if you are using that schema)
You can also do \sf to see the user defined function in psql

List stored functions that reference a table in PostgreSQL

Just a quick and simple question: in PostgreSQL, how do you list the names of all stored functions/stored procedures using a table using just a SELECT statement, if possible? If a simple SELECT is insufficient, I can make do with a stored function.
My question, I think, is somewhat similar to this other question, but this other question is for SQL Server 2005:
List of Stored Procedure from Table
(optional) For that matter, how do you also list the triggers and constraints that use the same table in the same manner?
SELECT p.proname
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p
ON p.pronamespace = n.oid
WHERE n.nspname = 'public';
SELECT proname, prosrc
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p
ON pronamespace = n.oid
WHERE nspname = 'public';
If you are using psql, try \df
From the man page:
Tip
To look up functions taking arguments or returning values of a specific type, use your pager's search capability to scroll through the \df output.
Running \set ECHO_HIDDEN will reveal what \df is running behind the scenes.
Same as #quassnoi and #davidwhthomas, except I added the argument names in there:
SELECT proname, proargnames, prosrc
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p
ON pronamespace = n.oid
WHERE nspname = 'public';
If the purpose behind listing the functions is to clean them up or iterate a new function with a changing params list, you will frequently need to drop functions:
DROP FUNCTION <name>(<args>);
By adding proargnames, I am able to construct the applicable function name for the drop.
Additionally, it's nice to see a more complete picture when evaluating the functions.
You can use the standard information_schema schema to get metadata about your database (it's in the SQL standard, so it should work the same way in different database systems). In this case you want information_schema.routines.
Excluding the system stuff:
select proname from pg_proc where proowner <> 1;
Have a look at my recipe. It reads functions and triggers. It is based on informations from: Extracting META information from PostgreSQL (INFORMATION_SCHEMA)
Please change the schema_name and table_name in the below query:
SELECT n.nspname AS schema_name
, p.proname AS function_name
, pg_get_function_arguments(p.oid) AS args
, pg_get_functiondef(p.oid) AS func_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
AND n.nspname = 'schema_name'
AND p.prosrc like '%table_name%'
Since the table name is case sensitive, so need to define the exact table name.
For retrieving the argument types of the functions, which are required when referencing the function in ALTER -- using oldevectortypes worked well for me.
See How can I get a list of all functions stored in the database of a particular schema in PostgreSQL?