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

69.3. 拡張性 #

<title>Extensibility</title>

<acronym>SP-GiST</acronym> offers an interface with a high level of abstraction, requiring the access method developer to implement only methods specific to a given data type. The <acronym>SP-GiST</acronym> core is responsible for efficient disk mapping and searching the tree structure. It also takes care of concurrency and logging considerations. SP-GiSTは高度に抽象化されたインタフェースを提供します。アクセスメソッドの開発者は特定のデータ型専用のメソッドだけを開発する必要があります。 SP-GiSTのコアは効率的なディスクマッピングと木構造の探索を担当します。 また、同時実行制御とログ出力も担当します。

Leaf tuples of an <acronym>SP-GiST</acronym> tree usually contain values of the same data type as the indexed column, although it is also possible for them to contain lossy representations of the indexed column. Leaf tuples stored at the root level will directly represent the original indexed data value, but leaf tuples at lower levels might contain only a partial value, such as a suffix. In that case the operator class support functions must be able to reconstruct the original value using information accumulated from the inner tuples that are passed through to reach the leaf level. SP-GiSTのツリーのリーフタプルは、インデックスの付けられた列の損失のある表現を含むこともできますが、通常はインデックスの付けられた列と同じデータ型の値を含んでいます。 ルートレベルに格納されたリーフタプルは、インデックスが付けられた元のデータの値を直接表現していますが、より下のレベルのリーフタプルは、接尾辞など、部分的な値しか含んでいないかも知れません。 この場合、演算子クラスのサポート関数が、内部タプルをリーフレベルまでたどりながら集める情報を使って元の値を再構築できる必要があります。

When an <acronym>SP-GiST</acronym> index is created with <literal>INCLUDE</literal> columns, the values of those columns are also stored in leaf tuples. The <literal>INCLUDE</literal> columns are of no concern to the <acronym>SP-GiST</acronym> operator class, so they are not discussed further here. SP-GiSTインデックスがINCLUDE列を付けて作成された場合には、その列の値もリーフタプルに格納されます。 INCLUDE列はSP-GiST演算子クラスとは関係ありませんので、ここではこれ以上議論しません。

Inner tuples are more complex, since they are branching points in the search tree. Each inner tuple contains a set of one or more <firstterm>nodes</firstterm>, which represent groups of similar leaf values. A node contains a downlink that leads either to another, lower-level inner tuple, or to a short list of leaf tuples that all lie on the same index page. Each node normally has a <firstterm>label</firstterm> that describes it; for example, in a radix tree the node label could be the next character of the string value. (Alternatively, an operator class can omit the node labels, if it works with a fixed set of nodes for all inner tuples; see <xref linkend="spgist-null-labels"/>.) Optionally, an inner tuple can have a <firstterm>prefix</firstterm> value that describes all its members. In a radix tree this could be the common prefix of the represented strings. The prefix value is not necessarily really a prefix, but can be any data needed by the operator class; for example, in a quad-tree it can store the central point that the four quadrants are measured with respect to. A quad-tree inner tuple would then also contain four nodes corresponding to the quadrants around this central point. 内部タプルは、探索木の分岐点となるため、もっと複雑です。 それぞれの内部タプルは1つ以上のノードの集合を含んでおり、ノードは類似のリーフ値のグループを表現します。 ノードは下向きのリンクを含んでおり、これは下のレベルの別の内部タプルを指すか、あるいはすべて同じインデックスページ上に載っているリーフタプルの短いリストを指しています。 それぞれのノードは、通常、それを記述するラベルを持っています。 例えば、基数木では、ノードのラベルは文字列の値の次の文字にすることができます。 (あるいは、すべての内部タプルについて、決まったノードの集合しか扱わないのであれば、演算子クラスはノードのラベルを省略することができます。 69.4.2を参照してください。) 省略可能ですが、内部タプルはそのすべてのメンバーを記述する接頭辞の値を持つことができます。 基数木では、これは表現される文字列に共通の接頭辞とすることができます。 接頭辞の値は、必ずしも本当の接頭辞である必要はなく、演算子クラスが必要とする任意の値で良いです。 例えば四分木では、その中心点を保持し、4つの象限をそこから相対的に測るようにできます。 そうすると、四分木の内部タプルはこの中心点の周りの象限に対応する4つのノードも含むことになるでしょう。

Some tree algorithms require knowledge of level (or depth) of the current tuple, so the <acronym>SP-GiST</acronym> core provides the possibility for operator classes to manage level counting while descending the tree. There is also support for incrementally reconstructing the represented value when that is needed, and for passing down additional data (called <firstterm>traverse values</firstterm>) during a tree descent. 木構造のアルゴリズムには、現在のタプルのレベル(深さ)を知っていることが必要なものがあります。そこで、SP-GiSTのコアは、演算子クラスが木構造をたどって下がるときにレベル数の管理を可能にしています。 また、必要であれば、表現される値を加算的に再構築すること、また木構造を下る間に追加データ(探索値と呼ばれます)を渡すこともサポートしています。

注記

The <acronym>SP-GiST</acronym> core code takes care of null entries. Although <acronym>SP-GiST</acronym> indexes do store entries for nulls in indexed columns, this is hidden from the index operator class code: no null index entries or search conditions will ever be passed to the operator class methods. (It is assumed that <acronym>SP-GiST</acronym> operators are strict and so cannot succeed for null values.) Null values are therefore not discussed further here. SP-GiSTのコアのコードはnullエントリについても対応しています。 SP-GiSTのインデックスはインデックス列がnullのエントリについても格納しますが、これはインデックスの演算子クラスのコードからは隠されているので、nullのインデックスエントリや検索条件が演算子クラスのメソッドに渡されることはありません。 (SP-GiSTの演算子は厳格なのでNULL値について成功を返すことはできないと想定されています。) 従って、ここではこれ以上、NULLについて議論しません。

