演算子

変換プロシージャ

演算子の評価

  1. pg_operator システムカタログ内で正確に一致するかどうかを点検します。

    1. 二項演算子の 1 つの引数が unknown であった場合、もう片 方の引数と同一の型であると仮定します。

    2. 引数を反転します。その演算子の交代演算子であると指定された演算子に一致す るものを検索します。もし存在するならば、パースツリー内の引数を反転し、 見つけた演算子を使用します。

  2. 最も合うものを検索します。

    1. 同じ名前を持つ全演算子の一覧を作成します。

    2. 一覧内に 1 つの演算子しかない場合、もし入力型を強制できればこの演算 子を使用し、できなければ、エラーを発生します。

    3. 型に最も明白に合う演算子を全て保持します。もし合うものがなければ全てを 保持し、次の段階に進みます。候補が 1 つのみ残った場合は、その型を強制 できるのならばそれを使用します。

    4. 入力引数が全て "unknown" ならば、入力候補をブール値、数値、文字列、 地理的情報、ユーザ定義というカテゴリに分類します。正しい選択肢を推 論するための手がかりがこれ以上ありませんので、カテゴリが混在する場 合またはユーザ定義型が 1 つ以上ある場合は、エラーを発生します。1 つ のカテゴリのみが存在する場合、以前は "unknown" であった入力カラムに "好ましい型" を代入します。

    5. もっとも正しく型に合う、そして、前の段階で得た各カラムのカテゴリの "好ましい型" に合う候補を選択します。まだ複数の候補がある場合や候補 が無くなった場合は、エラーを発生します。

指数演算子

カタログ内に定義された指数演算子は 1 つだけ存在し、float8 型の引数をとります。スキャナは、次の問い合わせの式の両方の引数に int4 という初期段階での型を割り当てます。

tgl=> select 2 ^ 3 AS "Exp";
Exp
---
  8
(1 row)
ですので、パーサは両引数に型変換を行ない、上の問い合わせは
tgl=> select float8(2) ^ float8(3) AS "Exp";
Exp
---
  8
(1 row)
、または、
tgl=> select 2.0 ^ 3.0 AS "Exp";
Exp
---
  8
(1 row)
と同じものになります。

Note: 暗黙的な型変換を行なう関数を呼び出すことがありませんので、最後の形 式が最もオーバヘッドの少ないものになります。これは小さな問い合わせ では問題にはなりませんが、大きなテーブルを伴う問い合わせの性能に影 響を与える可能性があります。

文字列の結合

文字列のような文法は、複雑な拡張された型を使った作業用だけでなく、 文字列型を使った作業用として使用されます。型指定のない文字列は演算 子候補と同様の一致がなされます。

1 つの引数が指定されていない場合

tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
Text and Unknown
----------------
abcdef
(1 row)

この場合、パーサは、text を両引数にとる演算子が存在す るかどうかを検索します。これは存在しますので、パーサは 2 番目の引数 は text 型として解釈すべきであると仮定をします。

型指定の無い結合の場合

tgl=> SELECT 'abc' || 'def' AS "Unspecified";
Unspecified
-----------
abcdef
(1 row)

この場合、問い合わせに型が何も指定されていませんので使用すべき型に ついてのヒントが初期段階において存在しません。ですので、パーサは全 ての候補となる演算子を検索し、候補全てについて、その候補の全引数が 文字列型であるものを見つけます。パーサは、この問い合わせ用の型とし て、文字列型の "好ましい型" である、text を選択します。

Note: ユーザが新しい型を定義し、その型用の "||" 演算子を定義 した場合、この問い合わせは記述した通りに動かないようになります。パー サは 2 つのカテゴリから型の候補を持つことになり、どちらを使えば良い のかを決定できなくなります。

階乗

この例は興味深い結果を示しています。歴史的に、階乗演算子は整数型につ いてのみ定義されています。Postgres 演算子 カタログは、階乗用に整数を引数としてとる 1 つのエントリしか持ちませ ん。もし非整数の数字を引数として渡した場合、 Postgres は、その引数を整数に変換して階乗 計算を行なうようになります。

tgl=> select (4.3 !);
?column?
--------
      24
(1 row)

Note: 非整数の階乗の原理が定義されていませんので、もちろん、これは数学的 に疑わしい結果を導き出します。しかしデータベースの役割は数学を教え るものでは無く、データを操作する道具です。ユーザが浮動小数点数値の 階乗を計算することを選択したならば、 Postgres はその要求に応えようとします。