テーブル定義出力するSQL
SELECT
sut.relname as tablename,
pd.description as table_comment,
att.attnum AS num,
att.attname AS columnname,
com.description AS column_comment,
typ.typname AS COL_TYPE,
CASE typ.typname WHEN 'varchar' THEN att.atttypmod - 4 WHEN 'bpchar' THEN
att.atttypmod - 4 WHEN 'numeric' THEN att.atttypmod / 65536 WHEN 'date'
THEN att.attlen WHEN 'timestamp' THEN att.attlen END AS COL_LENGTH,
CASE att.attnotnull WHEN 't' THEN 'NOT NULL' WHEN 'f' THEN 'NULL' END AS
NOTNULL,
def.adsrc as default
FROM
(((pg_attribute att
-- pg_descriptionと1回目のLEFT JOIN。各カラムに対応するコメント。
LEFT JOIN pg_description com ON att.attnum = com.objsubid AND att.attrelid = com.objoid)
-- pg_attrdef
LEFT JOIN pg_attrdef def ON att.attrelid= def.adrelid AND att.attnum = def.adnum))
-- pg_descriptionと2回目のLEFT JOIN。こちらはテーブル用コメント。
LEFT JOIN pg_description pd on att.attrelid = pd.objoid AND pd.objsubid = 0 ,
--ユーザーが定義したテーブル
pg_stat_user_tables sut,
--pg_type
pg_type typ
WHERE
att.attrelid = sut.relid AND
att.atttypid = typ.oid AND
att.attnum > 0 AND
sut.relname IN (
SELECT
c.relname
FROM
pg_namespace AS n JOIN pg_class AS c ON (n.oid = c.relnamespace)
WHERE
c.relkind = 'r' AND
c.relname not like 'pg_%' AND
c.relname not like 'sql_%'
--必要に応じて条件を追記
)
ORDER BY sut.relname, att.attnum
ポイント
システムカタログを見よう
システムカタログにだいたいのことが書いてあるので、利用バージョンのシステムカタログを読もう。
9.6版のドキュメントは下記。
https://www.postgresql.jp/document/9.6/html/catalogs.html
システムカタログもただのテーブルなので、必要な情報が取れるように結合などしてあげればよい。
oid(オブジェクト識別子)
システムカタログもただのテーブルだが、結合するときに「oid」という特殊な属性を使うので、この点だけ注意。
また、oid型の列は、reg****** でキャスト可能。
オブジェクト識別子の型の一欄は、下記URL参照。
https://www.postgresql.jp/document/9.6/html/datatype-oid.html
どのoidがどのreg*****型にキャスト可能なのかは、上の表とシステムカタログのドキュメントを見て都度判断。
(読めばだいたい分かる)
キャストすると何が起こるのかは、以下のようなSQLを叩いてみれば大体わかると思う。
SELECT
relnamespace,
relnamespace::regnamespace as hoge,
reltype,
reltype::regtype as piyo,
relowner,
relowner::regrole as moge
FROM
pg_class
また、where句の条件などに利用することも可能。
SELECT
*
FROM
pg_class
WHERE
relnamespace = 'public'::regnamespace
ただ、以下のSQLはエラーになる。
(なんで駄目なのかは追いかけなかった)
SELECT
*
FROM
pg_class
WHERE
relnamespace::regnamespace = 'public'
デフォルト値
https://www.postgresql.jp/document/9.6/html/catalog-pg-attrdef.html
に記載されている通り、pg_get_exprを使ったadbinフィールドの逆コンパイルをしてる。