Les types énumérés (enum) sont des types de données qui comprennent un
ensemble statique, prédéfini de valeurs dans un ordre spécifique. Ils sont
équivalents aux types enum
dans de nombreux langages de
programmation. Les jours de la semaine ou un ensemble de valeurs de statut
pour un type de données sont de bons exemples de type enum.
Les types enum sont créés en utilisant la commande CREATE TYPE. Par exemple :
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
Une fois créé, le type enum peut être utilisé dans des définitions de table et de fonction, comme tous les autres types :
CREATE TYPE humeur AS ENUM ('triste', 'ok', 'heureux'); CREATE TABLE personne ( nom text, humeur_actuelle humeur ); INSERT INTO personne VALUES ('Moe', 'heureux'); SELECT * FROM personne WHERE humeur_actuelle = 'heureux'; name | humeur_actuelle ------+----------------- Moe | heureux (1 row)
L'ordre des valeurs dans un type enum correspond à l'ordre dans lequel les valeurs sont créées lors de la déclaration du type. Tous les opérateurs de comparaison et les fonctions d'agrégats relatives peuvent être utilisés avec des types enum. Par exemple :
INSERT INTO personne VALUES ('Larry', 'triste'); INSERT INTO personne VALUES ('Curly', 'ok'); SELECT * FROM personne WHERE humeur_actuelle > 'triste'; nom | humeur_actuelle -------+----------------- Moe | heureux Curly | ok (2 rows) SELECT * FROM personne WHERE humeur_actuelle > 'triste' ORDER BY humeur_actuelle; nom | humeur_actuelle -------+-------------- Curly | ok Moe | heureux (2 rows) SELECT nom FROM personne WHERE humeur_actuelle = (SELECT MIN(humeur_actuelle) FROM personne); nom ------- Larry (1 row)
Chaque type de données énuméré est séparé et ne peut pas être comparé aux autres types énumérés. Par exemple :
CREATE TYPE niveau_de_joie AS ENUM ('heureux', 'très heureux', 'ecstatique'); CREATE TABLE vacances ( nombre_de_semaines integer, niveau_de_joie niveau_de_joie ); INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (4, 'heureux'); INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (6, 'très heureux'); INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (8, 'ecstatique'); INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (2, 'triste'); ERROR: invalid input value for enum niveau_de_joie: "triste" SELECT personne.nom, vacances.nombre_de_semaines FROM personne, vacances WHERE personne.humeur_actuelle = vacances.niveau_de_joie; ERROR: operator does not exist: humeur = niveau_de_joie
Si vous avez vraiment besoin de ce type de conversion, vous pouvez soit écrire un opérateur personnalisé soit ajouter des conversions explicites dans votre requête :
SELECT personne.nom, vacances.nombre_de_semaines FROM personne, vacances WHERE personne.humeur_actuelle::text = vacances.niveau_de_joie::text; nom | nombre_de_semaines ------+-------------------- Moe | 4 (1 row)
Les labels enum sont sensibles à la casse, donc 'heureux'
n'est pas identique à 'HEUREUX'
. Les espaces blancs dans les
labels sont aussi pris en compte.
Bien que les types enum aient principalement pour but d'être des ensembles statiques de valeurs, il est possible d'ajouter de nouvelles valeurs à un type enum existant et de renommer les valeurs existantes (voir ALTER TYPE). Les valeurs existantes ne peuvent pas être supprimées d'un type enum, pas plus qu'il n'est possible de modifier l'ordre de tri de ces valeurs, si ce n'est en supprimant puis en re- créant le type enum.
Une valeur enum occupe quatre octets sur disque. La longueur du label texte
d'une valeur enum est limité au paramètre NAMEDATALEN
codé en dur dans PostgreSQL ; dans les
constructions standard, cela signifie un maximum de 63 octets.
Les traductions des valeurs enum internes vers des labels texte sont
gardées dans le catalogue système
pg_enum
. Interroger ce catalogue directement
peut s'avérer utile.