無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

57.2. 拡張性

GIN インタフェースは高度に抽象化されています。 アクセスメソッド実装者に要求されることは、アクセスするデータ型の意味を実装することだけです。 GIN 層自体が同時実行性、ログ処理、ツリー構造の検索処理に関する注意を行います。

GIN アクセスメソッドを動作させるために取ることは、4つ(または5つ)のユーザ定義関数を実装することだけです。 これは、ツリー内のキーの動作とキーとインデックス付けされる項目、インデックス可能な問い合わせ間の関係を定義します。 すなわち、 GIN は、一般化、コード再利用、整理されたインタフェースによる拡張性を組み合わせます。

GIN 用の演算子クラスが提供しなければならない4つのメソッドを示します。

int compare(Datum a, Datum b)

キー(インデックス付けされる項目ではありません)を比較し、0より小さい、0、または0より大きい整数を返します。 それぞれ、最初のキーが2番目のキーより、小さい、等しい、または大きいことを示します。 NULLキーがこの関数に渡されることはありません。

Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags)

インデックス対象値に与えられる、pallocで割り当てられたキーの配列を返します。 返されるキーの数は *nkeys に格納しなければなりません。 キーのいずれかがNULLになるかもしれない場合、 *nkeys 個の bool の配列をpallocで割り当てそのアドレスを *nullFlags に格納し、必要に応じてNULLフラグを設定してください。 すべてのキーが非NULLであれば、 *nullFlags NULL (初期値)のままにすることができます。 項目がキーを含まない場合、戻り値は NULL になるかもしれません。

Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)

問い合わせ対象の値に与えられる、pallocで割り当てられたキーの配列を返します。 つまり、 query はインデックス可能な演算子の右辺の値です。 この左辺はインデックス対象の列です。 n は演算子クラス内の演算子の戦略番号です( 項35.14.2 を参照)。 extractQuery はしばしば、 query のデータ型とキー値を抽出するために使用しなければならないメソッドを決定するために、 n を調べなければなりません。 返されるキーの数を *nkeys に格納しなければなりません。 キーのいずれかがNULLとなる可能性がある場合はまた、 *nkeys 個の bool の配列をpallocで割り当て、 *nullFlags にそのアドレスを格納し、必要に応じてNULLフラグを設定してください。 すべてのキーが非NULLならば *nullFlags NULL (初期値)のままにしておくことができます。 query がキーを含まない場合、戻り値を NULL にすることができます。

searchMode は出力引数です。 これにより extractQuery は検索がどのように行われるかの詳細を指定することができます。 *searchMode GIN_SEARCH_MODE_DEFAULT (呼び出し前にこの値に初期化されます。)に設定された場合、返されるキーの少なくとも1つに一致する項目が合致候補とみなされます。 *searchMode GIN_SEARCH_MODE_INCLUDE_EMPTY に設定された場合、少なくとも1つの一致するキーを含む項目に加え、キーをまったく含まない項目が合致候補とみなされます。 (このモードは例えば何のサブセットかを求める演算子を実装する際に有用です。) *searchMode GIN_SEARCH_MODE_ALL に設定された場合、返されるキーのいずれかに一致するかどうかは関係なく、インデックス内の非NULLの項目すべてが合致候とみなされます。 (このモードは、基本的にインデックス全体のスキャン処理が必要ですので、他の2つの選択肢と比べてかなり低速になります。 しかし境界条件を正確に実装するためにこれが必要になるかもしれません。 おそらく、このモードを必要とする演算子はほとんどの場合、GIN演算子クラス向けに優れた候補ではありません。) このモードを設定するために使用する記号は access/gin.h で定義されています。

pmatch は部分一致が提供されている場合に使用する出力引数です。 使用するには、 extractQuery *nkeys 論理値の配列を割り当て、そのアドレスを *pmatch に格納しなければなりません。 関連するキーが部分一致を必要とするとき、それぞれの配列要素は真に、そうでなければ偽に設定されなければなりません。 *pmatch NULL に設定されている場合、GINは部分一致が必要ないと想定します。 呼び出し前に変数は NULL に初期化されますので、この引数は部分一致が提供されていない演算子クラスでは、単に無視できます。

