<replaceable>A</replaceable>, <replaceable>B</replaceable>,
<replaceable>C</replaceable> are taken from any data types in the family.
The transitive laws are the trickiest to ensure, as in cross-type
situations they represent statements that the behaviors of two or three
different operators are consistent.
As an example, it would not work to put <type>float8</type>
and <type>numeric</type> into the same operator family, at least not with
the current semantics that <type>numeric</type> values are converted
to <type>float8</type> for comparison to a <type>float8</type>. Because
of the limited accuracy of <type>float8</type>, this means there are
distinct <type>numeric</type> values that will compare equal to the
same <type>float8</type> value, and thus the transitive law would fail.
</para>
<para>
Another requirement for a multiple-data-type family is that any implicit
or binary-coercion casts that are defined between data types included in
the operator family must not change the associated sort ordering.
</para>
<para>
It should be fairly clear why a btree index requires these laws to hold
within a single data type: without them there is no ordering to arrange
the keys with. Also, index searches using a comparison key of a
different data type require comparisons to behave sanely across two
data types. The extensions to three or more data types within a family
are not strictly required by the btree index mechanism itself, but the
planner relies on them for optimization purposes.
</para>
</sect2>
<sect2 id="btree-support-funcs">
<title>B-Tree Support Functions</title>
<para>
As shown in <xref linkend="xindex-btree-support-table"/>, btree defines
one required and five optional support functions. The six
user-defined methods are:
</para>
<variablelist>
<varlistentry>
<term><function>order</function></term>
<listitem>
<para>
For each combination of data types that a btree operator family
provides comparison operators for, it must provide a comparison
support function, registered in
<structname>pg_amproc</structname> with support function number 1
and
<structfield>amproclefttype</structfield>/<structfield>amprocrighttype</structfield>
equal to the left and right data types for the comparison (i.e.,
the same data types that the matching operators are registered
with in <structname>pg_amop</structname>). The comparison
function must take two non-null values
<replaceable>A</replaceable> and <replaceable>B</replaceable> and
return an <type>int32</type> value that is
<literal><</literal> <literal>0</literal>,
<literal>0</literal>, or <literal>></literal>
<literal>0</literal> when <replaceable>A</replaceable>
<literal><</literal> <replaceable>B</replaceable>,
<replaceable>A</replaceable> <literal>=</literal>
<replaceable>B</replaceable>, or <replaceable>A</replaceable>
<literal>></literal> <replaceable>B</replaceable>,
respectively. A null result is disallowed: all values of the
data type must be comparable. See
<filename>src/backend/access/nbtree/nbtcompare.c</filename> for
examples.
</para>
<para>
If the compared values are of a collatable data type, the
appropriate collation OID will be passed to the comparison
support function, using the standard
<function>PG_GET_COLLATION()</function> mechanism.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>sortsupport</function></term>
<listitem>
<para>
Optionally, a btree operator family may provide <firstterm>sort
support</firstterm> function(s), registered under support
function number 2. These functions allow implementing
comparisons for sorting purposes in a more efficient way than
naively calling the comparison support function. The APIs
involved in this are defined in
<filename>src/include/utils/sortsupport.h</filename>.