CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES
(1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
-- Containment
SELECT int4range(10, 20) @> 3;
-- Overlaps
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);
-- Extract the upper bound
SELECT upper(int8range(15, 25));
-- Compute the intersection
SELECT int4range(10, 20) * int4range(15, 25);
-- Is the range empty?
SELECT isempty(numrange(1, 5));
</programlisting>
See <xref linkend="range-operators-table"/>
and <xref linkend="range-functions-table"/> for complete lists of
operators and functions on range types.
</para>
</sect2>
<sect2 id="rangetypes-inclusivity">
<title>Inclusive and Exclusive Bounds</title>
<para>
Every non-empty range has two bounds, the lower bound and the upper
bound. All points between these values are included in the range. An
inclusive bound means that the boundary point itself is included in
the range as well, while an exclusive bound means that the boundary
point is not included in the range.
</para>
<para>
In the text form of a range, an inclusive lower bound is represented by
<quote><literal>[</literal></quote> while an exclusive lower bound is
represented by <quote><literal>(</literal></quote>. Likewise, an inclusive upper bound is represented by
<quote><literal>]</literal></quote>, while an exclusive upper bound is
represented by <quote><literal>)</literal></quote>.
(See <xref linkend="rangetypes-io"/> for more details.)
</para>
<para>
The functions <literal>lower_inc</literal>
and <literal>upper_inc</literal> test the inclusivity of the lower
and upper bounds of a range value, respectively.
</para>
</sect2>
<sect2 id="rangetypes-infinite">
<title>Infinite (Unbounded) Ranges</title>
<para>
The lower bound of a range can be omitted, meaning that all
values less than the upper bound are included in the range, e.g.,
<literal>(,3]</literal>. Likewise, if the upper bound of the range
is omitted, then all values greater than the lower bound are included
in the range. If both lower and upper bounds are omitted, all values
of the element type are considered to be in the range. Specifying a
missing bound as inclusive is automatically converted to exclusive,
e.g., <literal>[,]</literal> is converted to <literal>(,)</literal>.
You can think of these missing values as +/-infinity, but they are
special range type values and are considered to be beyond any range
element type's +/-infinity values.
</para>
<para>
Element types that have the notion of <quote>infinity</quote> can
use them as explicit bound values. For example, with timestamp
ranges, <literal>[today,infinity)</literal> excludes the special
<type>timestamp</type> value <literal>infinity</literal>,
while <literal>[today,infinity]</literal> include it, as does
<literal>[today,)</literal> and <literal>[today,]</literal>.
</para>
<para>
The functions <literal>lower_inf</literal>
and <literal>upper_inf</literal> test for infinite lower
and upper bounds of a range, respectively.
</para>
</sect2>
<sect2 id="rangetypes-io">
<title>Range Input/Output</title>
<para>
The input for a range value must follow one of the following patterns:
<synopsis>
(<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>)
(<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>]
[<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>)
[<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>]
empty
</synopsis>
The parentheses or brackets indicate whether the lower and upper bounds
are exclusive or inclusive, as described previously.
Notice that the final pattern is <literal>empty</literal>, which
represents an empty range (a range that contains no points).
</para>
<para>
The <replaceable>lower-bound</replaceable>