表 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(valtype1,basetype1,offsettype2,subbool,lessbool) 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とマークされます。