searches). The optional ninth method <function>fetch</function> is needed if the
operator class wishes to support index-only scans, except when the
<function>compress</function> method is omitted. The optional tenth method
<function>options</function> is needed if the operator class has
user-specified parameters.
The optional eleventh method <function>sortsupport</function> is used to
speed up building a <acronym>GiST</acronym> index.
The optional twelfth method <function>stratnum</function> is used to
translate compare types (from
<filename>src/include/nodes/primnodes.h</filename>) into strategy numbers
used by the operator class. This lets the core code look up operators for
temporal constraint indexes.
</para>
<variablelist>
<varlistentry>
<term><function>consistent</function></term>
<listitem>
<para>
Given an index entry <literal>p</literal> and a query value <literal>q</literal>,
this function determines whether the index entry is
<quote>consistent</quote> with the query; that is, could the predicate
<quote><replaceable>indexed_column</replaceable>
<replaceable>indexable_operator</replaceable> <literal>q</literal></quote> be true for
any row represented by the index entry? For a leaf index entry this is
equivalent to testing the indexable condition, while for an internal
tree node this determines whether it is necessary to scan the subtree
of the index represented by the tree node. When the result is
<literal>true</literal>, a <literal>recheck</literal> flag must also be returned.
This indicates whether the predicate is certainly true or only possibly
true. If <literal>recheck</literal> = <literal>false</literal> then the index has
tested the predicate condition exactly, whereas if <literal>recheck</literal>
= <literal>true</literal> the row is only a candidate match. In that case the
system will automatically evaluate the
<replaceable>indexable_operator</replaceable> against the actual row value to see
if it is really a match. This convention allows
<acronym>GiST</acronym> to support both lossless and lossy index
structures.
</para>
<para>
The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting>
CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
</programlisting>
And the matching code in the C module could then follow this skeleton:
<programlisting>
PG_FUNCTION_INFO_V1(my_consistent);
Datum
my_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
data_type *query = PG_GETARG_DATA_TYPE_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
data_type *key = DatumGetDataType(entry->key);
bool retval;
/*
* determine return value as a function of strategy, key and query.
*
* Use GIST_LEAF(entry) to know where you're called in the index tree,
* which comes handy when supporting the = operator for example (you could
* check for non empty union() in non-leaf nodes and equality in leaf
* nodes).
*/
*recheck = true; /* or false if check is exact */
PG_RETURN_BOOL(retval);
}
</programlisting>
Here, <varname>key</varname> is an element in the index and <varname>query</varname>
the value being looked up in the index. The <literal>StrategyNumber</literal>
parameter indicates which operator of your operator class is being
applied — it matches one of the operator numbers in the
<command>CREATE OPERATOR CLASS</command> command.
</para>
<para>
Depending on which operators you have included in the class,