There are five user-defined methods that an index operator class for <acronym>SP-GiST</acronym> must provide, and two are optional. All five mandatory methods follow the convention of accepting two <type>internal</type> arguments, the first of which is a pointer to a C struct containing input values for the support method, while the second argument is a pointer to a C struct where output values must be placed. Four of the mandatory methods just return <type>void</type>, since all their results appear in the output struct; but <function>leaf_consistent</function> returns a <type>boolean</type> result. The methods must not modify any fields of their input structs. In all cases, the output struct is initialized to zeroes before calling the user-defined method. The optional sixth method <function>compress</function> accepts a <type>datum</type> to be indexed as the only argument and returns a value suitable for physical storage in a leaf tuple. The optional seventh method <function>options</function> accepts an <type>internal</type> pointer to a C struct, where opclass-specific parameters should be placed, and returns <type>void</type>. SP-GiSTのインデックス演算子クラスが提供しなければならないユーザ定義メソッドは5つあり、加えて、オプションのメソッドが2つあります。 5つの必須メソッド全ては2つのinternal引数を受け付けるというしきたりに従い、1つ目はサポートメソッドへの入力値を含むC構造体へのポインタで、一方2つ目は出力値が配置されるであろうC構造体へのポインタです。 4つの必須メソッドでは、その結果がすべて出力構造体の中にあるので、単にvoidを返します。ですが、leaf_consistentbooleanの結果を返します。 メソッドは、その入力構造体のどのフィールドも変更してはいけません。 どんな場合でも、出力構造体はユーザ定義メソッドを呼び出す前にゼロに初期化されます。 オプションの6番目のメソッドcompressは、唯一の引数としてインデックス付けされるdatumを受け付け、リーフタプルの物理格納に適した値を返します。 オプションの7番目のメソッドoptionsは、演算子クラスに固有のパラメータを入れるC構造体へのinternalポインタを受け付け、voidを返します。

The five mandatory user-defined methods are: 5つの必須ユーザ定義メソッドは以下のとおりです。

config

Returns static information about the index implementation, including the data type OIDs of the prefix and node label data types. 接頭辞とノードラベルのデータ型のデータ型OIDを含め、インデックスの実装に関する静的情報を返します。

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE FUNCTION my_config(internal, internal) RETURNS void ...

The first argument is a pointer to a <structname>spgConfigIn</structname> C struct, containing input data for the function. The second argument is a pointer to a <structname>spgConfigOut</structname> C struct, which the function must fill with result data. 1番目の引数はCのspgConfigIn構造体へのポインタで、関数の入力データを含みます。 2番目の引数はCのspgConfigOut構造体へのポインタで、関数が結果のデータを入れます。

typedef struct spgConfigIn
{

    Oid         attType;        /* Data type to be indexed */

    Oid         attType;        /* インデックス付けされるデータ型 */
} spgConfigIn;

typedef struct spgConfigOut
{

    Oid         prefixType;     /* Data type of inner-tuple prefixes */
    Oid         labelType;      /* Data type of inner-tuple node labels */
    Oid         leafType;       /* Data type of leaf-tuple values */
    bool        canReturnData;  /* Opclass can reconstruct original data */
    bool        longValuesOK;   /* Opclass can cope with values &gt; 1 page */

    Oid         prefixType;     /* 内部タプルの接頭辞のデータ型 */
    Oid         labelType;      /* 内部タプルのノードのラベルのデータ型 */
    Oid         leafType;       /* リーフタプル値のデータ型 */
    bool        canReturnData;  /* 演算子クラスは元のデータを再構築できる */
    bool        longValuesOK;   /* 演算子クラスは1ページより大きな値を扱える */
} spgConfigOut;

<structfield>attType</structfield> is passed in order to support polymorphic index operator classes; for ordinary fixed-data-type operator classes, it will always have the same value and so can be ignored. attTypeは多様のインデックス演算子クラスをサポートするために渡されます。 通常の固定データ型の演算子クラスでは、それは常に同じ値を持っているので無視できます。

For operator classes that do not use prefixes, <structfield>prefixType</structfield> can be set to <literal>VOIDOID</literal>. Likewise, for operator classes that do not use node labels, <structfield>labelType</structfield> can be set to <literal>VOIDOID</literal>. <structfield>canReturnData</structfield> should be set true if the operator class is capable of reconstructing the originally-supplied index value. <structfield>longValuesOK</structfield> should be set true only when the <structfield>attType</structfield> is of variable length and the operator class is capable of segmenting long values by repeated suffixing (see <xref linkend="spgist-limits"/>). 接頭辞を使わない演算子クラスでは、prefixTypeVOIDOIDに設定することができます。 同様に、ノードラベルを使わない演算子クラスでは、labelTypeVOIDOIDに設定することができます。 演算子クラスが、元々提供されていたインデックスの値を再構築できるときは、canReturnDataをtrueにします。 attTypeが可変長で、演算子クラスが接尾辞付けの繰り返しによって長い値を分割できるときにのみ、longValuesOKをtrueにします(69.4.1参照)。

<structfield>leafType</structfield> should match the index storage type defined by the operator class's <structfield>opckeytype</structfield> catalog entry. (Note that <structfield>opckeytype</structfield> can be zero, implying the storage type is the same as the operator class's input type, which is the most common situation.) For reasons of backward compatibility, the <function>config</function> method can set <structfield>leafType</structfield> to some other value, and that value will be used; but this is deprecated since the index contents are then incorrectly identified in the catalogs. Also, it's permissible to leave <structfield>leafType</structfield> uninitialized (zero); that is interpreted as meaning the index storage type derived from <structfield>opckeytype</structfield>. leafTypeは、演算子クラスのopckeytypeカタログエントリにより定義されたインデックス格納型と一致しなければなりません。 (opckeytypeは0の場合もあり得て、それは格納型が演算子クラスの入力型と同じであることを意味しています。これが最も一般的な状況であることに注意してください。) 後方互換性のため、configメソッドはleafTypeを他の値に設定して、その値を使うことができます。ですが、インデックスの内容がカタログでは誤って特定されますので、これは非推奨です。 また、leafTypeを初期化しないまま(0)にできます。これはopckeytypeから導かれたインデックス格納型を意味すると解釈されます。

When <structfield>attType</structfield> and <structfield>leafType</structfield> are different, the optional method <function>compress</function> must be provided. Method <function>compress</function> is responsible for transformation of datums to be indexed from <structfield>attType</structfield> to <structfield>leafType</structfield>. attTypeleafTypeが異なる場合には、オプションのメソッドcompressを提供しなければなりません。 メソッドcompressは、インデックス付けされるデータをattTypeからleafTypeに変換する責任があります。

choose

Chooses a method for inserting a new value into an inner tuple. 内部タプルに新しい値を挿入するときのメソッドを選択します。

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE FUNCTION my_choose(internal, internal) RETURNS void ...

The first argument is a pointer to a <structname>spgChooseIn</structname> C struct, containing input data for the function. The second argument is a pointer to a <structname>spgChooseOut</structname> C struct, which the function must fill with result data. 1番目の引数はCのspgChooseIn構造体へのポインタで、関数の入力データを含みます。 2番目の引数はCのspgChooseOut構造体へのポインタで、関数が結果のデータを入れます。

