8.7. 列挙型

列挙(enum)型は静的、順序付き集合から構成されるデータ型です。 これは、多くのプログラミング言語でサポートされているenum型と同じです。 列挙型の例として、曜日や個々のデータについての状態値の集合が挙げられます。

8.7.1. 列挙型の宣言

列挙型はCREATE TYPEコマンドを使用して作成されます。 以下に例を示します。

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

作成後、他のデータ型とほとんど同じように、列挙型をテーブルや関数定義で使用することができます。

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
    name text,
    current_mood mood
);
INSERT INTO person VALUES ('Moe', 'happy');
SELECT * FROM person WHERE current_mood = 'happy';
 name | current_mood 
------+--------------
 Moe  | happy
(1 row)

8.7.2. 順序

列挙型内の値の順序はその型が作成された時に値を列挙した順番になります。 列挙型に対して、すべての比較演算子と関連する集約関数がサポートされます。 以下に例を示します。

INSERT INTO person VALUES ('Larry', 'sad');
INSERT INTO person VALUES ('Curly', 'ok');
SELECT * FROM person WHERE current_mood > 'sad';
 name  | current_mood 
-------+--------------
 Moe   | happy
 Curly | ok
(2 rows)

SELECT * FROM person WHERE current_mood > 'sad' ORDER BY current_mood;
 name  | current_mood 
-------+--------------
 Curly | ok
 Moe   | happy
(2 rows)

SELECT name FROM person
WHERE current_mood = (SELECT MIN(current_mood) FROM person);
 name  
-------
 Larry
(1 row)

8.7.3. 型の安全性

それぞれの列挙型データ型は別個のもので、他の列挙型と比較することはできません。 以下の例を参照してください。

CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
CREATE TABLE holidays (
    num_weeks integer,
    happiness happiness
);
INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy');
INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy');
INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic');
INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad');
ERROR:  invalid input value for enum happiness: "sad"
SELECT person.name, holidays.num_weeks FROM person, holidays
  WHERE person.current_mood = holidays.happiness;
ERROR:  operator does not exist: mood = happiness

もし本当に上のようなことが必要ならば、独自の演算子を作成するか、問い合わせに明示的なキャストを付けることで行うことができます。

SELECT person.name, holidays.num_weeks FROM person, holidays
  WHERE person.current_mood::text = holidays.happiness::text;
 name | num_weeks 
------+-----------
 Moe  |         4
(1 row)

8.7.4. 実装の詳細

列挙型の値はディスク上では4バイトを占めます。 列挙型の値のテキストラベルの長さは、PostgreSQLに組み込まれたNAMEDATALEN設定により制限されます。 標準の構築では、これは最大63バイトを意味します。

列挙型のラベルは大文字小文字を区別します。 このため'happy''HAPPY'と同じではありません。 ラベル内の空白文字も意味を持ちます。

列挙型の内部値からテキスト形式のラベルへの変換は、pg_enumシステムカタログ内に保持されます。 このカタログを直接問い合わせることが役に立つ場合があります。