Home Explore Blog CI



postgresql

8th chunk of `doc/src/sgml/rangetypes.sgml`
c4138af898c9ad5dc638a5f088852b12586168077c37c2df0000000100000d08
 <literal>&lt;&lt;</literal>,
   <literal>&gt;&gt;</literal>,
   <literal>-|-</literal>,
   <literal>&amp;&lt;</literal>, and
   <literal>&amp;&gt;</literal>.
   See <xref linkend="range-operators-table"/> for more information.
  </para>

  <para>
   In addition, B-tree and hash indexes can be created for table columns of
   range types.  For these index types, basically the only useful range
   operation is equality.  There is a B-tree sort ordering defined for range
   values, with corresponding <literal>&lt;</literal> and <literal>&gt;</literal> operators,
   but the ordering is rather arbitrary and not usually useful in the real
   world.  Range types' B-tree and hash support is primarily meant to
   allow sorting and hashing internally in queries, rather than creation of
   actual indexes.
  </para>
 </sect2>

 <sect2 id="rangetypes-constraint">
  <title>Constraints on Ranges</title>

  <indexterm>
    <primary>range type</primary>
    <secondary>exclude</secondary>
  </indexterm>

  <para>
   While <literal>UNIQUE</literal> is a natural constraint for scalar
   values, it is usually unsuitable for range types. Instead, an
   exclusion constraint is often more appropriate
   (see <link linkend="sql-createtable-exclude">CREATE TABLE
   ... CONSTRAINT ... EXCLUDE</link>). Exclusion constraints allow the
   specification of constraints such as <quote>non-overlapping</quote> on a
   range type. For example:

<programlisting>
CREATE TABLE reservation (
    during tsrange,
    EXCLUDE USING GIST (during WITH &amp;&amp;)
);
</programlisting>

   That constraint will prevent any overlapping values from existing
   in the table at the same time:

<programlisting>
INSERT INTO reservation VALUES
    ('[2010-01-01 11:30, 2010-01-01 15:00)');
INSERT 0 1

INSERT INTO reservation VALUES
    ('[2010-01-01 14:45, 2010-01-01 15:45)');
ERROR:  conflicting key value violates exclusion constraint "reservation_during_excl"
DETAIL:  Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts
with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).
</programlisting>
  </para>

  <para>
   You can use the <link linkend="btree-gist"><literal>btree_gist</literal></link>
   extension to define exclusion constraints on plain scalar data types, which
   can then be combined with range exclusions for maximum flexibility.  For
   example, after <literal>btree_gist</literal> is installed, the following
   constraint will reject overlapping ranges only if the meeting room numbers
   are equal:

<programlisting>
CREATE EXTENSION btree_gist;
CREATE TABLE room_reservation (
    room text,
    during tsrange,
    EXCLUDE USING GIST (room WITH =, during WITH &amp;&amp;)
);

INSERT INTO room_reservation VALUES
    ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)');
INSERT 0 1

INSERT INTO room_reservation VALUES
    ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)');
ERROR:  conflicting key value violates exclusion constraint "room_reservation_room_during_excl"
DETAIL:  Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts
with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")).

INSERT INTO room_reservation VALUES
    ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)');
INSERT 0 1
</programlisting>
  </para>
 </sect2>
</sect1>

Title: Constraints on Ranges using Exclusion Constraints
Summary
This section focuses on constraints applicable to range types, particularly the use of exclusion constraints in PostgreSQL. It explains why `UNIQUE` constraints are often unsuitable for range types and introduces exclusion constraints as a better alternative for specifying conditions like non-overlapping ranges. Examples demonstrate how to create and use exclusion constraints to prevent overlapping values in a table, and how to combine them with scalar data types using the `btree_gist` extension for more flexible constraints, such as rejecting overlapping ranges only when meeting room numbers are equal.