typedef struct spgChooseIn
{

    Datum       datum;          /* original datum to be indexed */
    Datum       leafDatum;      /* current datum to be stored at leaf */
    int         level;          /* current level (counting from zero) */

    Datum       datum;          /* インデックス付けされる元のデータ */
    Datum       leafDatum;      /* リーフに保存されている現在のデータ */
    int         level;          /* (0から数えた)現在のレベル */


    /* Data from current inner tuple */
    bool        allTheSame;     /* tuple is marked all-the-same? */
    bool        hasPrefix;      /* tuple has a prefix? */
    Datum       prefixDatum;    /* if so, the prefix value */
    int         nNodes;         /* number of nodes in the inner tuple */
    Datum      *nodeLabels;     /* node label values (NULL if none) */

    /* 現在の内部タプルからのデータ */
    bool        allTheSame;     /* タプルはall-the-sameの印を付けられているか */
    bool        hasPrefix;      /* タプルは接頭辞を持っているか */
    Datum       prefixDatum;    /* そうであれば、接頭辞の値 */
    int         nNodes;         /* 内部タプル内のノード数 */
    Datum      *nodeLabels;     /* ノードのラベルの値(なければNULL) */
} spgChooseIn;

typedef enum spgChooseResultType
{

    spgMatchNode = 1,           /* descend into existing node */
    spgAddNode,                 /* add a node to the inner tuple */
    spgSplitTuple               /* split inner tuple (change its prefix) */

    spgMatchNode = 1,           /* 既存のノードに下がる */
    spgAddNode,                 /* ノードに内部タプルを追加する */
    spgSplitTuple               /* 内部タプルを分割する(その接頭辞を変更する) */
} spgChooseResultType;

typedef struct spgChooseOut
{

    spgChooseResultType resultType;     /* action code, see above */

    spgChooseResultType resultType;     /* アクションコード、上記参照 */
    union
    {

        struct                  /* results for spgMatchNode */

        struct                  /* spgMatchNodeの結果 */
        {

            int         nodeN;      /* descend to this node (index from 0) */
            int         levelAdd;   /* increment level by this much */
            Datum       restDatum;  /* new leaf datum */

            int         nodeN;      /* このノードに下がる(0からのインデックス) */
            int         levelAdd;   /* この分だけレベルを増やす */
            Datum       restDatum;  /* 新しいリーフデータ */
        }           matchNode;

        struct                  /* results for spgAddNode */

        struct                  /* spgAddNodeの結果 */
        {

            Datum       nodeLabel;  /* new node's label */
            int         nodeN;      /* where to insert it (index from 0) */

            Datum       nodeLabel;  /* 新しいノードのラベル */
            int         nodeN;      /* 挿入する場所(0からのインデックス) */
        }           addNode;

        struct                  /* results for spgSplitTuple */

        struct                  /* spgSplitTupleの結果 */
        {

            /* Info to form new upper-level inner tuple with one child tuple */
            bool        prefixHasPrefix;    /* tuple should have a prefix? */
            Datum       prefixPrefixDatum;  /* if so, its value */
            int         prefixNNodes;       /* number of nodes */
            Datum      *prefixNodeLabels;   /* their labels (or NULL for
                                             * no labels) */
            int         childNodeN;         /* which node gets child tuple */

            /* 子タプルを1つ持つ新しい上位のレベルの内部タプルを生成するための情報 */
            bool        prefixHasPrefix;    /* タプルは接頭辞を持つか */
            Datum       prefixPrefixDatum;  /* そうならば、その値 */
            int         prefixNNodes;       /* ノード数 */
            Datum      *prefixNodeLabels;   /* そのラベル(ラベルがなければNULL) */
            int         childNodeN;         /* どのタプルが子タプルを得るか */


            /* Info to form new lower-level inner tuple with all old nodes */
            bool        postfixHasPrefix;   /* tuple should have a prefix? */
            Datum       postfixPrefixDatum; /* if so, its value */

            /* 古いノードをすべて持つ新しい低位の内部タプルを生成するための情報 */
            bool        postfixHasPrefix;   /* タプルは接頭辞を持つか */
            Datum       postfixPrefixDatum; /* そうならば、その値 */
        }           splitTuple;
    }           result;
} spgChooseOut;

<structfield>datum</structfield> is the original datum of <structname>spgConfigIn</structname>.<structfield>attType</structfield> type that was to be inserted into the index. <structfield>leafDatum</structfield> is a value of <structname>spgConfigOut</structname>.<structfield>leafType</structfield> type, which is initially a result of method <function>compress</function> applied to <structfield>datum</structfield> when method <function>compress</function> is provided, or the same value as <structfield>datum</structfield> otherwise. <structfield>leafDatum</structfield> can change at lower levels of the tree if the <function>choose</function> or <function>picksplit</function> methods change it. When the insertion search reaches a leaf page, the current value of <structfield>leafDatum</structfield> is what will be stored in the newly created leaf tuple. <structfield>level</structfield> is the current inner tuple's level, starting at zero for the root level. <structfield>allTheSame</structfield> is true if the current inner tuple is marked as containing multiple equivalent nodes (see <xref linkend="spgist-all-the-same"/>). <structfield>hasPrefix</structfield> is true if the current inner tuple contains a prefix; if so, <structfield>prefixDatum</structfield> is its value. <structfield>nNodes</structfield> is the number of child nodes contained in the inner tuple, and <structfield>nodeLabels</structfield> is an array of their label values, or NULL if there are no labels. datumはインデックスに挿入できたspgConfigIn.attType型の元データです。 leafDatumspgConfigOut.leafType型の値です。これは最初は、メソッドcompressが提供されているならdatumに適用されたメソッドcompressの結果で、さもなくばdatumと同じ値です。 leafDatumは、choosepicksplitメソッドがこれを変更すると、ツリーのより低いレベルで変化することがあります。 挿入の探索がリーフページに到達するとき、leafDatumの現在値は、新しく作成されるリーフタプルに格納される値です。 levelは、ルートレベルを0として、現在の内部タプルのレベルを示します。 現在の内部タプルが複数の同等なノードを含むとして印を付けられているとき、allTheSameをtrueにします(69.4.3参照)。 現在の内部タプルが接頭辞を含むとき、hasPrefixをtrueにします。 このとき、prefixDatumがその値になります。 nNodesは内部タプルが含む子ノードの数で、nodeLabelsはそれらのラベル値の配列、あるいはラベルがなければNULLになります。