extra_data は、 extractQuery consistent comparePartial メソッドに追加データを渡すことができるようにする出力引数です。 使用するには、 extractQuery *nkeys ポインタの配列を割り当て、そのアドレスを *extra_data に格納し、そして望まれるものは何でも個別のポインタに格納しなければなりません。 変数は呼び出し前に NULL に初期化されますので、追加データを必要としない演算子クラスでこの引数は単に無視できます。 もし *extra_data が設定されれば、配列全部が consistent メソッドに、適切な要素が comparePartial メソッドに渡されます。

bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, Datum queryKeys[], bool nullFlags[])

インデックス付けられた項目が戦略番号 n を持つ問い合わせ演算子を満たす(または、recheck印が返されたときはたぶん満たすかもしれない)場合に真を返します。 GIN は項目を明示的に格納しませんので、この関数はインデックス付けされた項目の値に直接アクセスすることができません。 どちらかというと、この問い合わせから取り出される指定された問い合わせで現れるキー値に関する知識が利用できるものです。 check 配列は長さ nkeys であり、この query データに対して事前に行われた extractQuery が返したキーの数と同じです。 インデックス対象の項目が対応する問い合わせキーを持つ場合、 check 配列の各要素は真です。 つまり、(check[i] == TRUE)の場合、 extractQuery の結果配列のi番目のキーがインデックス対象項目内に存在します。 元の query データは、 consistent メソッドがそれを調査する必要がある場合に、渡されます。 このため queryKeys[] および nullFlags[] は事前に extractQuery によって返されます。 extra_data extractQuery により返された追加データ配列で、ない場合は NULL です。

extractQuery queryKeys[] 内でNULLキーを返す時、インデックス対象項目がNULLキーを含む場合は対応する check[] 要素は真です、 つまり、 check[] の意味は IS NOT DISTINCT FROM のようなものです。 consistent 関数は、通常の値の合致とNULL合致との違いを通知する必要がある場合、対応する nullFlags[] 要素を検査することができます。

成功の場合、 *recheck はヒープタプルが問い合わせ演算子に対し再検査を必要とすれば真で、インデックス検査が的確であれば偽です。 つまり、FALSEという戻り値はヒープタプルが問い合わせに合わないことを保証し、 *recheck が付いたTRUEという戻り値はヒープタプルが問い合わせに一致する可能性があるため、それを取り出し、元のインデックス付けされた項目を直接問い合わせ演算子で評価することで再検査する必要があることを意味します。

省略可能ですが、 GIN に対する演算子クラスは第5のメソッドを提供します。

int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)

問い合わせキーとインデックスキーの部分一致を比較します。 符号が結果を示す整数が返ります。 ゼロ未満はインデックスキーは問い合わせに一致しないが、インデックススキャンを続けるべきであることを示します。 ゼロはインデックスキーが問い合わせに一致することを示します。 ゼロより大きな値はこれ以上の一致はありえないためインデックススキャンを停止すべきであることを示します。 スキャンをいつ停止するかを決めるためにセマンテックスが必要とされる場合、部分一致問い合わせを生成した演算子の戦略番号 n が提供されます。 また extra_data extractQuery で作成される追加データ配列の対応する要素、もしなければ NULL です。 NULLキーがこの関数に渡されることはありません。

"部分一致" 問い合わせをサポートするためには、演算子クラスは comparePartial メソッドを提供しなければなりません。 またその extractQuery は、部分一致問い合わせであった時に pmatch パラメータを設定しなければなりません。 詳細については 項57.3.2 を参照してください。

上記の各種 Datum 値の実データ型は、演算子クラスに依存して変動します。 extractValue に渡される項目値は常に演算子クラスの入力型であり、キー値はすべてそのクラスの STORAGE 型でなければなりません。 extractQuery および consistent に渡される query 引数は、戦略番号によって識別されるクラスのメンバ演算子の右辺入力型として指定されたものになります。 正しい型のキー値がそこから抽出できる限り、これは項目の型と同じである必要はありません。


powered by SEO.CUG.NET