10.5. UNION
, CASE
и связанные конструкции
SQL-конструкция UNION
взаимодействует с системой типов, так как ей приходится объединять значения возможно различных типов в единый результирующий набор. Алгоритм разрешения типов при этом применяется независимо к каждому отдельному столбцу запроса. Подобным образом различные типы сопоставляются при выполнении INTERSECT
и EXCEPT
сопоставляют различные типы подобно UNION
. По такому же алгоритму сопоставляют типы выражений и определяют тип своего результата конструкции CASE
, ARRAY
, VALUES
, GREATEST
и LEAST
.
Разрешение типов для UNION
, CASE
и связанных конструкций
Если все данные одного типа и это не тип
unknown
, выбрать его.Если тип данных — домен, далее считать их типом базовый тип домена. [9]
Если все данные типа
unknown
, выбрать для результата типtext
(предпочитаемый для категории string). В противном случае значенияunknown
для остальных правил игнорируются.Если известные типы входных данных оказываются не из одной категории, констатировать неудачу.
Выбрать первый известный предпочитаемый тип из этой категории, если такой есть.
В противном случае выбрать последний известный тип, в который можно неявно преобразовать все данные предшествующих известных типов. (Такой тип есть всегда, в крайнем случае этому условию удовлетворяет первый тип.)
Привести все данные к выбранном типу. Констатировать неудачу, если для каких-либо данных преобразование в этот тип невозможно.
Ниже это проиллюстрировано на примерах.
Пример 10.9. Разрешение типов с частичным определением в Union
SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows)
В данном случае константа 'b'
неизвестного типа будет преобразована в тип text
.
Пример 10.10. Разрешение типов в простом объединении
SELECT 1.2 AS "numeric" UNION SELECT 1; numeric --------- 1 1.2 (2 rows)
Константа 1.2
имеет тип numeric
и целочисленное значение 1
может быть неявно приведено к типу numeric
, так что используется этот тип.
Пример 10.11. Разрешение типов в противоположном объединении
SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); real ------ 1 2.2 (2 rows)
Здесь значение типа real
нельзя неявно привести к integer
, но integer
можно неявно привести к real
, поэтому типом результата объединения будет real
.
[9] Так же, как домены воспринимаются при выборе операторов и функций, доменные типы могут сохраняться в конструкции UNION
или подобной, если пользователь позаботится о том, чтобы все входные данные приводились к этому типу явно или неявно. В противном случае предпочтение будет отдано базовому типу домена.