The <function>choose</function> function can determine either that the new value matches one of the existing child nodes, or that a new child node must be added, or that the new value is inconsistent with the tuple prefix and so the inner tuple must be split to create a less restrictive prefix. choose関数は、新しい値が既存の子ノードの1つとマッチするか、新しい子ノードを追加する必要があるか、あるいは新しい値がタプルの接頭辞と適合しないので内部タプルを分割してより制限のない接頭辞を作成する必要があるか、を決定することができます。

If the new value matches one of the existing child nodes, set <structfield>resultType</structfield> to <literal>spgMatchNode</literal>. Set <structfield>nodeN</structfield> to the index (from zero) of that node in the node array. Set <structfield>levelAdd</structfield> to the increment in <structfield>level</structfield> caused by descending through that node, or leave it as zero if the operator class does not use levels. Set <structfield>restDatum</structfield> to equal <structfield>leafDatum</structfield> if the operator class does not modify datums from one level to the next, or otherwise set it to the modified value to be used as <structfield>leafDatum</structfield> at the next level. 新しい値が既存の子ノードの1つにマッチしたときは、resultTypespgMatchNodeにセットします。 nodeNはノードの配列中のそのノードの(0からの)番号にセットします。 levelAddは、そのノードをたどって下がるときに生じたlevelの増分にセットします。あるいは演算子クラスがレベルを使っていなければ0のままにします。 restDatumは、演算子クラスがデータをあるレベルから次のレベルに変更しないのであれば、datumに等しくセットします。そうでなければ、次のレベルでleafDatumとして使われる修正された値にセットします。

If a new child node must be added, set <structfield>resultType</structfield> to <literal>spgAddNode</literal>. Set <structfield>nodeLabel</structfield> to the label to be used for the new node, and set <structfield>nodeN</structfield> to the index (from zero) at which to insert the node in the node array. After the node has been added, the <function>choose</function> function will be called again with the modified inner tuple; that call should result in an <literal>spgMatchNode</literal> result. 新しい子ノードを追加しなければならないときは、resultTypespgAddNodeにセットします。 nodeLabelは、新しいノードで使われるラベルにセットし、nodeNはノードの配列中の挿入される場所のノードの(0からの)番号にセットします。 ノードを追加した後で、choose関数を修正された内部タプルを使って再び呼び出しますが、このときは、spgMatchNodeという結果になるはずです。

If the new value is inconsistent with the tuple prefix, set <structfield>resultType</structfield> to <literal>spgSplitTuple</literal>. This action moves all the existing nodes into a new lower-level inner tuple, and replaces the existing inner tuple with a tuple having a single downlink pointing to the new lower-level inner tuple. Set <structfield>prefixHasPrefix</structfield> to indicate whether the new upper tuple should have a prefix, and if so set <structfield>prefixPrefixDatum</structfield> to the prefix value. This new prefix value must be sufficiently less restrictive than the original to accept the new value to be indexed. Set <structfield>prefixNNodes</structfield> to the number of nodes needed in the new tuple, and set <structfield>prefixNodeLabels</structfield> to a palloc'd array holding their labels, or to NULL if node labels are not required. Note that the total size of the new upper tuple must be no more than the total size of the tuple it is replacing; this constrains the lengths of the new prefix and new labels. Set <structfield>childNodeN</structfield> to the index (from zero) of the node that will downlink to the new lower-level inner tuple. Set <structfield>postfixHasPrefix</structfield> to indicate whether the new lower-level inner tuple should have a prefix, and if so set <structfield>postfixPrefixDatum</structfield> to the prefix value. The combination of these two prefixes and the downlink node's label (if any) must have the same meaning as the original prefix, because there is no opportunity to alter the node labels that are moved to the new lower-level tuple, nor to change any child index entries. After the node has been split, the <function>choose</function> function will be called again with the replacement inner tuple. That call may return an <literal>spgAddNode</literal> result, if no suitable node was created by the <literal>spgSplitTuple</literal> action. Eventually <function>choose</function> must return <literal>spgMatchNode</literal> to allow the insertion to descend to the next level. 新しい値がタプルの接頭辞と適合しないときは、resultTypespgSplitTupleにセットします。 このアクションは、すべての既存のノードを新しい低位の内部タプルに移動し、新しい低位の内部タプルを指す単一の下向きのリンクを持つ新しいタプルで既存のタプルを置換します。 prefixHasPrefixは新しい上位のタプルが接頭辞を持つかどうかを示し、持つ場合にはprefixPrefixDatumをその接頭辞の値にセットします。 インデックスに追加される新しい値を受け入れるため、新しい接頭辞の値は元のものよりも十分に制限の緩いものになっていなければなりません。 prefixNNodesは新しいタプルで必要なノード数にセットし、prefixNodeLabelsはラベルを保持するためにpallocされた配列に、ノードのラベルが必要でないときはNULLにセットします。 新しい上位のタプルの全サイズは置き換えるタプルの全サイズよりも大きくはないことに注意してください。これは新しい接頭辞と新しいラベルの長さを制約します。 childNodeNは、新しい低位の内部タプルへ下向きにリンクするノードの(0からの)番号にセットします。 postfixHasPrefixは、新しい低位のタプルが接頭辞を持つかどうかを示し、持つときにはpostfixPrefixDatumを接頭辞の値にセットします。 新しい低位に移動したタプルのノードのラベルを変更する機会も、子のインデックスのエントリを変更する機会もありませんから、これら2つの接頭辞と(もしあれば)下向きのリンクのノードのラベルの組み合わせは、元の接頭辞と同じ意味を持つ必要があります。 ノードが分割された後で、置換した内部タプルを使ってchoose関数を再び呼び出します。 この呼び出しは、spgSplitTupleアクションにより適切なノードが作られなければ、spgAddNodeという結果になります。 そのうち、choosespgMatchNodeを返し、次のレベルに下がる挿入が可能となります。

picksplit

Decides how to create a new inner tuple over a set of leaf tuples. リーフタプルの集合に対し、新しい内部タプルをどうやって作るかを決定します。

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ...

The first argument is a pointer to a <structname>spgPickSplitIn</structname> C struct, containing input data for the function. The second argument is a pointer to a <structname>spgPickSplitOut</structname> C struct, which the function must fill with result data. 1番目の引数はCのspgPickSplitIn構造体へのポインタで、関数の入力データを含みます。 2番目の引数はCのspgPickSplitOut構造体へのポインタで、関数が結果のデータを入れます。

