Home Explore Blog CI



postgresql

12th chunk of `doc/src/sgml/xindex.sgml`
2a252e549d22c0974e3cf24f24c71c602770b14fb64966900000000100000fa0
 <productname>PostgreSQL</productname>
   uses the concept of an <firstterm>operator
   family</firstterm><indexterm><primary>operator family</primary></indexterm>.
   An operator family contains one or more operator classes, and can also
   contain indexable operators and corresponding support functions that
   belong to the family as a whole but not to any single class within the
   family.  We say that such operators and functions are <quote>loose</quote>
   within the family, as opposed to being bound into a specific class.
   Typically each operator class contains single-data-type operators
   while cross-data-type operators are loose in the family.
  </para>

  <para>
   All the operators and functions in an operator family must have compatible
   semantics, where the compatibility requirements are set by the index
   method.  You might therefore wonder why bother to single out particular
   subsets of the family as operator classes; and indeed for many purposes
   the class divisions are irrelevant and the family is the only interesting
   grouping.  The reason for defining operator classes is that they specify
   how much of the family is needed to support any particular index.
   If there is an index using an operator class, then that operator class
   cannot be dropped without dropping the index &mdash; but other parts of
   the operator family, namely other operator classes and loose operators,
   could be dropped.  Thus, an operator class should be specified to contain
   the minimum set of operators and functions that are reasonably needed
   to work with an index on a specific data type, and then related but
   non-essential operators can be added as loose members of the operator
   family.
  </para>

  <para>
   As an example, <productname>PostgreSQL</productname> has a built-in
   B-tree operator family <literal>integer_ops</literal>, which includes operator
   classes <literal>int8_ops</literal>, <literal>int4_ops</literal>, and
   <literal>int2_ops</literal> for indexes on <type>bigint</type> (<type>int8</type>),
   <type>integer</type> (<type>int4</type>), and <type>smallint</type> (<type>int2</type>)
   columns respectively.  The family also contains cross-data-type comparison
   operators allowing any two of these types to be compared, so that an index
   on one of these types can be searched using a comparison value of another
   type.  The family could be duplicated by these definitions:

<programlisting><![CDATA[
CREATE OPERATOR FAMILY integer_ops USING btree;

CREATE OPERATOR CLASS int8_ops
DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS
  -- standard int8 comparisons
  OPERATOR 1 < ,
  OPERATOR 2 <= ,
  OPERATOR 3 = ,
  OPERATOR 4 >= ,
  OPERATOR 5 > ,
  FUNCTION 1 btint8cmp(int8, int8) ,
  FUNCTION 2 btint8sortsupport(internal) ,
  FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) ,
  FUNCTION 4 btequalimage(oid) ,
  FUNCTION 6 btint8skipsupport(internal) ;

CREATE OPERATOR CLASS int4_ops
DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS
  -- standard int4 comparisons
  OPERATOR 1 < ,
  OPERATOR 2 <= ,
  OPERATOR 3 = ,
  OPERATOR 4 >= ,
  OPERATOR 5 > ,
  FUNCTION 1 btint4cmp(int4, int4) ,
  FUNCTION 2 btint4sortsupport(internal) ,
  FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) ,
  FUNCTION 4 btequalimage(oid) ,
  FUNCTION 6 btint4skipsupport(internal) ;

CREATE OPERATOR CLASS int2_ops
DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS
  -- standard int2 comparisons
  OPERATOR 1 < ,
  OPERATOR 2 <= ,
  OPERATOR 3 = ,
  OPERATOR 4 >= ,
  OPERATOR 5 > ,
  FUNCTION 1 btint2cmp(int2, int2) ,
  FUNCTION 2 btint2sortsupport(internal) ,
  FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) ,
  FUNCTION 4 btequalimage(oid) ,
  FUNCTION 6 btint2skipsupport(internal) ;

ALTER OPERATOR FAMILY integer_ops USING btree ADD
  -- cross-type comparisons int8 vs int2
  OPERATOR 1 < (int8, int2) ,
  OPERATOR 2 <= (int8, int2) ,
  OPERATOR 3 = (int8, int2) ,
  OPERATOR 4 >= (int8,

Title: Operator Families and Classes in PostgreSQL
Summary
This section explains the concept of operator families in PostgreSQL, which contain one or more operator classes and can include 'loose' operators and functions that work across different data types. Operator families provide flexibility for cross-data-type operations while maintaining semantic compatibility. The text uses the built-in B-tree operator family 'integer_ops' as an example, showing how it includes operator classes for different integer types (int8, int4, int2) and cross-type comparison operators. The passage demonstrates how to create an operator family, define operator classes within it, and add cross-type operators. It emphasizes that operator classes should contain the minimum set of operators and functions needed for indexing a specific data type, while additional related operators can be added as loose members of the family.