バージョンごとのドキュメント一覧

70.3. 拡張性 #

<title>Extensibility</title>

The <acronym>GIN</acronym> interface has a high level of abstraction, requiring the access method implementer only to implement the semantics of the data type being accessed. The <acronym>GIN</acronym> layer itself takes care of concurrency, logging and searching the tree structure. GINインタフェースは高度に抽象化されています。 アクセスメソッド実装者に要求されることは、アクセスするデータ型の意味を実装することだけです。 GIN層自体が同時実行性、ログ処理、ツリー構造の検索処理に関する面倒を見ます。

All it takes to get a <acronym>GIN</acronym> access method working is to implement a few user-defined methods, which define the behavior of keys in the tree and the relationships between keys, indexed items, and indexable queries. In short, <acronym>GIN</acronym> combines extensibility with generality, code reuse, and a clean interface. GINアクセスメソッドを動作させるために必要なことは、少数のユーザ定義関数を実装することだけです。 これは、ツリー内のキーの動作とキーとインデックス付けされる項目、インデックス可能な問い合わせ間の関係を定義します。 すなわち、GINは、一般化、コード再利用、整理されたインタフェースによる拡張性を組み合わせます。

There are two methods that an operator class for <acronym>GIN</acronym> must provide: GIN用の演算子クラスが提供しなければならないメソッドは2つあります。

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

Returns a palloc'd array of keys given an item to be indexed. The number of returned keys must be stored into <literal>*nkeys</literal>. If any of the keys can be null, also palloc an array of <literal>*nkeys</literal> <type>bool</type> fields, store its address at <literal>*nullFlags</literal>, and set these null flags as needed. <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value) if all keys are non-null. The return value can be <symbol>NULL</symbol> if the item contains no keys. インデックス対象値に与えられる、pallocで割り当てられたキーの配列を返します。 返されるキーの数は*nkeysに格納しなければなりません。 キーのいずれかがNULLになるかもしれない場合、*nkeys個のboolの配列をpallocで割り当てそのアドレスを*nullFlagsに格納し、必要に応じてNULLフラグを設定してください。 すべてのキーが非NULLであれば、*nullFlagsNULL(初期値)のままにすることができます。 項目がキーを含まない場合、戻り値はNULLになるかもしれません。

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

Returns a palloc'd array of keys given a value to be queried; that is, <literal>query</literal> is the value on the right-hand side of an indexable operator whose left-hand side is the indexed column. <literal>n</literal> is the strategy number of the operator within the operator class (see <xref linkend="xindex-strategies"/>). Often, <function>extractQuery</function> will need to consult <literal>n</literal> to determine the data type of <literal>query</literal> and the method it should use to extract key values. The number of returned keys must be stored into <literal>*nkeys</literal>. If any of the keys can be null, also palloc an array of <literal>*nkeys</literal> <type>bool</type> fields, store its address at <literal>*nullFlags</literal>, and set these null flags as needed. <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value) if all keys are non-null. The return value can be <symbol>NULL</symbol> if the <literal>query</literal> contains no keys. 問い合わせ対象の値に与えられる、pallocで割り当てられたキーの配列を返します。 つまり、queryはインデックス可能な演算子の右辺の値です。 この左辺はインデックス対象の列です。 nは演算子クラス内の演算子の戦略番号です(38.16.2を参照)。 extractQueryはしばしば、queryのデータ型とキー値を抽出するために使用しなければならないメソッドを決定するために、nを調べなければなりません。 返されるキーの数を*nkeysに格納しなければなりません。 キーのいずれかがNULLとなる可能性がある場合はまた、*nkeys個のboolの配列をpallocで割り当て、*nullFlagsにそのアドレスを格納し、必要に応じてNULLフラグを設定してください。 すべてのキーが非NULLならば*nullFlagsNULL(初期値)のままにしておくことができます。 queryがキーを含まない場合、戻り値をNULLにすることができます。