typedef struct spgPickSplitIn
{

    int         nTuples;        /* number of leaf tuples */
    Datum      *datums;         /* their datums (array of length nTuples) */
    int         level;          /* current level (counting from zero) */

    int         nTuples;        /* リーフタプルの数 */
    Datum      *datums;         /* そのデータ(長さnTuplesの配列) */
    int         level;          /* (0から数えた)現在のレベル */
} spgPickSplitIn;

typedef struct spgPickSplitOut
{

    bool        hasPrefix;      /* new inner tuple should have a prefix? */
    Datum       prefixDatum;    /* if so, its value */

    bool        hasPrefix;      /* 新しい内部タプルは接頭辞を持つか */
    Datum       prefixDatum;    /* もしそうなら、その値 */


    int         nNodes;         /* number of nodes for new inner tuple */
    Datum      *nodeLabels;     /* their labels (or NULL for no labels) */

    int         nNodes;         /* 新しい内部タプルのノード数 */
    Datum      *nodeLabels;     /* そのラベル(ラベルがなければNULL) */


    int        *mapTuplesToNodes;   /* node index for each leaf tuple */
    Datum      *leafTupleDatums;    /* datum to store in each new leaf tuple */

    int        *mapTuplesToNodes;   /* 各リーフタプルへのノードのインデックス */
    Datum      *leafTupleDatums;    /* 新しい各リーフタプルに保存されているデータ */
} spgPickSplitOut;

<structfield>nTuples</structfield> is the number of leaf tuples provided. <structfield>datums</structfield> is an array of their datum values of <structname>spgConfigOut</structname>.<structfield>leafType</structfield> type. <structfield>level</structfield> is the current level that all the leaf tuples share, which will become the level of the new inner tuple. nTuplesは与えられるリーフタプルの個数です。 datumsspgConfigOut.leafType型のそれらのデータ値の配列です。 levelはすべてのリーフタプルが共有する現在のレベルで、これが新しい内部タプルのレベルになります。

Set <structfield>hasPrefix</structfield> to indicate whether the new inner tuple should have a prefix, and if so set <structfield>prefixDatum</structfield> to the prefix value. Set <structfield>nNodes</structfield> to indicate the number of nodes that the new inner tuple will contain, and set <structfield>nodeLabels</structfield> to an array of their label values, or to NULL if node labels are not required. Set <structfield>mapTuplesToNodes</structfield> to an array that gives the index (from zero) of the node that each leaf tuple should be assigned to. Set <structfield>leafTupleDatums</structfield> to an array of the values to be stored in the new leaf tuples (these will be the same as the input <structfield>datums</structfield> if the operator class does not modify datums from one level to the next). Note that the <function>picksplit</function> function is responsible for palloc'ing the <structfield>nodeLabels</structfield>, <structfield>mapTuplesToNodes</structfield> and <structfield>leafTupleDatums</structfield> arrays. hasPrefixは新しい内部タプルが接頭辞を持つかどうかを示し、持つ場合はprefixDatumを接頭辞の値にセットします。 nNodesは新しい内部タプルが含むノードの数を示し、nodeLabelsはそのラベル値の配列に、ノードのラベルが必要でないときはNULLにセットします。 mapTuplesToNodesは、それぞれのリーフタプルが割り当てられるノードの(0からの)番号の配列にセットします。 leafTupleDatumsは新しいリーフタプルに格納される値の配列にセットします(演算子クラスがデータをあるレベルから次のレベルに変更しなければこれらは入力のdatumsと同じになります)。 picksplit関数は、nodeLabelsmapTuplesToNodesleafTupleDatumsの配列についてpallocしなければならないことに注意してください。

If more than one leaf tuple is supplied, it is expected that the <function>picksplit</function> function will classify them into more than one node; otherwise it is not possible to split the leaf tuples across multiple pages, which is the ultimate purpose of this operation. Therefore, if the <function>picksplit</function> function ends up placing all the leaf tuples in the same node, the core SP-GiST code will override that decision and generate an inner tuple in which the leaf tuples are assigned at random to several identically-labeled nodes. Such a tuple is marked <literal>allTheSame</literal> to signify that this has happened. The <function>choose</function> and <function>inner_consistent</function> functions must take suitable care with such inner tuples. See <xref linkend="spgist-all-the-same"/> for more information. 2つ以上のリーフタプルを与えた場合、picksplit関数はそれらを2つ以上のノードに分類すると予想されます。そうでなければ、リーフタプルを複数のページにまたがって分割するという、この操作の究極の目的を実現できないからです。 従って、picksplitがすべてのリーフタプルを同じノードに置くことになった場合には、SP-GiSTのコアのコードがその決定を覆して内部タプルを生成し、その中の複数の同一のラベルが付けられたノードに、リーフタプルが無作為に割り当てられます。 そのようなタプルは、このことが発生したことを明示するため、allTheSameと印がつけられます。 choose関数とinner_consistent関数は、これらの内部タプルについて、適切な注意をして取り扱わなければなりません。 詳細な情報は69.4.3を参照してください。

<function>picksplit</function> can be applied to a single leaf tuple only in the case that the <function>config</function> function set <structfield>longValuesOK</structfield> to true and a larger-than-a-page input value has been supplied. In this case the point of the operation is to strip off a prefix and produce a new, shorter leaf datum value. The call will be repeated until a leaf datum short enough to fit on a page has been produced. See <xref linkend="spgist-limits"/> for more information. config関数がlongValuesOKをtrueにセットし、1ページよりも大きな入力値を与える場合にのみ、picksplitを1つだけのリーフタプルに適用できます。 この場合の操作の重要な点は、接頭辞をはがして、新しい、より短いリーフデータの値を生成することです。 この呼出は、1ページに収まる短さのリーフデータが生成されるまで繰り返されます。 詳細な情報は69.4.1を参照してください。

inner_consistent

Returns set of nodes (branches) to follow during tree search. ツリーの探索でたどるべきノード(枝)の集合を返します。

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ...

The first argument is a pointer to a <structname>spgInnerConsistentIn</structname> C struct, containing input data for the function. The second argument is a pointer to a <structname>spgInnerConsistentOut</structname> C struct, which the function must fill with result data. 1番目の引数はCのspgInnerConsistentIn構造体へのポインタで、関数の入力データを含みます。 2番目の引数はCのspgInnerConsistentOut構造体へのポインタで、関数が結果のデータを入れます。

