function determines the index entry's
<quote>distance</quote> from the query value. This function must be
supplied if the operator class contains any ordering operators.
A query using the ordering operator will be implemented by returning
index entries with the smallest <quote>distance</quote> values first,
so the results must be consistent with the operator's semantics.
For a leaf index entry the result just represents the distance to
the index entry; for an internal tree node, the result must be the
smallest distance that any child entry could have.
</para>
<para>
The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting>
CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal)
RETURNS float8
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_distance);
Datum
my_distance(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);
double retval;
/*
* determine return value as a function of strategy, key and query.
*/
PG_RETURN_FLOAT8(retval);
}
</programlisting>
The arguments to the <function>distance</function> function are identical to
the arguments of the <function>consistent</function> function.
</para>
<para>
Some approximation is allowed when determining the distance, so long
as the result is never greater than the entry's actual distance. Thus,
for example, distance to a bounding box is usually sufficient in
geometric applications. For an internal tree node, the distance
returned must not be greater than the distance to any of the child
nodes. If the returned distance is not exact, the function must set
<literal>*recheck</literal> to true. (This is not necessary for internal tree
nodes; for them, the calculation is always assumed to be inexact.) In
this case the executor will calculate the accurate distance after
fetching the tuple from the heap, and reorder the tuples if necessary.
</para>
<para>
If the distance function returns <literal>*recheck = true</literal> for any
leaf node, the original ordering operator's return type must
be <type>float8</type> or <type>float4</type>, and the distance function's
result values must be comparable to those of the original ordering
operator, since the executor will sort using both distance function
results and recalculated ordering-operator results. Otherwise, the
distance function's result values can be any finite <type>float8</type>
values, so long as the relative order of the result values matches the
order returned by the ordering operator. (Infinity and minus infinity
are used internally to handle cases such as nulls, so it is not
recommended that <function>distance</function> functions return these values.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>fetch</function></term>
<listitem>
<para>
Converts the compressed index representation of a data item into the
original data type, for index-only scans. The returned data must be an
exact, non-lossy copy of the originally indexed value.
</para>
<para>
The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting>
CREATE OR REPLACE FUNCTION my_fetch(internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
</programlisting>