<literal>searchMode</literal> is an output argument that allows <function>extractQuery</function> to specify details about how the search will be done. If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_DEFAULT</literal> (which is the value it is initialized to before call), only items that match at least one of the returned keys are considered candidate matches. If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</literal>, then in addition to items containing at least one matching key, items that contain no keys at all are considered candidate matches. (This mode is useful for implementing is-subset-of operators, for example.) If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_ALL</literal>, then all non-null items in the index are considered candidate matches, whether they match any of the returned keys or not. (This mode is much slower than the other two choices, since it requires scanning essentially the entire index, but it may be necessary to implement corner cases correctly. An operator that needs this mode in most cases is probably not a good candidate for a GIN operator class.) The symbols to use for setting this mode are defined in <filename>access/gin.h</filename>. searchModeは出力引数です。 これによりextractQueryは検索がどのように行われるかの詳細を指定することができます。 *searchModeGIN_SEARCH_MODE_DEFAULT(呼び出し前にこの値に初期化されます。)に設定された場合、返されるキーの少なくとも1つに一致する項目が合致候補とみなされます。 *searchModeGIN_SEARCH_MODE_INCLUDE_EMPTYに設定された場合、少なくとも1つの一致するキーを含む項目に加え、キーをまったく含まない項目が合致候補とみなされます。 (このモードは例えば何のサブセットかを求める演算子を実装する際に有用です。) *searchModeGIN_SEARCH_MODE_ALLに設定された場合、返されるキーのいずれかに一致するかどうかは関係なく、インデックス内の非NULLの項目すべてが合致候補とみなされます。 (このモードは、基本的にインデックス全体のスキャン処理が必要ですので、他の2つの選択肢と比べてかなり低速になります。 しかし境界条件を正確に実装するためにこれが必要になるかもしれません。 おそらく、このモードを必要とする演算子はほとんどの場合、GIN演算子クラス向けに優れた候補ではありません。) このモードを設定するために使用する記号はaccess/gin.hで定義されています。

<literal>pmatch</literal> is an output argument for use when partial match is supported. To use it, <function>extractQuery</function> must allocate an array of <literal>*nkeys</literal> <type>bool</type>s and store its address at <literal>*pmatch</literal>. Each element of the array should be set to true if the corresponding key requires partial match, false if not. If <literal>*pmatch</literal> is set to <symbol>NULL</symbol> then GIN assumes partial match is not required. The variable is initialized to <symbol>NULL</symbol> before call, so this argument can simply be ignored by operator classes that do not support partial match. pmatchは部分一致が提供されている場合に使用する出力引数です。 使用するには、extractQuery*nkeys個のboolの配列を割り当て、そのアドレスを*pmatchに格納しなければなりません。 関連するキーが部分一致を必要とするとき、それぞれの配列要素は真に、そうでなければ偽に設定されなければなりません。 *pmatchNULLに設定されている場合、GINは部分一致が必要ないと想定します。 呼び出し前に変数はNULLに初期化されますので、この引数は部分一致が提供されていない演算子クラスでは、単に無視できます。

<literal>extra_data</literal> is an output argument that allows <function>extractQuery</function> to pass additional data to the <function>consistent</function> and <function>comparePartial</function> methods. To use it, <function>extractQuery</function> must allocate an array of <literal>*nkeys</literal> pointers and store its address at <literal>*extra_data</literal>, then store whatever it wants to into the individual pointers. The variable is initialized to <symbol>NULL</symbol> before call, so this argument can simply be ignored by operator classes that do not require extra data. If <literal>*extra_data</literal> is set, the whole array is passed to the <function>consistent</function> method, and the appropriate element to the <function>comparePartial</function> method. extra_dataは、extractQueryconsistentcomparePartialメソッドに追加データを渡すことができるようにする出力引数です。 使用するには、extractQuery*nkeysポインタの配列を割り当て、そのアドレスを*extra_dataに格納し、そして望まれるものは何でも個別のポインタに格納しなければなりません。 変数は呼び出し前にNULLに初期化されますので、追加データを必要としない演算子クラスでこの引数は単に無視できます。 もし*extra_dataが設定されれば、配列全部がconsistentメソッドに、適切な要素がcomparePartialメソッドに渡されます。

