colwidth="2*"/>
<colspec colname="col2" colwidth="3*"/>
<colspec colname="col3" colwidth="1*"/>
<thead>
<row>
<entry>Function</entry>
<entry>Description</entry>
<entry>Support Number</entry>
</row>
</thead>
<tbody>
<row>
<entry><function>opcInfo</function></entry>
<entry>
return internal information describing the indexed columns'
summary data
</entry>
<entry>1</entry>
</row>
<row>
<entry><function>add_value</function></entry>
<entry>add a new value to an existing summary index tuple</entry>
<entry>2</entry>
</row>
<row>
<entry><function>consistent</function></entry>
<entry>determine whether value matches query condition</entry>
<entry>3</entry>
</row>
<row>
<entry><function>union</function></entry>
<entry>
compute union of two summary tuples
</entry>
<entry>4</entry>
</row>
<row>
<entry><function>options</function></entry>
<entry>
define options that are specific to this operator class
(optional)
</entry>
<entry>5</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Unlike search operators, support functions return whichever data
type the particular index method expects; for example in the case
of the comparison function for B-trees, a signed integer. The number
and types of the arguments to each support function are likewise
dependent on the index method. For B-tree and hash the comparison and
hashing support functions take the same input data types as do the
operators included in the operator class, but this is not the case for
most GiST, SP-GiST, GIN, and BRIN support functions.
</para>
</sect2>
<sect2 id="xindex-example">
<title>An Example</title>
<para>
Now that we have seen the ideas, here is the promised example of
creating a new operator class.
(You can find a working copy of this example in
<filename>src/tutorial/complex.c</filename> and
<filename>src/tutorial/complex.sql</filename> in the source
distribution.)
The operator class encapsulates
operators that sort complex numbers in absolute value order, so we
choose the name <literal>complex_abs_ops</literal>. First, we need
a set of operators. The procedure for defining operators was
discussed in <xref linkend="xoper"/>. For an operator class on
B-trees, the operators we require are:
<itemizedlist spacing="compact">
<listitem><simpara>absolute-value less-than (strategy 1)</simpara></listitem>
<listitem><simpara>absolute-value less-than-or-equal (strategy 2)</simpara></listitem>
<listitem><simpara>absolute-value equal (strategy 3)</simpara></listitem>
<listitem><simpara>absolute-value greater-than-or-equal (strategy 4)</simpara></listitem>
<listitem><simpara>absolute-value greater-than (strategy 5)</simpara></listitem>
</itemizedlist>
</para>
<para>
The least error-prone way to define a related set of comparison operators
is to write the B-tree comparison support function first, and then write the
other functions as one-line wrappers around the support function. This
reduces the odds of getting inconsistent results for corner cases.
Following this approach, we first write:
<programlisting><![CDATA[
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
static int
complex_abs_cmp_internal(Complex *a, Complex *b)
{
double amag = Mag(a),
bmag = Mag(b);
if (amag < bmag)
return -1;
if (amag > bmag)
return 1;
return 0;
}
]]>
</programlisting>
Now the less-than function looks like:
<programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_abs_lt);
Datum
complex_abs_lt(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0);
Complex *b = (Complex *) PG_GETARG_POINTER(1);
PG_RETURN_BOOL(complex_abs_cmp_internal(a,