canonicalization function takes an input range value, and must return
an equivalent range value that may have different bounds and formatting.
The canonical output for two ranges that represent the same set of values,
for example the integer ranges <literal>[1, 7]</literal> and <literal>[1,
8)</literal>, must be identical. It doesn't matter which representation
you choose to be the canonical one, so long as two equivalent values with
different formattings are always mapped to the same value with the same
formatting. In addition to adjusting the inclusive/exclusive bounds
format, a canonicalization function might round off boundary values, in
case the desired step size is larger than what the subtype is capable of
storing. For instance, a range type over <type>timestamp</type> could be
defined to have a step size of an hour, in which case the canonicalization
function would need to round off bounds that weren't a multiple of an hour,
or perhaps throw an error instead.
</para>
<para>
In addition, any range type that is meant to be used with GiST or SP-GiST
indexes should define a subtype difference, or <literal>subtype_diff</literal>,
function. (The index will still work without <literal>subtype_diff</literal>,
but it is likely to be considerably less efficient than if a difference
function is provided.) The subtype difference function takes two input
values of the subtype, and returns their difference
(i.e., <replaceable>X</replaceable> minus <replaceable>Y</replaceable>) represented as
a <type>float8</type> value. In our example above, the
function <function>float8mi</function> that underlies the regular <type>float8</type>
minus operator can be used; but for any other subtype, some type
conversion would be necessary. Some creative thought about how to
represent differences as numbers might be needed, too. To the greatest
extent possible, the <literal>subtype_diff</literal> function should agree with
the sort ordering implied by the selected operator class and collation;
that is, its result should be positive whenever its first argument is
greater than its second according to the sort ordering.
</para>
<para>
A less-oversimplified example of a <literal>subtype_diff</literal> function is:
</para>
<programlisting>
CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;
CREATE TYPE timerange AS RANGE (
subtype = time,
subtype_diff = time_subtype_diff
);
SELECT '[11:10, 23:00]'::timerange;
</programlisting>
<para>
See <xref linkend="sql-createtype"/> for more information about creating
range types.
</para>
</sect2>
<sect2 id="rangetypes-indexing">
<title>Indexing</title>
<indexterm>
<primary>range type</primary>
<secondary>indexes on</secondary>
</indexterm>
<para>
GiST and SP-GiST indexes can be created for table columns of range types.
GiST indexes can be also created for table columns of multirange types.
For instance, to create a GiST index:
<programlisting>
CREATE INDEX reservation_idx ON reservation USING GIST (during);
</programlisting>
A GiST or SP-GiST index on ranges can accelerate queries involving these
range operators:
<literal>=</literal>,
<literal>&&</literal>,
<literal><@</literal>,
<literal>@></literal>,
<literal><<</literal>,
<literal>>></literal>,
<literal>-|-</literal>,
<literal>&<</literal>, and
<literal>&></literal>.
A GiST index on multiranges can accelerate queries involving