family.
If this is not the case, planner errors might occur when the operator
is used. Also, it is a good idea (but not strictly required) for
a hash operator family that supports multiple data types to provide
equality operators for every combination of the data types; this
allows better optimization.
</para>
<note>
<para>
The function underlying a hash-joinable operator must be marked
immutable or stable. If it is volatile, the system will never
attempt to use the operator for a hash join.
</para>
</note>
<note>
<para>
If a hash-joinable operator has an underlying function that is marked
strict, the
function must also be complete: that is, it should return true or
false, never null, for any two nonnull inputs. If this rule is
not followed, hash-optimization of <literal>IN</literal> operations might
generate wrong results. (Specifically, <literal>IN</literal> might return
false where the correct answer according to the standard would be null;
or it might yield an error complaining that it wasn't prepared for a
null result.)
</para>
</note>
</sect2>
<sect2 id="xoper-merges">
<title><literal>MERGES</literal></title>
<para>
The <literal>MERGES</literal> clause, if present, tells the system that
it is permissible to use the merge-join method for a join based on this
operator. <literal>MERGES</literal> only makes sense for a binary operator that
returns <literal>boolean</literal>, and in practice the operator must represent
equality for some data type or pair of data types.
</para>
<para>
Merge join is based on the idea of sorting the left- and right-hand tables
into order and then scanning them in parallel. So, both data types must
be capable of being fully ordered, and the join operator must be one
that can only succeed for pairs of values that fall at the
<quote>same place</quote>
in the sort order. In practice this means that the join operator must
behave like equality. But it is possible to merge-join two
distinct data types so long as they are logically compatible. For
example, the <type>smallint</type>-versus-<type>integer</type>
equality operator is merge-joinable.
We only need sorting operators that will bring both data types into a
logically compatible sequence.
</para>
<para>
To be marked <literal>MERGES</literal>, the join operator must appear
as an equality member of a <literal>btree</literal> index operator family.
This is not enforced when you create
the operator, since of course the referencing operator family couldn't
exist yet. But the operator will not actually be used for merge joins
unless a matching operator family can be found. The
<literal>MERGES</literal> flag thus acts as a hint to the planner that
it's worth looking for a matching operator family.
</para>
<para>
A merge-joinable operator must have a commutator (itself if the two
operand data types are the same, or a related equality operator
if they are different) that appears in the same operator family.
If this is not the case, planner errors might occur when the operator
is used. Also, it is a good idea (but not strictly required) for
a <literal>btree</literal> operator family that supports multiple data types to provide
equality operators for every combination of the data types; this
allows better optimization.
</para>
<note>
<para>
The function underlying a merge-joinable operator must be marked
immutable or stable. If it is volatile, the system will never
attempt to use the operator for a merge join.
</para>
</note>
</sect2>
</sect1>