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