8.7. Tipos enumerados #

8.7.1. Declaración de tipos enumerados
8.7.2. Ordenación
8.7.3. Seguridad de tipos
8.7.4. Detalles de implementación

Los tipos enumerados (enum) son tipos de datos que comprenden un conjunto estático y ordenado de valores. Son equivalentes a los tipos enum soportados en varios lenguajes de programación. Un ejemplo de un tipo enum podría ser los días de la semana, o un conjunto de valores de estado para un dato.

8.7.1. Declaración de tipos enumerados #

Los tipos enum se crean utilizando el comando CREATE TYPE, por ejemplo:

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

Una vez creado, el tipo enum se puede usar en definiciones de tablas y funciones de manera muy similar a cualquier otro tipo:

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. Ordenación #

El orden de los valores en un tipo enum es el orden en el que se listaron los valores al crear el tipo. Todos los operadores de comparación estándar y las funciones de agregación relacionadas son compatibles con los enums. Por ejemplo:

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. Seguridad de tipos #

Cada tipo de datos enumerado es independiente y no se puede comparar con otros tipos enumerados. Consulta este ejemplo:

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

Si realmente necesitas hacer algo así, puedes escribir un operador personalizado o agregar conversiones explícitas a tu consulta:

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. Detalles de implementación #

Las etiquetas de enum distinguen entre mayúsculas y minúsculas, por lo que 'happy' no es lo mismo que 'HAPPY'. El espacio en blanco en las etiquetas también es significativo.

Aunque los tipos enum están destinados principalmente a conjuntos estáticos de valores, existe soporte para agregar nuevos valores a un tipo enum existente y para renombrar valores (consulta la ALTER TYPE). Los valores existentes no se pueden eliminar de un tipo enum, ni se puede cambiar el orden de clasificación de dichos valores, a menos que se elimine y se vuelva a crear el tipo enum.

Un valor enum ocupa cuatro bytes en el disco. La longitud de la etiqueta textual de un valor enum está limitada por la configuración NAMEDATALEN compilada en PostgreSQL; en compilaciones estándar esto significa como máximo 63 bytes.

Las traducciones de valores enum internos a etiquetas textuales se mantienen en el catálogo del sistema pg_enum. Consultar este catálogo directamente puede ser útil.