UNION, CASE y constructores relacionados #
Los constructores UNION de SQL deben hacer coincidir tipos posiblemente
disímiles para convertirse en un único conjunto de resultados. El algoritmo de resolución se
aplica por separado a cada columna de salida de una consulta de unión. Los constructores
INTERSECT y EXCEPT resuelven tipos disímiles de la misma
manera que UNION. Algunos otros constructores, como CASE,
ARRAY, VALUES y las funciones GREATEST
y LEAST, utilizan el mismo algoritmo para hacer coincidir sus expresiones
componentes y seleccionar un tipo de datos de resultado.
Resolución de tipos para UNION, CASE
y constructores relacionados
Si todas las entradas son del mismo tipo y no es unknown, se resuelve como
ese tipo.
Si alguna entrada es de un tipo de dominio, trátala como si fuera del tipo base del dominio para todos los pasos siguientes. [12]
Si todas las entradas son de tipo unknown, se resuelve como tipo text
(el tipo preferido de la categoría de cadenas). De lo contrario, las entradas unknown
se ignoran a efectos de las reglas restantes.
Si las entradas que no son unknown no pertenecen todas a la misma categoría de tipos, falla.
Selecciona el primer tipo de entrada que no sea unknown como el tipo candidato, luego considera cada uno de los otros tipos de entrada que no sean unknown, de izquierda a derecha. [13] Si el tipo candidato se puede convertir implícitamente al otro tipo, pero no al revés, selecciona el otro tipo como el nuevo tipo candidato. Luego continúa considerando las entradas restantes. Si, en cualquier etapa de este proceso, se selecciona un tipo preferido, deja de considerar las entradas adicionales.
Convierte todas las entradas al tipo candidato final. Falla si no existe una conversión implícita desde un tipo de entrada dado al tipo candidato.
A continuación se muestran algunos ejemplos.
Example 10.10. Resolución de tipos con tipos subespecificados en una unión
SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows)
Aquí, el literal de tipo desconocido 'b' se resolverá como de tipo
text.
Example 10.11. Resolución de tipos en una unión simple
SELECT 1.2 AS "numeric" UNION SELECT 1;
numeric
---------
1
1.2
(2 rows)
El literal 1.2 es de tipo numeric, y el valor entero
1 se puede convertir implícitamente a numeric, por lo
que se utiliza ese tipo.
Example 10.12. Resolución de tipos en una unión transpuesta
SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
real
------
1
2.2
(2 rows)
Aquí, dado que el tipo real no se puede convertir implícitamente a
integer, pero integer sí se puede convertir implícitamente a
real, el tipo de resultado de la unión se resuelve como real.
Example 10.13. Resolución de tipos en una unión anidada
SELECT NULL UNION SELECT NULL UNION SELECT 1; ERROR: UNION types text and integer cannot be matched
Este fallo ocurre porque PostgreSQL trata múltiples
UNIONs como un anidamiento de operaciones de pares; es decir, esta
entrada es lo mismo que
(SELECT NULL UNION SELECT NULL) UNION SELECT 1;
La UNION interna se resuelve emitiendo el tipo text,
de acuerdo con las reglas dadas anteriormente. Luego, la UNION externa
tiene entradas de los tipos text e integer, lo que lleva al error
observado. El problema se puede solucionar asegurándose de que la UNION
más a la izquierda tenga al menos una entrada del tipo de resultado deseado.
Las operaciones INTERSECT y EXCEPT se resuelven
igualmente por pares. Sin embargo, los otros constructores descritos en esta sección
consideran todas sus entradas en un solo paso de resolución.
[12]
De manera similar al tratamiento de las entradas de dominio para operadores y funciones,
este comportamiento permite conservar un tipo de dominio a través de un UNION
o un constructor similar, siempre que el usuario tenga cuidado de asegurar que todas las
entradas sean implícita o explícitamente de ese tipo exacto. De lo contrario, se utilizará
el tipo base del dominio.
[13]
Por razones históricas, CASE trata su cláusula ELSE
(si la hay) como la “primera” entrada, considerándose las cláusulas
THEN después de ella. En todos los demás casos, “de izquierda a
derecha” significa el orden en que aparecen las expresiones en el texto de la consulta.