An operator class must also provide a function to check if an indexed item matches the query. It comes in two flavors, a Boolean <function>consistent</function> function, and a ternary <function>triConsistent</function> function. <function>triConsistent</function> covers the functionality of both, so providing <function>triConsistent</function> alone is sufficient. However, if the Boolean variant is significantly cheaper to calculate, it can be advantageous to provide both. If only the Boolean variant is provided, some optimizations that depend on refuting index items before fetching all the keys are disabled. 演算子クラスは、インデックス付けされた項目が問い合わせに一致するか確認する関数も提供しなければなりません。 それは2つの方法で行なわれます。 2値のconsistent関数と3値のtriConsistent関数です。 triConsistentが両方の機能を含みますので、triConsistentだけを提供しても十分です。 しかし、2値の亜種を計算するのが著しく安価であれば、両方を提供することは役に立つかもしれません。 2値の亜種のみが提供されていれば、すべてのキーを取得する前にインデックス項目が一致しないことを確認することに基づく最適化の中には無効となるものもあります。

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

Returns true if an indexed item satisfies the query operator with strategy number <literal>n</literal> (or might satisfy it, if the recheck indication is returned). This function does not have direct access to the indexed item's value, since <acronym>GIN</acronym> does not store items explicitly. Rather, what is available is knowledge about which key values extracted from the query appear in a given indexed item. The <literal>check</literal> array has length <literal>nkeys</literal>, which is the same as the number of keys previously returned by <function>extractQuery</function> for this <literal>query</literal> datum. Each element of the <literal>check</literal> array is true if the indexed item contains the corresponding query key, i.e., if (check[i] == true) the i-th key of the <function>extractQuery</function> result array is present in the indexed item. The original <literal>query</literal> datum is passed in case the <function>consistent</function> method needs to consult it, and so are the <literal>queryKeys[]</literal> and <literal>nullFlags[]</literal> arrays previously returned by <function>extractQuery</function>. <literal>extra_data</literal> is the extra-data array returned by <function>extractQuery</function>, or <symbol>NULL</symbol> if none. インデックス付けられた項目が戦略番号nを持つ問い合わせ演算子を満たす(または、recheck印が返されたときはたぶん満たすかもしれない)場合に真を返します。 GINは項目を明示的に格納しませんので、この関数はインデックス付けされた項目の値に直接アクセスすることができません。 どちらかというと、この問い合わせから取り出される指定された問い合わせで現れるキー値に関する知識が利用できるものです。 check配列は長さnkeysであり、このqueryデータに対して事前に行われたextractQueryが返したキーの数と同じです。 インデックス対象の項目が対応する問い合わせキーを持つ場合、check配列の各要素は真です。 つまり、(check[i] == true)の場合、extractQueryの結果配列のi番目のキーがインデックス対象項目内に存在します。 元のqueryデータは、consistentメソッドがそれを調査する必要がある場合に、渡されます。 このためqueryKeys[]およびnullFlags[]は事前にextractQueryによって返されます。 extra_dataextractQueryにより返された追加データ配列で、ない場合はNULLです。

When <function>extractQuery</function> returns a null key in <literal>queryKeys[]</literal>, the corresponding <literal>check[]</literal> element is true if the indexed item contains a null key; that is, the semantics of <literal>check[]</literal> are like <literal>IS NOT DISTINCT FROM</literal>. The <function>consistent</function> function can examine the corresponding <literal>nullFlags[]</literal> element if it needs to tell the difference between a regular value match and a null match. extractQueryqueryKeys[]内でNULLキーを返す時、インデックス対象項目がNULLキーを含む場合は対応するcheck[]要素は真です、 つまり、check[]の意味はIS NOT DISTINCT FROMのようなものです。 consistent関数は、通常の値の合致とNULL合致との違いを通知する必要がある場合、対応するnullFlags[]要素を検査することができます。

On success, <literal>*recheck</literal> should be set to true if the heap tuple needs to be rechecked against the query operator, or false if the index test is exact. That is, a false return value guarantees that the heap tuple does not match the query; a true return value with <literal>*recheck</literal> set to false guarantees that the heap tuple does match the query; and a true return value with <literal>*recheck</literal> set to true means that the heap tuple might match the query, so it needs to be fetched and rechecked by evaluating the query operator directly against the originally indexed item. 成功の場合、*recheckは、問い合わせ演算子に対してヒープタプルを再検査する必要があればtrue、インデックス検査が的確であればfalseに設定する必要があります。 つまり、falseの戻り値はヒープタプルが問い合わせに一致しないことを保証します。 trueの戻り値で、*recheckがfalseに設定された場合はヒープタプルが問い合わせに一致することを保証します。 trueの戻り値で、*recheckがtrueに設定された場合はヒープタプルが問い合わせに一致する可能性があることを意味します。 したがって、それを取り出し、元のインデックス付けされた項目を直接問い合わせ演算子で評価することで再検査する必要があることを意味します。

GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], Datum queryKeys[], bool nullFlags[])

<function>triConsistent</function> is similar to <function>consistent</function>, but instead of Booleans in the <literal>check</literal> vector, there are three possible values for each key: <literal>GIN_TRUE</literal>, <literal>GIN_FALSE</literal> and <literal>GIN_MAYBE</literal>. <literal>GIN_FALSE</literal> and <literal>GIN_TRUE</literal> have the same meaning as regular Boolean values, while <literal>GIN_MAYBE</literal> means that the presence of that key is not known. When <literal>GIN_MAYBE</literal> values are present, the function should only return <literal>GIN_TRUE</literal> if the item certainly matches whether or not the index item contains the corresponding query keys. Likewise, the function must return <literal>GIN_FALSE</literal> only if the item certainly does not match, whether or not it contains the <literal>GIN_MAYBE</literal> keys. If the result depends on the <literal>GIN_MAYBE</literal> entries, i.e., the match cannot be confirmed or refuted based on the known query keys, the function must return <literal>GIN_MAYBE</literal>. triConsistentconsistentと似ていますが、checkベクターの論理値の代わりに、各キーに対して3つの可能な値があります。GIN_TRUEGIN_FALSEGIN_MAYBEです。 GIN_FALSEGIN_TRUEは通常の論理値と同じ意味であり、GIN_MAYBEはそのキーの存在が分からないこと意味します。 GIN_MAYBE値があれば、インデックス項目が対応する問い合わせキーを含むかどうかに関わらず、項目が確実に一致する場合にのみ関数はGIN_TRUEを返すべきです。 同様に、GIN_MAYBEを含むかどうかに関わらず項目が確実に一致しない場合にのみ関数はGIN_FALSEを返さなければなりません。 結果がGIN_MAYBE項目に依存する、すなわち、分かっている問い合わせキーに基づいて、一致することもしないことも確認できない場合には、関数はGIN_MAYBEを返さなければなりません。

When there are no <literal>GIN_MAYBE</literal> values in the <literal>check</literal> vector, a <literal>GIN_MAYBE</literal> return value is the equivalent of setting the <literal>recheck</literal> flag in the Boolean <function>consistent</function> function. checkベクターにGIN_MAYBE値がなければ、GIN_MAYBE戻り値は論理値のconsistent関数でrecheckフラグを設定することと同じです。

In addition, GIN must have a way to sort the key values stored in the index. The operator class can define the sort ordering by specifying a comparison method: さらに、GINにはインデックス内に格納されているキー値をソートする方法がなければなりません。 演算子クラスは比較メソッドを指定することでソート順を定義できます。

int compare(Datum a, Datum b)

Compares two keys (not indexed items!) and returns an integer less than zero, zero, or greater than zero, indicating whether the first key is less than, equal to, or greater than the second. Null keys are never passed to this function. キー(インデックス付けされる項目ではありません)を比較し、0より小さい、0、または0より大きい整数を返します。 それぞれ、最初のキーが2番目のキーより、小さい、等しい、または大きいことを示します。 NULLキーがこの関数に渡されることはありません。

Alternatively, if the operator class does not provide a <function>compare</function> method, GIN will look up the default btree operator class for the index key data type, and use its comparison function. It is recommended to specify the comparison function in a GIN operator class that is meant for just one data type, as looking up the btree operator class costs a few cycles. However, polymorphic GIN operator classes (such as <literal>array_ops</literal>) typically cannot specify a single comparison function. あるいは、演算子クラスがcompareメソッドを提供しない場合には、GINはそのインデックスキーデータ型に対するデフォルトのbtree演算子クラスを探し、その比較関数を使います。 btree演算子クラスを探すのは処理に多少掛かりますので、GIN演算子クラスの中で比較関数を指定することを勧めます。それはただ一つのデータ型に対するものであることを意味します。 しかし、(array_opsのような)多様GIN演算子クラスでは、通常は単一の比較関数を指定できません。

