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.
Answer from Erwin Brandstetter on Stack OverflowPostgres 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.
Can I export data back to my business systems with Coefficient?
Does Coefficient work with both Google Sheets and Excel?
How much does Coefficient cost?
In addition to the command line \d+ <table_name> you already found, you could also use the Information Schema to look up the column data, using information_schema.columns:
SELECT *
FROM information_schema.columns
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'
;
Note: As per the example above, make sure the values are enclosed within quotes.
As a supplement to the other answers, even a SELECT statement that returns no rows will expose the column names to you and to application code.
select *
from table_name
where false;
I intend this to be executable by almost any client software for almost any DBMS. (Almost? Yes, some don't support a clause like where false. Instead, they require an expression like where 1 = 0.)
Permissions might come into play with any of these approaches.
Information schema vs. system catalogs
We have discussed this many times. The information schema serves certain purposes. System catalogs are the actual source of all information.
The information schema provides standardized views which help with portability - mostly across major Postgres versions as portability across different RDBMS platforms typically is an illusion once your queries are sophisticated enough to look up system catalogs. Notably, Oracle still doesn't support the information schema.
Views in the information schema must jump through many hoops to achieve a format complying to the standard. This makes them slow, sometimes very slow. Compare plans and performance for these basic objects:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
The difference is remarkable.
Your example
For your example SELECT * from tbl compare the two queries below for this simple table:
CREATE TEMP TABLE foo(
a numeric(12,3)
, b timestamp(0)
);
Using pg_attribute:
SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum;
format_type() returns the complete type with all modifiers:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
Also note that the cast to regclass resolves the table name according to the current search_path. It raises an exception if the name is not valid. See:
- ERROR: could not find array type for datatype information_schema.sql_identifier
Using information_schema.columns:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
The information is standardized, but incomplete:
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
To get full information for the data type you need to consider all of these columns additionally:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Related answers:
- How to check if a table exists in a given schema
- List all columns for a specified table
List of pros & cons
The biggest pros (IMO) in bold.
Information schema views
- often simpler (depends)
- slow
- preprocessed, which may or may not suit your needs
- selective (users only see objects they have privileges for)
- conforming to an SQL standard (that's implemented by some of the major RDBMS)
- mostly portable across major Postgres versions
- do not require much specific knowledge about Postgres
- identifiers are descriptive, long and sometimes awkward
System catalogs
- often more complex (depends), closer to the source
- fast
- complete (system columns like
oidincluded) - not complying to an SQL standard
- less portable across major Postgres versions (but basics aren't going to change)
- require more specific knowledge about Postgres
- identifiers are terse, less descriptive but conveniently short
Arbitrary query
To get the same list of column names and types from a query, you could use a simple trick: CREATE a temporary table from the query output, then use the same techniques as above.
You can append LIMIT 0, since you do not need actual data:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
To get the data type of individual columns, you can also use the function pg_typeof():
SELECT pg_typeof(1);
You can use the psql command line client.
\dt will show a list of tables
\dv will show a list of views
\d [object_name] will describe the schema of the table or view
Not sure how you would describe a query though.
More info: https://manikandanmv.wordpress.com/tag/basic-psql-commands/
information_schema.columns.Table_name (at least under Sql Server 2000) includes views, so just use
SELECT * FROM information_schema.columns WHERE table_name = 'VIEW_NAME'
Try this:
SELECT *
FROM sys.views
This gives you the views as such - if you need the columns, use this:
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID('dbo.YourViewNameHere')
Not sure how you can do it using the INFORMATION_SCHEMA - I never use that, since it feels rather "clunky" and unintuitive, compared to the sys schema catalog views.
See the MSDN docs on the Catalog Views for all the details of all the views available, and what information they might contain.