<filename>src/include/utils/sortsupport.h</filename>.
</para>
<para>
The matching code in the C module could then follow this skeleton:
<programlisting>
PG_FUNCTION_INFO_V1(my_sortsupport);
static int
my_fastcmp(Datum x, Datum y, SortSupport ssup)
{
/* establish order between x and y by computing some sorting value z */
int z1 = ComputeSpatialCode(x);
int z2 = ComputeSpatialCode(y);
return z1 == z2 ? 0 : z1 > z2 ? 1 : -1;
}
Datum
my_sortsupport(PG_FUNCTION_ARGS)
{
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
ssup->comparator = my_fastcmp;
PG_RETURN_VOID();
}
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>translate_cmptype</function></term>
<listitem>
<para>
Given a <literal>CompareType</literal> value from
<filename>src/include/nodes/primnodes.h</filename>, returns a strategy
number used by this operator class for matching functionality. The
function should return <literal>InvalidStrategy</literal> if the
operator class has no matching strategy.
</para>
<para>
This is used for temporal index constraints (i.e., <literal>PRIMARY
KEY</literal> and <literal>UNIQUE</literal>). If the operator class
provides this function and it returns results for
<literal>COMPARE_EQ</literal>, it can be used in the
non-<literal>WITHOUT OVERLAPS</literal> part(s) of an index constraint.
</para>
<para>
This support function corresponds to the index access method callback
function <structfield>amtranslatecmptype</structfield> (see <xref
linkend="index-functions"/>). The
<structfield>amtranslatecmptype</structfield> callback function for
GiST indexes merely calls down to the
<function>translate_cmptype</function> support function of the
respective operator family, since the GiST index access method has no
fixed strategy numbers itself.
</para>
<para>
The <acronym>SQL</acronym> declaration of the function must look like
this:
<programlisting>
CREATE OR REPLACE FUNCTION my_translate_cmptype(integer)
RETURNS smallint
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
</programlisting>
And the operator family registration must look like this:
<programlisting>
ALTER OPERATOR FAMILY my_opfamily USING gist ADD
FUNCTION 12 ("any", "any") my_translate_cmptype(int);
</programlisting>
</para>
<para>
The matching code in the C module could then follow this skeleton:
<programlisting>
PG_FUNCTION_INFO_V1(my_translate_cmptype);
Datum
my_translate_cmptype(PG_FUNCTION_ARGS)
{
CompareType cmptype = PG_GETARG_INT32(0);
StrategyNumber ret = InvalidStrategy;
switch (cmptype)
{
case COMPARE_EQ:
ret = BTEqualStrategyNumber;
}
PG_RETURN_UINT16(ret);
}
</programlisting>
</para>
<para>
One translation function is provided by
<productname>PostgreSQL</productname>:
<literal>gist_translate_cmptype_common</literal> is for operator classes that
use the <literal>RT*StrategyNumber</literal> constants.
The <literal>btree_gist</literal>
extension defines a second translation function,
<literal>gist_translate_cmptype_btree</literal>, for operator classes that use
the <literal>BT*StrategyNumber</literal> constants.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
All the GiST support methods are normally called in short-lived memory
contexts; that is, <varname>CurrentMemoryContext</varname> will get reset after
each tuple is processed. It is therefore not very important to worry about
pfree'ing everything you palloc. However, in some cases it's useful for a
support method to cache data across repeated calls. To do that, allocate
the longer-lived data in <literal>fcinfo->flinfo->fn_mcxt</literal>,