operator must specify that it is valid, by marking the
operator with commutator information.
</para>
</sect2>
<sect2 id="xoper-negator">
<title><literal>NEGATOR</literal></title>
<para>
The <literal>NEGATOR</literal> clause, if provided, names an operator that is the
negator of the operator being defined. We say that operator A
is the negator of operator B if both return Boolean results and
(x A y) equals NOT (x B y) for all possible inputs x, y.
Notice that B is also the negator of A.
For example, <literal><</literal> and <literal>>=</literal> are a negator pair for most data types.
An operator can never validly be its own negator.
</para>
<para>
Unlike commutators, a pair of unary operators could validly be marked
as each other's negators; that would mean (A x) equals NOT (B x)
for all x.
</para>
<para>
An operator's negator must have the same left and/or right operand types
as the operator to be defined, so just as with <literal>COMMUTATOR</literal>, only the operator
name need be given in the <literal>NEGATOR</literal> clause.
</para>
<para>
Providing a negator is very helpful to the query optimizer since
it allows expressions like <literal>NOT (x = y)</literal> to be simplified into
<literal>x <> y</literal>. This comes up more often than you might think, because
<literal>NOT</literal> operations can be inserted as a consequence of other rearrangements.
</para>
</sect2>
<sect2 id="xoper-restrict">
<title><literal>RESTRICT</literal></title>
<para>
The <literal>RESTRICT</literal> clause, if provided, names a restriction selectivity
estimation function for the operator. (Note that this is a function
name, not an operator name.) <literal>RESTRICT</literal> clauses only make sense for
binary operators that return <type>boolean</type>. The idea behind a restriction
selectivity estimator is to guess what fraction of the rows in a
table will satisfy a <literal>WHERE</literal>-clause condition of the form:
<programlisting>
column OP constant
</programlisting>
for the current operator and a particular constant value.
This assists the optimizer by
giving it some idea of how many rows will be eliminated by <literal>WHERE</literal>
clauses that have this form. (What happens if the constant is on
the left, you might be wondering? Well, that's one of the things that
<literal>COMMUTATOR</literal> is for...)
</para>
<para>
Writing new restriction selectivity estimation functions is far beyond
the scope of this chapter, but fortunately you can usually just use
one of the system's standard estimators for many of your own operators.
These are the standard restriction estimators:
<simplelist>
<member><function>eqsel</function> for <literal>=</literal></member>
<member><function>neqsel</function> for <literal><></literal></member>
<member><function>scalarltsel</function> for <literal><</literal></member>
<member><function>scalarlesel</function> for <literal><=</literal></member>
<member><function>scalargtsel</function> for <literal>></literal></member>
<member><function>scalargesel</function> for <literal>>=</literal></member>
</simplelist>
</para>
<para>
You can frequently get away with using either <function>eqsel</function> or <function>neqsel</function> for
operators that have very high or very low selectivity, even if they
aren't really equality or inequality. For example, the
approximate-equality geometric operators use <function>eqsel</function> on the assumption that
they'll usually only match a small fraction of the entries in a table.
</para>
<para>
You can use <function>scalarltsel</function>, <function>scalarlesel</function>,
<function>scalargtsel</function> and <function>scalargesel</function> for comparisons on