typedef struct spgInnerConsistentIn
{

    ScanKey     scankeys;       /* array of operators and comparison values */
    ScanKey     orderbys;       /* array of ordering operators and comparison
                                 * values */
    int         nkeys;          /* length of scankeys array */
    int         norderbys;      /* length of orderbys array */

    ScanKey     scankeys;       /* 演算子と比較する値の配列 */
    ScanKey     orderbys;       /* 順序付け演算子と比較する値の配列 */
    int         nkeys;          /* scankeys配列の長さ */
    int         norderbys;      /* orderbys配列の長さ */


    Datum       reconstructedValue;     /* value reconstructed at parent */
    void       *traversalValue; /* opclass-specific traverse value */
    MemoryContext traversalMemoryContext;   /* put new traverse values here */
    int         level;          /* current level (counting from zero) */
    bool        returnData;     /* original data must be returned? */

    Datum       reconstructedValue;     /* 親で再構築された値 */
    void       *traversalValue; /* 演算子クラスに固有の探索値 */
    MemoryContext traversalMemoryContext;   /* 新しい探索値をここに入れる */
    int         level;          /* (0から数えた)現在のレベル */
    bool        returnData;     /* 元のデータを返さなければならないか */


    /* Data from current inner tuple */
    bool        allTheSame;     /* tuple is marked all-the-same? */
    bool        hasPrefix;      /* tuple has a prefix? */
    Datum       prefixDatum;    /* if so, the prefix value */
    int         nNodes;         /* number of nodes in the inner tuple */
    Datum      *nodeLabels;     /* node label values (NULL if none) */

    /* 現在の内部タプルからのデータ */
    bool        allTheSame;     /* タプルはall-the-sameと印が付けられているか */
    bool        hasPrefix;      /* タプルは接頭辞を持つか */
    Datum       prefixDatum;    /* もしそうなら、接頭辞の値 */
    int         nNodes;         /* 内部タプルの中のノード数 */
    Datum      *nodeLabels;     /* ノードのラベルの値(なければNULL) */
} spgInnerConsistentIn;

typedef struct spgInnerConsistentOut
{

    int         nNodes;         /* number of child nodes to be visited */
    int        *nodeNumbers;    /* their indexes in the node array */
    int        *levelAdds;      /* increment level by this much for each */
    Datum      *reconstructedValues;    /* associated reconstructed values */
    void      **traversalValues;        /* opclass-specific traverse values */
    double    **distances;              /* associated distances */

    int         nNodes;         /* 訪れるべき子ノードの数 */
    int        *nodeNumbers;    /* ノードの配列でのそのインデックス */
    int        *levelAdds;      /* この分だけそれぞれレベルを挙げる */
    Datum      *reconstructedValues;    /* 関連する再構築された値 */
    void      **traversalValues;        /* 演算子クラスに固有の探索値 */
    double    **distances;              /* 関連する距離 */
} spgInnerConsistentOut;

The array <structfield>scankeys</structfield>, of length <structfield>nkeys</structfield>, describes the index search condition(s). These conditions are combined with AND &mdash; only index entries that satisfy all of them are interesting. (Note that <structfield>nkeys</structfield> = 0 implies that all index entries satisfy the query.) Usually the consistent function only cares about the <structfield>sk_strategy</structfield> and <structfield>sk_argument</structfield> fields of each array entry, which respectively give the indexable operator and comparison value. In particular it is not necessary to check <structfield>sk_flags</structfield> to see if the comparison value is NULL, because the SP-GiST core code will filter out such conditions. The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>, describes ordering operators (if any) in the same manner. <structfield>reconstructedValue</structfield> is the value reconstructed for the parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the <function>inner_consistent</function> function did not provide a value at the parent level. <structfield>traversalValue</structfield> is a pointer to any traverse data passed down from the previous call of <function>inner_consistent</function> on the parent index tuple, or NULL at the root level. <structfield>traversalMemoryContext</structfield> is the memory context in which to store output traverse values (see below). <structfield>level</structfield> is the current inner tuple's level, starting at zero for the root level. <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is required for this query; this will only be so if the <function>config</function> function asserted <structfield>canReturnData</structfield>. <structfield>allTheSame</structfield> is true if the current inner tuple is marked <quote>all-the-same</quote>; in this case all the nodes have the same label (if any) and so either all or none of them match the query (see <xref linkend="spgist-all-the-same"/>). <structfield>hasPrefix</structfield> is true if the current inner tuple contains a prefix; if so, <structfield>prefixDatum</structfield> is its value. <structfield>nNodes</structfield> is the number of child nodes contained in the inner tuple, and <structfield>nodeLabels</structfield> is an array of their label values, or NULL if the nodes do not have labels. 配列scankeysは長さがnkeysで、インデックス検索の条件を記述します。 複数の条件はANDで結合されます。つまり、条件のすべてを満たすインデックスエントリのみが対象となります。 (nkeys = 0 は全インデックスエントリが問い合わせを満たす意味になる、ということに注意してください。) 通常、consistent関数では、配列のそれぞれのエントリのsk_strategyおよびsk_argumentフィールドのみが問題となります。これらのフィールドにはそれぞれインデックス付け可能な演算子と比較値が入ります。 とりわけ、比較値がNULLかどうかを確認するためにsk_flagsを検査する必要はありません。なぜならSP-GiSTのコアのコードがそのような条件を除外するからです。 配列orderbysは長さがnorderbysで、(もしあれば)順序付け演算子を同じように記述します。 reconstructedValueは親タプルのために再構築された値で、ルートレベルの場合、あるいは親レベルのinner_consistent関数が値を返さなかった場合は(Datum) 0となります。 traversalValueは親インデックスのタプルのinner_consistentの前の呼び出しから渡された探索データへのポインタで、ルートレベルならNULLです。 traversalMemoryContextは出力探索値が格納されるメモリコンテキストです(以下を参照)。 levelは現在の内部タプルのレベルを、ルートレベルを0として数えたものです。 returnDataは、この問い合わせで再構築されたデータが必要な場合にtrueとなりますが、これはconfig関数がcanReturnDataであると主張した場合にのみ、そうなります。 現在の内部タプルがall-the-sameと印付けされているなら、allTheSameは真になります。この場合、(もしあるなら)全てのノードが同じラベルを持ち、問い合わせに全てが一致するか、全く一致しないかのいずれかになります(69.4.3を参照)。 現在の内部タプルがプレフィックスを含んでいるならhasPrefixは真になります。その場合、prefixDatumがその値です。 nNodesは内部タプルに含まれる子ノードの数で、nodeLabelsはそれらのラベル値の配列、あるいは、ノードがラベルを持たないならNULLです。

