意図的かどうかにかかわらず、1つの式の中に異なる型を混ぜ合わせた式をSQLの問い合わせでは持つことができます。 PostgreSQLは、異なる型が混在する式の評価に関して幅広い能力を持っています。
多くの場合、ユーザは型変換機構の詳細を理解する必要はありません。 しかし、PostgreSQLによって暗黙的に行われる変換は問い合わせの結果に影響を及ぼします。 必要ならばユーザまたはプログラマにより、明示的な型変換を用いて目的とするものに合わせることができます。
本章では、PostgreSQLの型変換機構とその規定について紹介します。 特定のデータ型、使用できる関数と演算子についての情報については、第8章と第9章の関連する節を参照してください。
SQLは強く型付けされた言語です。 つまり、各データ項目は、その動作と許される使用方法を決定するデータ型を所有しています。 PostgreSQLは、他のSQLの実装よりもより一般的で柔軟性のある、拡張可能な型システムを持ちます。 ゆえに、PostgreSQLでのほとんどの型変換の動作は、ユーザー定義型についても型の混在する式を有意義に使えるように、特定の目的について勝手に作り上げられることなく一般的な規則ルールで管理しなければなりません。
PostgreSQLのスキャナ/パーサは字句要素を、整数、浮動小数点、文字列、名前、キーワードというわずか5個の基礎カテゴリに解読します。 ほとんどの非数値型定数は、まず文字列にクラス分けされます。 SQL言語定義では、文字列で型の名前を指定することを許しており、この手法はパーサーが正しい手順に沿って処理を始められるようにPostgreSQLによって使用されています。 たとえば、以下のような問い合わせを考えてみましょう。
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
この問い合わせは、textとpointという2つの型を指定したリテラル定数を持ちます。 文字列リテラルに型が指定されていない場合、後述するように、後の段階で解決されるように、とりあえず場所を確保するための型であるunknownが割り当てられます。
PostgreSQLのパーサには、個別の型変換ルールが必要な4つの基礎的なSQL構成要素があります。
PostgreSQLでは、(引数が2つである)二項演算子と同様に、(引数が1つである)前置、後置単項演算子を持つ式が使用できます。
PostgreSQLの型システムの多くは、多くの関数の集合を持って構築されています。 関数呼び出しには1つ以上の引数をつけることができます。 PostgreSQLは関数のオーバーロードを許可するので、関数名のみでは呼び出される関数を一意に識別しません。 パーサが、与えられる引数のデータ型に基づいて正しい関数を選択しなければいけません。
SQLのINSERTとUPDATE文は式の結果をテーブルの中に格納します。 文内の式は対象となるカラムの型に一致する、または、変換できるものである必要があります。
UNIONを構成するSELECT文からの選択結果はすべて、ある1つの列集合として現れなければいけませんので、各SELECT句の結果型は統一された集合に一致し変換できる必要があります。 同様に、CASE式が全体として既知の出力型を持つようになるために、CASE構文の分岐式は共通の型に変換される必要があります。
システムカタログには、データ型間の変換、キャストと呼ばれます、が有効かどうかやその変換の実行方法に関する情報を格納します。 ユーザはCREATE CASTコマンドを使用してキャストを追加することができます。 (これは通常新しいデータ型を定義する時にまとめて行なわれます。組み込み型間のキャスト集合は注意深く作成されており、また、変更しないことが最善です。)
更に、SQL標準型用の適切な動作をうまく推測できるようにするための発見的方法がパーサに提供されています。 基本的な型カテゴリとして、boolean、numeric、string、bitstring、datetime、timespan、geometric、network、ユーザ定義が定義されています。 ユーザ定義を除いた各カテゴリは、あいまいさがある場合に優先的に選択される、1つ以上の好ましい型を持ちます。 ユーザ定義カテゴリでは、それぞれの型はそれ自身の好ましい型です。 従って、あいまいな式(複数の解析結果侯補を持つもの)は、複数の可能な組み込み型があったとしてもしばしば解決できますが、複数のユーザ定義型選択肢がある場合にはエラーが発生します。
すべての型変換規則は次のようないくつかの基本的な考え方に基づいて設計されています。
暗黙的な変換は、びっくりするような、あるいは、予想できない結果を持つべきではない。
パーサがあらかじめ知ることのないユーザ定義型は型の階層内で"より高位"にあるべきです。 型が混在する式では、固有型は常にユーザ定義型に変換されます(もちろん、変換が必要なときのみです)。
ユーザ定義型は関係を持ちません。 現時点では、PostgreSQLは型の間における関係について、組み込み型用に直接コードで特別に作成したものと、利用可能な関数とキャストに基づいた暗黙的な関係を除いては、有効な情報を保有していません。
暗黙的な型変換を必要としない問い合わせの場合、パーサやエクザキュータに余計なオーバヘッドがあるべきではありません。 つまり、問い合わせがきちんとまとめられ、型がすでに一致するものになっていれば、パーサ内で余計な時間を費やすことがなく、また、問い合わせに不要な暗黙的な型変換関数が使用されないように問い合わせは処理されるべきです。
さらに、もし問い合わせが通常は関数を使った暗黙的な変換を要求していたものであり、そして、ユーザが正しい引数型をもつ関数を明示的に定義した場合、パーサはこの新しい関数を使い、古い関数を使った暗黙的な変換を行わないようにすべきです。