An operator class for <acronym>GIN</acronym> can optionally supply the following methods: 省略可能ですが、GINに対する演算子クラスは以下のメソッドを提供します。

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

Compare a partial-match query key to an index key. Returns an integer whose sign indicates the result: less than zero means the index key does not match the query, but the index scan should continue; zero means that the index key does match the query; greater than zero indicates that the index scan should stop because no more matches are possible. The strategy number <literal>n</literal> of the operator that generated the partial match query is provided, in case its semantics are needed to determine when to end the scan. Also, <literal>extra_data</literal> is the corresponding element of the extra-data array made by <function>extractQuery</function>, or <symbol>NULL</symbol> if none. Null keys are never passed to this function. 問い合わせキーとインデックスキーの部分一致を比較します。 符号が結果を示す整数が返ります。 ゼロ未満はインデックスキーは問い合わせに一致しないが、インデックススキャンを続けるべきであることを示します。 ゼロはインデックスキーが問い合わせに一致することを示します。 ゼロより大きな値はこれ以上の一致はありえないためインデックススキャンを停止すべきであることを示します。 スキャンをいつ停止するかを決めるためにセマンティクスが必要とされる場合、部分一致問い合わせを生成した演算子の戦略番号nが提供されます。 またextra_dataextractQueryで作成される追加データ配列の対応する要素、もしなければNULLです。 NULLキーがこの関数に渡されることはありません。

void options(local_relopts *relopts)

Defines a set of user-visible parameters that control operator class behavior. 演算子クラスの振舞いを制御するユーザに可視のパラメータの集合を定義します。

The <function>options</function> function is passed a pointer to a <structname>local_relopts</structname> struct, which needs to be filled with a set of operator class specific options. The options can be accessed from other support functions using the <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros. options関数にはlocal_relopts構造体へのポインタが渡されますが、構造体を演算子クラスに固有のオプションの集合で満たすことが必要です。 オプションはマクロPG_HAS_OPCLASS_OPTIONS()PG_GET_OPCLASS_OPTIONS()を使って他のサポート関数からアクセスできます。

Since both key extraction of indexed values and representation of the key in <acronym>GIN</acronym> are flexible, they may depend on user-specified parameters. インデックス付けされた値からのキーの抽出にもGINでのキーの表現にも柔軟性がありますので、ユーザに固有のパラメータに依存するかもしれません。

To support <quote>partial match</quote> queries, an operator class must provide the <function>comparePartial</function> method, and its <function>extractQuery</function> method must set the <literal>pmatch</literal> parameter when a partial-match query is encountered. See <xref linkend="gin-partial-match"/> for details. 部分一致問い合わせをサポートするためには、演算子クラスはcomparePartialメソッドを提供しなければなりません。 またそのextractQueryは、部分一致問い合わせであった時にpmatchパラメータを設定しなければなりません。 詳細については70.4.2を参照してください。

The actual data types of the various <literal>Datum</literal> values mentioned above vary depending on the operator class. The item values passed to <function>extractValue</function> are always of the operator class's input type, and all key values must be of the class's <literal>STORAGE</literal> type. The type of the <literal>query</literal> argument passed to <function>extractQuery</function>, <function>consistent</function> and <function>triConsistent</function> is whatever is the right-hand input type of the class member operator identified by the strategy number. This need not be the same as the indexed type, so long as key values of the correct type can be extracted from it. However, it is recommended that the SQL declarations of these three support functions use the opclass's indexed data type for the <literal>query</literal> argument, even though the actual type might be something else depending on the operator. 上記の各種Datum値の実データ型は、演算子クラスに依存して変動します。 extractValueに渡される項目値は常に演算子クラスの入力型であり、キー値はすべてそのクラスのSTORAGE型でなければなりません。 extractQueryconsistentおよびtriConsistentに渡されるquery引数の型は、戦略番号によって識別されるクラスのメンバ演算子の右辺入力型です。 正しい型のキー値がそこから抽出できる限り、これはインデックス付けされた型と同じである必要はありません。 しかしながら、この3つのサポート関数のSQL宣言では、実際の型は演算子に依存して何か他のものであるとしても、query引数には演算子クラスのインデックス付けされたデータ型を使うことを勧めます。