Reputation: 1546
Let's say we've defined a postgresql type:
CREATE TYPE my_type AS ENUM('foo', 'bar');
Is there any way to show the type definition after creation ?
I would expect "\d my_type" to show me "ENUM('foo', 'bar')", but it says :
Did not find any relation named "my_type"
The pg_type table doesn't seem to give enough information.
Upvotes: 111
Views: 62607
Reputation: 658322
enum_range
(anyenum
) →anyarray
Returns all values of the input enum type in an ordered array.
To also get the schema:
SELECT typnamespace::regnamespace AS "schema", typname
, enum_range(null::my_enum_type)
FROM pg_catalog.pg_type
WHERE typname = 'my_enum_type';
Returns:
schema | typname | enum_labels
--------+--------------+-------------
public | my_enum_type | {foo,bar}
You can also get the SQL CREATE
statement from a dump file. Cheapest from a schema-only dump with pg_dump --schema-only ...
.
Or simply use pgAdmin. Select the object in the object browser
and its create script is displayed in the SQL pane
.
Upvotes: 15
Reputation: 65
using this post, I've archived the goal to mimic the 'CREATE TYPE' in PgAdmin & PgBackup
WITH types AS (
SELECT n.nspname,
pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
CASE
WHEN t.typrelid != 0 THEN CAST ( 'tuple' AS pg_catalog.text )
WHEN t.typlen < 0 THEN CAST ( 'var' AS pg_catalog.text )
ELSE CAST ( t.typlen AS pg_catalog.text )
END AS obj_type,
coalesce ( pg_catalog.obj_description ( t.oid, 'pg_type' ), '' ) AS description
FROM pg_catalog.pg_type t
JOIN pg_catalog.pg_namespace n
ON n.oid = t.typnamespace
WHERE ( t.typrelid = 0
OR ( SELECT c.relkind = 'c'
FROM pg_catalog.pg_class c
WHERE c.oid = t.typrelid ) )
AND NOT EXISTS (
SELECT 1
FROM pg_catalog.pg_type el
WHERE el.oid = t.typelem
AND el.typarray = t.oid )
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
),
cols AS (
SELECT n.nspname::text AS schema_name,
pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
a.attname::text AS column_name,
pg_catalog.format_type ( a.atttypid, a.atttypmod ) AS data_type,
a.attnotnull AS is_required,
a.attnum AS ordinal_position,
pg_catalog.col_description ( a.attrelid, a.attnum ) AS description
FROM pg_catalog.pg_attribute a
JOIN pg_catalog.pg_type t
ON a.attrelid = t.typrelid
JOIN pg_catalog.pg_namespace n
ON ( n.oid = t.typnamespace )
JOIN types
ON ( types.nspname = n.nspname
AND types.obj_name = pg_catalog.format_type ( t.oid, NULL ) )
WHERE a.attnum > 0
AND NOT a.attisdropped
)
SELECT 'CREATE TYPE ' || cols.schema_name || '.' || cols.obj_name || E' AS (\n ' ||
pg_catalog.array_to_string (ARRAY(
SELECT cols.column_name || ' ' || cols.data_type AS col_num_typ
FROM cols
WHERE cols.obj_name='my_user_data_type'
ORDER BY cols.schema_name,
cols.obj_name,
cols.ordinal_position ), E',\n '
) || E'\n);'
AS cre_typ
FROM cols
WHERE cols.obj_name='my_user_data_type'
LIMIT 1
and run it under psql with this command to have only the SQL code :
\t\a\g\a\t
Upvotes: -1
Reputation: 3727
Check this:
select enum_range(null::my_type)
I think this is a much simpler solution :).
Upvotes: 162
Reputation: 22952
It's \dT you're after, but it doesn't give it as a "CREATE" statement. You use \dD for domains.
\dT+ action.action_status
List of data types
Schema | Name | Internal name | Size | Elements | Description
--------+----------------------+---------------+------+----------+-------------
action | action.action_status | action_status | 4 | pending +|
| | | | live +|
| | | | done +|
| | | | notdone |
(1 row)
Upvotes: 124
Reputation: 3002
SELECT t.typname
FROM pg_class c JOIN pg_attribute a ON c.oid = a.attrelid JOIN pg_type t ON a.atttypid = t.oid
WHERE c.relname = 'your_type';
The tricky part was that simply selecting * from these views one does not get OIDs in the results.
Upvotes: 1