PostgreSQLLa base de données la plus sophistiquée au monde.

Version anglaise

10.5. Constructions UNION, CASE et constructions relatives

Les constructions SQL avec des UNION doivent potentiellement faire correspondre des types différents pour avoir un ensemble unique dans le résultat. L'algorithme de résolution est appliqué séparément à chaque colonne de sortie d'une requête d'union. Les constructions INTERSECT et EXCEPT résolvent des types différents de la même manière qu'UNION. Les constructions CASE, ARRAY, VALUES, GREATEST et LEAST utilisent le même algorithme pour faire correspondre les expressions qui les composent et sélectionner un type de résultat.

Procédure 10.4. Résolution des types pour UNION, CASE et les constructions relatives

  1. Si toutes les entrées sont du même type et qu'il ne s'agit pas du type unknown, résoudre comme étant de ce type. Sinon, remplacer tous les types de domaine dans la liste avec les types de base sous-jacents.

  2. Si toutes les entrées sont du type unknown, résoudre comme étant du type text (le type préféré de la catégorie chaîne).

  3. Si un argument est de type domaine, le traiter comme le type de base du domaine pour toutes les étapes suivantes. [10]

  4. Si toutes les entrées non-inconnues ne sont pas toutes de la même catégorie, échouer.

  5. Choisir la première entrée non-inconnue qui est un type préféré dans sa catégorie, s'il y en a une.

  6. Sinon, choisir le dernier type en entrée qui ne soit pas inconnu et qui permet à toutes les entrées précédentes qui ne sont pas inconnues à être implicitement converties. (Il y a toujours un type de ce genre car au moins le premier type dans la liste doit satisfaire cette condition.)

  7. Convertir toutes les entrées du type sélectionné. Échoue s'il n'y a pas de conversion à partir de l'entrée donnée vers le type sélectionné.

Quelques exemples suivent.

Exemple 10.10. Résolution de types avec des types sous-spécifiés dans une union

                SELECT text 'a' AS "text" UNION SELECT 'b';

 text
------
 a
 b
(2 rows)

Ici, la chaîne de type inconnu 'b' sera convertie vers le type text.


Exemple 10.11. Résolution de types dans une union simple

SELECT 1.2 AS "numeric" UNION SELECT 1;

 numeric
---------
       1
     1.2
(2 rows)

Le littéral 1.2 est du type numeric et la valeur 1, de type integer, peut être convertie implicitement vers un type numeric, donc ce type est utilisé.


Exemple 10.12. Résolution de types dans une union transposée

                SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);

 real
------
    1
  2.2
(2 rows)

Dans cet exemple, le type real (réel) ne peut pas être implicitement converti en integer (entier) mais un integer peut être implicitement converti en real ; le résultat de l'union est résolu comme étant un real.


Exemple 10.13. Résolution de type dans une union imbriquée

SELECT NULL UNION SELECT NULL UNION SELECT 1;

ERROR:  UNION types text and integer cannot be matched

Cet échec survient parce que PostgreSQL™ traite plusieurs UNION comme une imbrication d'opérations sous forme de paires ; c'est-à-dire que cette entrée est identique à

(SELECT NULL UNION SELECT NULL) UNION SELECT 1;

Le UNION interne est résolu en émettant le type text, suivant les règles données ci-dessus. Puis le UNION externe a en entrée les types text et integer, amenant l'erreur observé. Le problème peut être corrigé en s'assurant que le UNION le plus à gauche dispose au moins d'une entrée du type résultant désiré.

Les opérations INTERSECT et EXCEPT procèdent de la même façon. Néanmoins, les autres constructions décrites dans cette section considèrent toutes leurs entrées en une seule étape de résolution.




[10] Ressemblant un peu au traitement des arguments de type domaine pour les opérateurs et les fonctions, ce comportement permet à un type domaine d'être préservé à travers un UNION ou une construction similaire, si tant est que l'utilisateur fait attention à ce que tous les arguments soient implicitement ou explicitement de ce type même. Sinon le type de base du domaine sera préféré.