web-dev-qa-db-fra.com

Déterminez si le type défini par l'utilisateur est enum

Existe-t-il un moyen de déterminer si un type défini par l'utilisateur dans PostgreSQL est un énumé?

Essentiellement nous avons ce qui suit:

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

Avec une table instanciée par:

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

Je suis capable de déterminer le type de foo de la colonne lyrics, cependant, j'ai du mal à trouver un moyen de déterminer si foo est une énumération.

Pour le contexte, j'ai besoin de ces informations pour obtenir de manière programmable une liste de toutes les valeurs possibles de foo lorsqu'il est donné une colonne de lyrics.

6

Vous pouvez faire quelque chose comme ça,

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

Vous pouvez créer une fonction simple qui le fait aussi,

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

Comme souvent avec de telles questions, le \set ECHO_HIDDEN on commande de psql aide. \dT+ montrera les valeurs possibles de l'énum, ​​si le type en question est une énumération. La requête derrière la sortie est plutôt complexe, mais on peut le simplifier pour répondre à vos besoins comme

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;

Cela reviendra {NULL} (un tableau avec une nulle dedans) si le type n'est pas une énumération, et les éléments réels en tant que tableau autrement. Vous pouvez le modifier plus loin si nécessaire.

5
dezso