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や類似の構成体に保存できます。
そうでなければ、ドメインの基本型が優先されます。