Chapter 5. 型変換

Table of Contents
5.1. 概要
5.2. 演算子
5.3. 関数
5.4. 問い合わせの対象
5.5. UNION と CASE 構築子

意図的かどうかに関らず、 1 つの式の中に異なる型を混ぜ合わせた式を SQL の問い合わせでは持つことができま す。 Postgres は 異なる型が混在する式の 評価に関して幅広い能力を持っています。

この章は Postgres の型変換機構とその規定 について紹介します。特定のデータ型、 使用できる関数と演算子についての 情報については、 ユーザガイドとプログラマガイドの関連する節を参照して下さい。

プログラマガイドには、暗黙的な型変換と強制に使用される正確な アルゴリズムについて、より詳細に記述されています。

5.1. 概要

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)
という問い合わせは textpoint という 2 つの型を 指定した文字列を持ちます。型が指定されていない場合、後述するように、後の段階で 解決されるように、とりあえず場所を確保するための型、 unknown が割り当てられます。

Postgres 個別の型変換ルールが必要な 4 つの基礎的な SQL 構成要素があります。

演算子

Postgres では、(引数が 2 つである) 二項演算子と同様、(引数が 1 つである) 左方単項、右方単項演算子を持つ式が使用できます。

関数呼び出し

Postgres の型システムの多くは、多くの関数の集合を 持って構築されています。ある特定の問い合わせにおける関数呼び出しは引数 を 1 つ以上もち、システムカタログ内で使用可能とされている関数定義に一致 していなければいけません。Postgresは関数の オーバーロードを許可するので、関数名のみでは呼び出される関数を一意に 識別しません。パーサが、与えられる引数のデータ型に基づいて正しい 関数を選択しなければなりません。

問い合わせの対象

SQL のINSERT と UPDATE 文は問い合わせの結果をテーブルの 中に格納します。問い合わせ内の式は対象となるカラムの型に一致する、 または、変換できるものである必要があります。

UNION と CASE 構造体

UNION SELECT 文からの select 結果は全て、ある一つのカラム集合に現れなければ いけませんので、各 SELECT 句の型は統一された集合に一致し変換できる必要 があります。同様に、CASE 構造体の結果の式は、CASE 式が全体として既知の 出力型を持つようになるために、CASE 構成要素の結果式は共通の型を強制 する必要があります。

一般的な型の変換ルールの多くは、Postgres 関数と演算子のシステムテーブルに組み込まれている簡単な規定を使用します。 smallintintegerfloat といった、 SQL92 標準に固有の型の変換をよりうまくサポートする ために、変換ルールには特別に用意されたものもあります。

Postgres パーサは、全ての型変換関数は変換元 となる型の引数を 1 つとり、対象とする型と同じ名前の関数名となっているという 規定を用いています。この基準に従う関数は全て、有効な変換関数とみなされ、 パーサによって変換関数として使用される可能性があります。この簡単な仮定に よって、パーサは、直接コード内に記述することなく型変換を表現できます。 ですから、拡張されたユーザ定義型はこの機能を透過的に使用できるわけです。

更に、SQL 標準型用の適切な動作をうまく推測できるように するための発見的方法がパーサに提供されています。基本的な 型カテゴリは、ブール値、数値、文字列、 ビット文字列、日付、timespan、幾何学データ、ネットワーク、ユーザ定義 があります。ユーザ定義を除いた各カテゴリは、曖昧さがある場合に優先的に 選択される 好ましい型 を持ちます。 ユーザ定義カテゴリでは、それぞれの型はそれ自身の好ましい型です。 曖昧な式(複数の解析結果侯補を持つもの)は、複数の可能な組み込み型が あればしばしば解決されますが、複数のユーザ定義型選択子がある場合 エラーが発生します。

5.1.1. ガイドライン

全ての型変換ルールは次のような考えの数個の原理に基づいて設計されています。

  • 暗黙的な変換は、びっくりするようなあるいは、予想できない結果を持つべきではない。

  • パーサがあらかじめ知ることのないユーザ定義型は型の階層内で "より高位" にあるべきです。型が混在する式では、固有型は常にユーザ定義型に 変換されます。(もちろん、変換が必要な時のみです。)

  • ユーザ定義型は関係を持ちません。現時点では、 Postgres は型の間における関係について、 組み込み型用に直接コードで特別に作成したものと、カタログ内の使用可能 な関数に基づいた暗黙的な関係を除いては、有効な情報を保有していません。

  • 暗黙的な型変換を必要としない問い合わせの場合、パーサやエクザキュー タに余計な オーバヘッドがあるべきではありません。つまり、問い合わせ がきちんとまとめられ、 型が既に一致するものになっていれば、パーサ内で余計な時間を費やすことがなく、 また、 問い合わせに不要な暗黙的な型変換関数が使用されないように問い合わせは処理 されるべきです。

    更に、もし問い合わせが通常は関数を使った暗黙的な変換を要求していたものであり、 そして、ユーザが正しい引数型をもつ関数を明示的に定義した場合、パーサは この新しい関数を使い、古い関数を使った暗黙的な変換を行なわないように すべきです。