<structfield>nNodes</structfield> must be set to the number of child nodes that need to be visited by the search, and <structfield>nodeNumbers</structfield> must be set to an array of their indexes. If the operator class keeps track of levels, set <structfield>levelAdds</structfield> to an array of the level increments required when descending to each node to be visited. (Often these increments will be the same for all the nodes, but that's not necessarily so, so an array is used.) If value reconstruction is needed, set <structfield>reconstructedValues</structfield> to an array of the values reconstructed for each child node to be visited; otherwise, leave <structfield>reconstructedValues</structfield> as NULL. The reconstructed values are assumed to be of type <structname>spgConfigOut</structname>.<structfield>leafType</structfield>. (However, since the core system will do nothing with them except possibly copy them, it is sufficient for them to have the same <literal>typlen</literal> and <literal>typbyval</literal> properties as <structfield>leafType</structfield>.) If ordered search is performed, set <structfield>distances</structfield> to an array of distance values according to <structfield>orderbys</structfield> array (nodes with lowest distances will be processed first). Leave it NULL otherwise. If it is desired to pass down additional out-of-band information (<quote>traverse values</quote>) to lower levels of the tree search, set <structfield>traversalValues</structfield> to an array of the appropriate traverse values, one for each child node to be visited; otherwise, leave <structfield>traversalValues</structfield> as NULL. Note that the <function>inner_consistent</function> function is responsible for palloc'ing the <structfield>nodeNumbers</structfield>, <structfield>levelAdds</structfield>, <structfield>distances</structfield>, <structfield>reconstructedValues</structfield>, and <structfield>traversalValues</structfield> arrays in the current memory context. However, any output traverse values pointed to by the <structfield>traversalValues</structfield> array should be allocated in <structfield>traversalMemoryContext</structfield>. Each traverse value must be a single palloc'd chunk. nNodesは探索で訪れる必要のある子ノードの数にセットされなければなりません。また、nodeNumbersはそれらの番号の配列にセットされなければなりません。 演算子クラスがレベルを監視しているときは、それぞれのノードへと下って訪れるときに必要なレベルの増分の配列をlevelAddsにセットします。 (この増分はすべてのノードについて同じになることも多いですが、必ずしもそうなるとは限らないので配列が使われます。) 値の再構築が必要なときには、訪れるそれぞれの子ノードについて再構築された値の配列をreconstructedValuesにセットします。再構築が必要でなければ、reconstructedValuesをNULLのままにします。 再構築された値はspgConfigOut.leafType型と仮定されます。 (しかしながら、コアシステムはそれらに対してコピー以外のことをしませんので、leafTypeと同じtyplentypbyval属性を持っていれば十分です。) 順序付け検索を実行するなら、orderbys配列に従ってdistancesに距離の値の配列を設定します(距離の最も近いノードが最初に処理されます)。 そうでなければNULLのままにします。 追加の外部情報(探索値)をツリー探索の下位レベルに渡したい場合は、traversalValuesを適切な探索値、訪れるそれぞれの子ノードについて1つの配列にセットします。 それ以外の場合はtraversalValuesをNULLのままにします。 inner_consistent関数は、現在のメモリコンテキスト内のnodeNumberslevelAddsdistancesreconstructedValuestraversalValuesの配列についてpallocしなければならないことに注意してください。 ただし、traversalValues配列が指すすべての出力探索値はtraversalMemoryContext内に割り当てられます。 それぞれの探索値は1つのpallocされた塊でなければなりません。

leaf_consistent

Returns true if a leaf tuple satisfies a query. リーフタプルが問い合わせを満たす場合、trueを返します。

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ...

The first argument is a pointer to a <structname>spgLeafConsistentIn</structname> C struct, containing input data for the function. The second argument is a pointer to a <structname>spgLeafConsistentOut</structname> C struct, which the function must fill with result data. 1番目の引数はCのspgLeafConsistentIn構造体へのポインタで、関数の入力データを含みます。 2番目の引数はCのspgLeafConsistentOut構造体へのポインタで、関数が結果のデータを入れます。

typedef struct spgLeafConsistentIn
{

    ScanKey     scankeys;       /* array of operators and comparison values */
    ScanKey     orderbys;       /* array of ordering operators and comparison
                                 * values */
    int         nkeys;          /* length of scankeys array */
    int         norderbys;      /* length of orderbys array */

    ScanKey     scankeys;       /* 演算子と比較する値の配列 */
    ScanKey     orderbys;       /* 順序付け演算子と比較する値の配列 */
    int         nkeys;          /* scankeys配列の長さ */
    int         norderbys;      /* orderbys配列の長さ */


    Datum       reconstructedValue;     /* value reconstructed at parent */
    void       *traversalValue; /* opclass-specific traverse value */
    int         level;          /* current level (counting from zero) */
    bool        returnData;     /* original data must be returned? */

    Datum       reconstructedValue;     /* 親で再構築された値 */
    void       *traversalValue; /* 演算子クラスに固有の探索値 */
    int         level;          /* (0から数えた)現在のレベル */
    bool        returnData;     /* 元のデータを返さなければならないか */


    Datum       leafDatum;      /* datum in leaf tuple */

    Datum       leafDatum;      /* リーフタプルのデータ */
} spgLeafConsistentIn;

typedef struct spgLeafConsistentOut
{

    Datum       leafValue;        /* reconstructed original data, if any */
    bool        recheck;          /* set true if operator must be rechecked */
    bool        recheckDistances; /* set true if distances must be rechecked */
    double     *distances;        /* associated distances */

    Datum       leafValue;        /* もしあれば、再構築された元のデータ */
    bool        recheck;          /* 演算子を再チェックする必要があればtrue */
    bool        recheckDistances; /* 距離を再チェックする必要があればtrue */
    double     *distances;        /* 関連する距離 */
} spgLeafConsistentOut;

The array <structfield>scankeys</structfield>, of length <structfield>nkeys</structfield>, describes the index search condition(s). These conditions are combined with AND &mdash; only index entries that satisfy all of them satisfy the query. (Note that <structfield>nkeys</structfield> = 0 implies that all index entries satisfy the query.) Usually the consistent function only cares about the <structfield>sk_strategy</structfield> and <structfield>sk_argument</structfield> fields of each array entry, which respectively give the indexable operator and comparison value. In particular it is not necessary to check <structfield>sk_flags</structfield> to see if the comparison value is NULL, because the SP-GiST core code will filter out such conditions. The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>, describes the ordering operators in the same manner. <structfield>reconstructedValue</structfield> is the value reconstructed for the parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the <function>inner_consistent</function> function did not provide a value at the parent level. <structfield>traversalValue</structfield> is a pointer to any traverse data passed down from the previous call of <function>inner_consistent</function> on the parent index tuple, or NULL at the root level. <structfield>level</structfield> is the current leaf tuple's level, starting at zero for the root level. <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is required for this query; this will only be so if the <function>config</function> function asserted <structfield>canReturnData</structfield>. <structfield>leafDatum</structfield> is the key value of <structname>spgConfigOut</structname>.<structfield>leafType</structfield> stored in the current leaf tuple. 配列scankeysは長さがnkeysで、インデックス探索の条件を記述します。 複数の条件はANDで結合されます。つまり、条件のすべてを満たすインデックスエントリのみが対象となります。 (nkeysが0ならば、すべてのエントリが検索条件を満たすことになる、ということに注意してください。) 通常、consistent関数では、配列のそれぞれのエントリのsk_strategyおよびsk_argumentフィールドのみが問題となります。これらのフィールドにはそれぞれインデックス付け可能な演算子と比較値が入ります。 なお、比較値がNULLかどうかを確認するためにsk_flagsを検査する必要はありません。なぜならSP-GiSTのコアのコードがそのような条件を除外するからです。 配列orderbysは長さがnorderbysで、順序付け演算子を同じように記述します。 reconstructedValueは親タプルのために再構築された値で、ルートレベルの場合、あるいは親レベルのinner_consistent関数が値を返さなかった場合は(Datum) 0となります。 traversalValueは親インデックスのタプルのinner_consistentの前の呼び出しから渡された探索データへのポインタで、ルートレベルならNULLです。 levelは現在のリーフタプルのレベルを、ルートレベルを0として数えたものです。 returnDataは、この問い合わせで再構築されたデータが必要な場合にtrueとなりますが、これはconfig関数がcanReturnDataを確認した場合にのみ、そうなります。 leafDatumは現在のリーフタプルに格納されているspgConfigOut.leafTypeのキーの値です。

The function must return <literal>true</literal> if the leaf tuple matches the query, or <literal>false</literal> if not. In the <literal>true</literal> case, if <structfield>returnData</structfield> is <literal>true</literal> then <structfield>leafValue</structfield> must be set to the value (of type <structname>spgConfigIn</structname>.<structfield>attType</structfield>) originally supplied to be indexed for this leaf tuple. Also, <structfield>recheck</structfield> may be set to <literal>true</literal> if the match is uncertain and so the operator(s) must be re-applied to the actual heap tuple to verify the match. If ordered search is performed, set <structfield>distances</structfield> to an array of distance values according to <structfield>orderbys</structfield> array. Leave it NULL otherwise. If at least one of returned distances is not exact, set <structfield>recheckDistances</structfield> to true. In this case, the executor will calculate the exact distances after fetching the tuple from the heap, and will reorder the tuples if needed. この関数は、リーフタプルが問い合わせにマッチすればtrueを返し、マッチしなければfalseを返します。 trueの場合、returnDatatrueであれば、leafValueを、このリーフタプルにインデックス付けするために元々提供された(spgConfigIn.attType型の)値に設定しなければなりません。 また、マッチするかどうかが不確実で、マッチするかの確認のために実際のヒープタプルに演算子を再適用しなければならないときは、rechecktrueにセットされることがあります。 順序付け検索を実行するなら、orderbys配列に従ってdistancesに距離の値の配列を設定します。 そうでなければNULLのままにします。 返される距離の少なくとも1つが正確でないのなら、recheckDistancesにtrueを設定します。 この場合、エグゼキュータはヒープからタプルを取得した後正確な距離を計算し、必要ならタプルを並べ替えます。

The optional user-defined methods are: オプションのユーザ定義メソッドは以下です。

Datum compress(Datum in)

Converts a data item into a format suitable for physical storage in a leaf tuple of the index. It accepts a value of type <structname>spgConfigIn</structname>.<structfield>attType</structfield> and returns a value of type <structname>spgConfigOut</structname>.<structfield>leafType</structfield>. The output value must not contain an out-of-line TOAST pointer. インデックスのリーフタプルでデータ項目を物理ストレージに適した形式に変換します。 spgConfigIn.attType型の値を受け付け、spgConfigOut.leafType型の値を返します。 出力値は行に収まらないTOASTを含んでいてはいけません。

Note: the <function>compress</function> method is only applied to values to be stored. The consistent methods receive query <structfield>scankeys</structfield> unchanged, without transformation using <function>compress</function>. 注意: compressメソッドは格納される値にのみ適用されます。 適合するメソッドはcompressを使って変換することなく、問い合わせのscankeysをそのまま受け取ります。

options

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

The <acronym>SQL</acronym> declaration of the function must look like this: 関数のSQL宣言は以下のようになります。

CREATE OR REPLACE FUNCTION my_options(internal)
RETURNS void
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;

The 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. 関数にはlocal_relopts構造体へのポインタが渡されますが、構造体を演算子クラスに固有のオプションの集合で満たすことが必要です。 オプションはマクロPG_HAS_OPCLASS_OPTIONS()PG_GET_OPCLASS_OPTIONS()を使って他のサポート関数からアクセスできます。

Since the representation of the key in <acronym>SP-GiST</acronym> is flexible, it may depend on user-specified parameters. SP-GiSTでのキーの表現には柔軟性がありますので、ユーザに固有のパラメータに依存するかもしれません。

All the SP-GiST support methods are normally called in a short-lived memory context; that is, <varname>CurrentMemoryContext</varname> will be reset after processing of each tuple. It is therefore not very important to worry about pfree'ing everything you palloc. (The <function>config</function> method is an exception: it should try to avoid leaking memory. But usually the <function>config</function> method need do nothing but assign constants into the passed parameter struct.) SP-GiSTのすべてのサポートメソッドは、通常は短期間有効なメモリコンテキスト内で呼び出されます。つまり、それぞれのタプルについて処理した後でCurrentMemoryContextはリセットされます。 したがって、pallocしたものすべてについてpfreeすることを気にかけることはあまり重要ではありません。 (configメソッドは例外で、メモリリークを避けるようにする必要があります。 しかし、通常はconfigメソッドは、パラメータとして渡された構造体に定数を代入する以外、何もする必要がありません。)

If the indexed column is of a collatable data type, the index collation will be passed to all the support methods, using the standard <function>PG_GET_COLLATION()</function> mechanism. インデックス付けされた列が照合可能なデータ型の場合、インデックスの照合は、標準的なPG_GET_COLLATION()の仕組みを使ってすべてのサポートメソッドに渡されます。