web-dev-qa-db-ja.com

ユーザー定義タイプがENUMかどうかを判別

PostgreSQLのユーザー定義型がENUMであるかどうかを判断する方法はありますか?

基本的に、次のものが用意されています。

CREATE TYPE foo AS ENUM (
  'Sometimes',
  'You',
  'Wanna',
  'Go',
  'Where Everybody Knows Your Name'
);

次のようにインスタンス化されたテーブルを使用:

CREATE TABLE bar (
  lyrics foo DEFAULT 'Wanna'::foo
);

fooからlyricsのタイプを判別できますが、fooがENUMであるかどうかを判別する方法を見つけるのに苦労しています。

コンテキストについては、fooの列が与えられたときにlyricsのすべての可能な値のリストをプログラムで取得するために、この情報が必要です。

このようなことができます

SELECT true
FROM pg_enum
WHERE enumtypid = pg_typeof('You'::foo)::regtype
FETCH FIRST ROW ONLY;

それを行う簡単な関数を作成することもできます。

CREATE FUNCTION is_enum(x regtype)
RETURNS bool
AS $$
  SELECT true
  FROM pg_enum
  WHERE enumtypid = x
  FETCH FIRST ROW ONLY;
$$ LANGUAGE sql
IMMUTABLE;

SELECT is_enum(pg_typeof('You'::foo));
 is_enum 
---------
 t
(1 row)
4
Evan Carroll

このような質問でよくあることですが、psql\set ECHO_HIDDEN onコマンドが役立ちます。 \dT+は、問題の型が列挙型の場合、列挙型の可能な値を示します。出力の背後にあるクエリはかなり複雑ですが、次のようなニーズに合わせて簡略化できます

SELECT format_type(t.oid, NULL) AS name,
       array_agg(e.enumlabel ORDER BY e.enumsortorder) AS elements
  FROM pg_type AS t 
  LEFT JOIN pg_enum AS e ON e.enumtypid = t.oid
 WHERE t.typname = 'foo'
 GROUP BY t.oid;

これは、型が列挙型でない場合は{NULL}(NULLを含む配列)を返し、それ以外の場合は実際の要素を配列として返します。必要に応じてさらに調整することができます。

5
dezso