表 38.8で示すように、btreeでは一つの必須サポート関数と、2つの省略可能なサポート関数を定義します。
btree演算子族が比較演算子を提供するそれぞれのデータ型の組において、pg_amproc
でサポート関数番号1と、amproclefttype
/amprocrighttype
と等しい比較用の左と右のデータ型(つまりpg_amop
中に定義されている演算子に該当する同じデータ型)が必要です。
比較関数は、2つの非NULL値A
とB
を取り、それぞれA
<
B
、A
=
B
、あるいはA
>
B
であるときに、<
0
、0
あるいは>
0
であるint32
値を返さなければなりません。
NULLの結果は許されません。
そのデータ型のすべての値が比較可能でなければなりません。
src/backend/access/nbtree/nbtcompare.c
に例があります。
比較される値の型が照合可能データ型なら、標準のPG_GET_COLLATION()
機構を使って、適切な照合OIDが比較サポート関数に渡されます。
btree演算子族はオプションで、サポート関数番号2のsort support関数を提供することができます。
これらの関数により、ネィティブの比較サポート関数を呼び出すよりも効率の良いソートを目的とする比較を実装することができます。
このためのAPIは、src/include/utils/sortsupport.h
で定義されています。
オプションで、btree演算子族は、サポート関数番号3で登録されるin_rangeサポート関数を提供することができます。
これらはbtreeインデックス操作中には使われませんが、演算子族の意味を拡張し、RANGE
offset
PRECEDING
とRANGE
offset
FOLLOWING
フレーム境界型などのwindow句をサポートします(4.2.8参照)。
基本的に余分に追加された情報は、演算子族のデータ順に適合するやりで、offset
値を加算あるいは減算する方法です。
in_range
関数は次のシグネチャーを持たなければなりません。
in_range(val
type1,base
type1,offset
type2,sub
bool,less
bool) returns bool
val
とbase
は演算子族がサポートする同じ型(つまり、順序を提供する型)でなければなりません。
しかし、offset
は演算子族がサポートしない異なる型でも構いません。
一例として、組み込みのtime_ops
族はinterval
型のoffset
を持つin_range
関数を提供します。
演算子族は、サポートするすべての型のためのin_range
関数と、複数のoffset
型を提供できます。
個々のin_range
関数は、type1
と等しいamproclefttype
と、type2
と等しいamprocrighttype
とともにpg_amproc
に登録すべきです。
in_range
関数の本質的な意味は、2つの論理値型フラグ引数に依存しています。
それはbase
にoffset
を加算あるいは減算し、次のように結果をval
と比較します。
!
sub
かつ!
less
なら、val
>=
(base
+
offset
)を返します。
!
sub
かつless
なら、val
<=
(base
+
offset
)を返します。
sub
かつ!
less
なら、val
>=
(base
-
offset
)を返します。
sub
かつless
なら、val
<=
(base
-
offset
)を返します。
関数は実行する前にoffset
の符号を検査します。
0より小さければ、ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE
(22013)をエラー文字列「invalid preceding or following size in window function」で引き起こします。
(これはSQL標準によって要求されていますが、非標準の演算子族はおそらくこの制限を無視するかも知れません。意味的に必要性が低いからです。)
この要件は、in_range
関数に委任され、あるデータ型にとって「0より小さい」ということをコアコードが理解せずに済むようになります。
他に期待されることとして、base
+
offset
あるいはbase
-
offset
がオーバーフローしたときに、in_range
関数が実用上その方がよければエラーを引き起こすことを防ぐということがあります。
値がデータ型の許す範囲を逸脱していても、正しい比較結果を決定することができます。
データ型に「infinity」あるいは「NaN」の概念が含まれていると、in_range
の結果が演算子族の通常のソート順と矛盾しないように追加の考慮が必要になるかも知れません。
in_range
関数の結果は、演算子族が課するソート順と矛盾がないようにしなければなりません。
もっと正確に言うと、offset
とsub
のどんな値に対しても次のようになります。
あるval1
とbase
に対して、less
= trueであるin_range
がtrueならば、あるbase
のすべてのval2
<=
val1
に対してtrueでなければなりません。
あるval1
とbase
に対して、less
= trueであるin_range
がfalseならば、あるbase
のすべてのval2
>=
val1
に対してfalseでなければなりません。
あるval
とbase1
に対して、less
= trueであるin_range
がtrueならば、あるval
のすべてのval2
>=
base1
に対してtrueでなければなりません。
あるval
とbase1
に対して、less
= trueであるin_range
がfalseならば、あるval
のすべてのbase2
<=
base1
に対してfalseでなければなりません。
less
= falseのときには、逆の条件のもとで類似の表明が成り立ちます。
順序付けされている型(type1
)が照合可能ならば、標準のPG_GET_COLLATION()
機構を使って、適切な照合OIDがin_range
関数に渡されます。
in_range
関数はNULL入力を扱う必要がなく、典型的にはstrictとマークされます。