UNION
、CASE
および関連する構文UNION
SQL構文は、似ていない可能性がある型を1つの検索結果になるように適合させなければなりません。
解決アルゴリズムは1つのunion問い合わせの出力列ごとに適用されます。
INTERSECT
構文とEXCEPT
構文は、UNION
と同じ方法で、似ていない可能性がある型の解決を行います。
CASE
構文とARRAY
構文、VALUES
、GREATEST
、LEAST
もまた、同一のアルゴリズムを使用して、その要素式を適合させ、結果のデータ型を選択します。
UNION
、CASE
および関連する構文の型解決
もし全ての入力値が同一型であり、unknown
ではない場合、その型として解決されます。
入力のいずれかがドメイン型であれば、以降の段階すべてでドメインの基本型であるかのように扱います。 [11]
もし全ての入力値がunknown
型だった場合、text
型(文字列カテゴリの優先される型)として解決されます。
そうでない場合はunknown
入力は残りの規則のために無視されます。
もしunknownではない入力値が全て同じ型カテゴリでなければ失敗します。
最初のunknownではない入力データ型を選択します。 もし存在すれば、このデータ型はそのカテゴリの優先される型です。
さもなくば、すべての先行する非unknownの入力値を暗黙的に変換させることができる、最後のunknownではない入力型を選択します。 (少なくともリストの先頭の型はこの条件を満たす必要がありますので、常にこのような型は存在します。)
全ての入力値を選択された型に変換します。 指定された入力から選択された型への変換が存在しない場合は失敗します。
以下に例を示します。
例10.10 Unionにおける指定された型の型解決
SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows)
ここで、unknown型のリテラル'b'
はtext
へと解決されます。
例10.11 簡単なUnionにおける型解決
SELECT 1.2 AS "numeric" UNION SELECT 1; numeric --------- 1 1.2 (2 rows)
numeric
型のリテラル1.2
とinteger
型の値1
は、暗黙的にnumeric
にキャスト可能です。
したがって、この型が使用されます。
例10.12 転置されたUNIONにおける型解決
SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); real ------ 1 2.2 (2 rows)
ここで、real
型を暗黙的にinteger
型にキャストすることはできませんが、integer
型を暗黙的にreal
型にキャストすることはできるため、UNIONの結果データ型はreal
型として解決されます。
例10.13 入れ子のUNIONにおける型解決
SELECT NULL UNION SELECT NULL UNION SELECT 1; ERROR: UNION types text and integer cannot be matched
この失敗は、PostgreSQLが複数のUNION
を二項演算の入れ子として扱うために起こります。すなわち、この入力は以下と同じです。
(SELECT NULL UNION SELECT NULL) UNION SELECT 1;
内側のUNION
は、上に挙げた規則に従って、型text
になるものとして解決されます。
すると、外側のUNION
は型text
とinteger
の入力を受け取ることになりますので、上のようなエラーになります。
一番左のUNION
が望む結果型の入力を少なくとも1つ確実に受け取るようにすることで、この問題を修正できます。
INTERSECT
とEXCEPT
操作は同様に二項演算として解決されます。
しかしながら、この節のその他の構文は入力をすべて解決の段階1つで考慮します。
[11] 演算子や関数に対するドメイン入力の取り扱いとある程度似ていて、この振舞いにより、利用者が注意して入力をすべて厳密な型であると保証する限り、ドメイン型をUNION
や類似の構成体に保存できます。
そうでなければ、ドメインの基本型が優先されます。