web-dev-qa-db-ja.com

ユーザー定義タイプとその詳細を表示する

PostgreSQLでいくつかの新しいUDTを作成しました。しかし、今は2つの問題があります。

  1. 定義されているUDTを確認する方法
  2. これらのUDT内で定義された列を確認するにはどうすればよいですか?

残念ながら、PostgreSQLのドキュメントではそれについて何も見つかりませんでした。

12
navige

これで始められますか?

SELECT n.nspname AS schema,
        pg_catalog.format_type ( t.oid, NULL ) AS name,
        t.typname AS internal_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 size,
        pg_catalog.array_to_string (
            ARRAY( SELECT e.enumlabel
                    FROM pg_catalog.pg_enum e
                    WHERE e.enumtypid = t.oid
                    ORDER BY e.oid ), E'\n'
            ) AS elements,
        pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description
    FROM pg_catalog.pg_type t
    LEFT 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 pg_catalog.pg_type_is_visible ( t.oid )
    ORDER BY 1, 2;

Psqlでは、\set ECHO_HIDDEN onを使用して、\d...コマンドの出力を生成するために使用されるクエリをpsqlに表示できます。これらのクエリは、メタデータをデータベースから掘り下げるときの出発点として非常に役立つことがわかりました。

更新:2019-12-16

複合型の場合、列のメタデータは次のようなものを使用して決定できます。

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 cols.schema_name,
        cols.obj_name,
        cols.column_name,
        cols.data_type,
        cols.ordinal_position,
        cols.is_required,
        coalesce ( cols.description, '' ) AS description
    FROM cols
    ORDER BY cols.schema_name,
            cols.obj_name,
            cols.ordinal_position ;
16
gsiems

標準のGUIを使用できます pgAdmin

types in pgAdmin

オブジェクトブラウザでタイプが有効になっていることを確認してください(オプション-ブラウザ-表示

左側には、選択したスキーマのユーザー定義型が表示されます(質問1。)。

SQL pane右側には、選択したタイプ(質問2。)のリバースエンジニアリングされたSQLスクリプトがあります。
その上のペインに、Dependentsなどの詳細が表示されます。


または、標準のインタラクティブコンソールpsqlを使用します。

  1. \dTユーザー定義型のリストを取得します。
  2. \d type_nameは、指定されたタイプの列定義リストを取得します。

マニュアル:

\d[S+] [ pattern ]

各リレーション(テーブル、ビュー、マテリアライズドビュー、インデックス、シーケンス、または外部テーブル)またはパターンに一致する複合タイプ、すべての列とそのタイプを表示、[...]

大胆な強調鉱山。このコマンドは、少なくともPostgres 9.1以降の複合型でも機能します。

そして:

\dT[S+] [ pattern ]

データ型をリストします。 patternが指定されている場合、名前がパターンに一致するタイプのみがリストされます。 +がコマンド名に追加されます。各タイプは、その内部名とサイズ、enumタイプの場合に許可される値、および関連する権限とともにリストされます。デフォルトでは、ユーザーが作成したオブジェクトのみが表示されます。システムオブジェクトを含めるには、パターンまたはS修飾子を指定します。

13

これは非常に単純な代替手段ですですが、単純な使用例には十分です。列のタイプがUDTの場合、udt_nameテーブルのinformation_schema.columns列を使用します。

select column_name, case 
        when (data_type = 'USER-DEFINED') then udt_name 
        else data_type 
    end as data_type
from information_schema.columns 
where table_schema = 'altimetria' and table_name = 'cnivel';

結果(geometryはUDT):

 column_name  |    data_type     
--------------+------------------
 ogc_fid      | integer
 wkb_geometry | geometry
 id_cnivel    | bigint
 cod_cart     | bigint
 cod_fam      | bigint
 cod_sub      | integer
 z            | double precision
 shape_len    | double precision
1
jgrocha

このコードを実行してみてください:

SELECT
    pg_type.typname, 
     pg_enum.enumlabel
FROM
    pg_type 
JOIN
    pg_enum ON pg_enum.enumtypid = pg_type.oid;
1