<primary>ordering operator</primary>
</indexterm>
<para>
<productname>PostgreSQL</productname> uses operator classes to infer the
properties of operators in more ways than just whether they can be used
with indexes. Therefore, you might want to create operator classes
even if you have no intention of indexing any columns of your data type.
</para>
<para>
In particular, there are SQL features such as <literal>ORDER BY</literal> and
<literal>DISTINCT</literal> that require comparison and sorting of values.
To implement these features on a user-defined data type,
<productname>PostgreSQL</productname> looks for the default B-tree operator
class for the data type. The <quote>equals</quote> member of this operator
class defines the system's notion of equality of values for
<literal>GROUP BY</literal> and <literal>DISTINCT</literal>, and the sort ordering
imposed by the operator class defines the default <literal>ORDER BY</literal>
ordering.
</para>
<para>
If there is no default B-tree operator class for a data type, the system
will look for a default hash operator class. But since that kind of
operator class only provides equality, it is only able to support grouping
not sorting.
</para>
<para>
When there is no default operator class for a data type, you will get
errors like <quote>could not identify an ordering operator</quote> if you
try to use these SQL features with the data type.
</para>
<note>
<para>
In <productname>PostgreSQL</productname> versions before 7.4,
sorting and grouping operations would implicitly use operators named
<literal>=</literal>, <literal><</literal>, and <literal>></literal>. The new
behavior of relying on default operator classes avoids having to make
any assumption about the behavior of operators with particular names.
</para>
</note>
<para>
Sorting by a non-default B-tree operator class is possible by specifying
the class's less-than operator in a <literal>USING</literal> option,
for example
<programlisting>
SELECT * FROM mytable ORDER BY somecol USING ~<~;
</programlisting>
Alternatively, specifying the class's greater-than operator
in <literal>USING</literal> selects a descending-order sort.
</para>
<para>
Comparison of arrays of a user-defined type also relies on the semantics
defined by the type's default B-tree operator class. If there is no
default B-tree operator class, but there is a default hash operator class,
then array equality is supported, but not ordering comparisons.
</para>
<para>
Another SQL feature that requires even more data-type-specific knowledge
is the <literal>RANGE</literal> <replaceable>offset</replaceable>
<literal>PRECEDING</literal>/<literal>FOLLOWING</literal> framing option
for window functions (see <xref linkend="syntax-window-functions"/>).
For a query such as
<programlisting>
SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING)
FROM mytable;
</programlisting>
it is not sufficient to know how to order by <literal>x</literal>;
the database must also understand how to <quote>subtract 5</quote> or
<quote>add 10</quote> to the current row's value of <literal>x</literal>
to identify the bounds of the current window frame. Comparing the
resulting bounds to other rows' values of <literal>x</literal> is
possible using the comparison operators provided by the B-tree operator
class that defines the <literal>ORDER BY</literal> ordering — but
addition and subtraction operators are not part of the operator class, so
which ones should be used? Hard-wiring that choice would be undesirable,
because different sort orders (different B-tree operator classes) might
need different behavior. Therefore, a B-tree operator class can specify
an <firstterm>in_range</firstterm> support function that encapsulates the
addition and subtraction