patternsqlMajor
Get column names and data types of a query, table or view
Viewed 0 times
columnqueryviewnamesgettypesanddatatable
Problem
Is there a PostgreSQL query or command that returns the field names and field types of a query, table or view?
E.g., a solution if applied to simple SELECT query like
I have looked up the
The last is any arbitrary but valid SELECT query eg involving,
I am developing a program that creates data and querying forms and the information is needed for data validation and executing functions on the returned data.
E.g., a solution if applied to simple SELECT query like
SELECT * from person should return a list like:Column Name | Column Type
===========================
First Name | character
Last Name | character
Age | integer
Date of Birth | dateI have looked up the
information_schema views described in an answer below and it seems to cover tables quite well, and I suspect it covers views as well but I haven't checked that yet.The last is any arbitrary but valid SELECT query eg involving,
JOINS, UNIONS etc, on the database. Is there a built-in procedure, or other stored procedure or script that can return the same for any valid QUERY at all?I am developing a program that creates data and querying forms and the information is needed for data validation and executing functions on the returned data.
Solution
information_schema vs. system catalogsWe 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 zoneAlso 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 zoneTo 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_precisionRelated 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);Code Snippets
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;CREATE TEMP TABLE foo(
a numeric(12,3)
, b timestamp(0)
);SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum;attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zoneSELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;Context
StackExchange Database Administrators Q#75015, answer score: 37
Revisions (0)
No revisions yet.