head	1.67;
access;
symbols
	REL9_0_0:1.66.4.1
	REL9_1_ALPHA1:1.67
	REL9_0_RC1:1.66.4.1
	REL9_0_BETA4:1.66
	REL9_0_STABLE:1.66.0.4
	REL9_0_BETA3:1.66
	REL9_0_BETA2:1.66
	REL7_4_29:1.34
	REL8_0_25:1.37.4.1
	REL8_1_21:1.41
	REL8_2_17:1.53
	REL8_3_11:1.61
	REL8_4_4:1.64
	REL9_0_BETA1:1.66
	REL9_0_ALPHA5_BRANCH:1.66.0.2
	REL9_0_ALPHA5:1.66
	REL7_4_28:1.34
	REL8_0_24:1.37.4.1
	REL8_1_20:1.41
	REL8_2_16:1.53
	REL8_3_10:1.61
	REL8_4_3:1.64
	REL9_0_ALPHA4:1.64
	REL9_0_ALPHA4_BRANCH:1.64.0.10
	REL8_5_ALPHA3:1.64
	REL8_5_ALPHA3_BRANCH:1.64.0.8
	REL7_4_27:1.34
	REL8_0_23:1.37.4.1
	REL8_1_19:1.41
	REL8_2_15:1.53
	REL8_3_9:1.61
	REL8_4_2:1.64
	REL8_5_ALPHA2:1.64
	REL8_5_ALPHA2_BRANCH:1.64.0.6
	REL7_4_26:1.34
	REL8_0_22:1.37.4.1
	REL8_1_18:1.41
	REL8_2_14:1.53
	REL8_3_8:1.61
	REL8_4_1:1.64
	REL8_5_ALPHA1:1.64
	REL8_5_ALPHA1_BRANCH:1.64.0.4
	REL8_4_STABLE:1.64.0.2
	REL8_4_0:1.64
	REL8_4_RC2:1.64
	REL8_4_RC1:1.64
	REL8_4_BETA2:1.64
	REL8_4_BETA1:1.64
	REL7_4_25:1.34
	REL8_0_21:1.37.4.1
	REL8_1_17:1.41
	REL8_2_13:1.53
	REL8_3_7:1.61
	REL7_4_24:1.34
	REL8_0_20:1.37.4.1
	REL8_1_16:1.41
	REL8_2_12:1.53
	REL8_3_6:1.61
	REL7_4_23:1.34
	REL8_0_19:1.37.4.1
	REL8_1_15:1.41
	REL8_2_11:1.53
	REL8_3_5:1.61
	REL7_4_22:1.34
	REL8_0_18:1.37.4.1
	REL8_1_14:1.41
	REL8_2_10:1.53
	REL8_3_4:1.61
	REL7_4_21:1.34
	REL8_0_17:1.37.4.1
	REL8_1_13:1.41
	REL8_2_9:1.53
	REL8_3_3:1.61
	REL7_4_20:1.34
	REL8_0_16:1.37.4.1
	REL8_1_12:1.41
	REL8_2_8:1.53
	REL8_3_2:1.61
	REL8_2_7:1.53
	REL8_3_1:1.61
	REL8_3_STABLE:1.61.0.2
	REL8_3_0:1.61
	REL8_3_RC2:1.61
	REL7_3_21:1.29
	REL7_4_19:1.34
	REL8_0_15:1.37.4.1
	REL8_1_11:1.41
	REL8_2_6:1.53
	REL8_3_RC1:1.61
	REL8_3_BETA4:1.61
	REL8_3_BETA3:1.60
	REL8_3_BETA2:1.60
	REL8_3_BETA1:1.60
	REL7_3_20:1.29
	REL7_4_18:1.34
	REL8_0_14:1.37.4.1
	REL8_1_10:1.41
	REL8_2_5:1.53
	REL7_3_19:1.29
	REL7_4_17:1.34
	REL8_0_13:1.37.4.1
	REL8_1_9:1.41
	REL8_2_4:1.53
	REL8_0_12:1.37.4.1
	REL8_1_8:1.41
	REL8_2_3:1.53
	REL7_3_18:1.29
	REL7_4_16:1.34
	REL8_0_11:1.37.4.1
	REL8_1_7:1.41
	REL8_2_2:1.53
	REL8_0_10:1.37.4.1
	REL8_1_6:1.41
	REL8_2_1:1.53
	REL7_4_15:1.34
	REL7_3_17:1.29
	REL8_2_STABLE:1.53.0.2
	REL8_2_0:1.53
	REL8_2_RC1:1.52
	REL8_2_BETA3:1.52
	REL8_2_BETA2:1.52
	REL8_1_5:1.41
	REL8_0_9:1.37.4.1
	REL7_4_14:1.34
	REL7_3_16:1.29
	REL8_2_BETA1:1.51
	REL7_3_15:1.29
	REL7_4_13:1.34
	REL8_0_8:1.37.4.1
	REL8_1_4:1.41
	REL7_3_14:1.29
	REL7_4_12:1.34
	REL8_0_7:1.37.4.1
	REL8_1_3:1.41
	REL7_3_13:1.29
	REL7_4_11:1.34
	REL8_0_6:1.37.4.1
	REL8_1_2:1.41
	REL7_3_12:1.29
	REL7_4_10:1.34
	REL8_0_5:1.37.4.1
	REL8_1_1:1.41
	REL8_1_STABLE:1.41.0.2
	REL8_1_0:1.41
	REL8_1_0RC1:1.41
	REL8_1_0BETA4:1.41
	REL8_1_0BETA3:1.41
	REL7_3_11:1.29
	REL7_4_9:1.34
	REL8_0_4:1.37.4.1
	REL8_1_0BETA2:1.41
	REL8_1_0BETA1:1.41
	REL7_2_8:1.22
	REL7_3_10:1.29
	REL7_4_8:1.34
	REL8_0_3:1.37.4.1
	REL8_0_2:1.37.4.1
	REL7_2_7:1.22
	REL7_3_9:1.29
	REL7_4_7:1.34
	REL8_0_1:1.37.4.1
	REL8_0_STABLE:1.37.0.4
	REL8_0_0:1.37.0.2
	REL8_0_0RC5:1.37
	REL8_0_0RC4:1.37
	REL8_0_0RC3:1.37
	REL8_0_0RC2:1.37
	REL8_0_0RC1:1.37
	REL8_0_0BETA5:1.37
	REL8_0_0BETA4:1.36
	REL7_4_6:1.34
	REL7_3_8:1.29
	REL7_2_6:1.22
	REL8_0_0BETA3:1.36
	REL8_0_0BETA2:1.36
	REL7_2_5:1.22
	REL7_4_5:1.34
	REL7_3_7:1.29
	REL7_4_4:1.34
	REL8_0_0BETA1:1.36
	REL7_4_3:1.34
	REL7_4_2:1.34
	REL7_3_6:1.29
	REL7_4_1:1.34
	REL7_3_5:1.29
	REL7_4:1.34
	REL7_4_RC2:1.34
	REL7_4_STABLE:1.34.0.2
	REL7_4_RC1:1.34
	REL7_4_BETA5:1.33
	REL7_4_BETA4:1.32
	REL7_4_BETA3:1.32
	REL7_4_BETA2:1.31
	WIN32_DEV:1.30.0.2
	REL7_4_BETA1:1.30
	REL7_3_4:1.29
	REL7_3_2:1.29
	REL7_2_4:1.22
	REL7_3_STABLE:1.29.0.2
	REL7_2_3:1.22
	REL7_2_STABLE:1.22.0.2
	REL7_2:1.22
	REL7_2_RC2:1.22
	REL7_2_RC1:1.22
	REL7_2_BETA5:1.22
	REL7_2_BETA4:1.21
	REL7_2_BETA3:1.20
	REL7_2_BETA2:1.20
	REL7_2_BETA1:1.19
	REL7_1_2:1.14
	REL7_1_STABLE:1.14.0.2
	REL7_1_BETA:1.11
	REL7_1_BETA3:1.12
	REL7_1_BETA2:1.12
	REL7_1:1.14
	REL7_0_PATCHES:1.11.0.2
	REL7_0:1.11
	REL6_5_PATCHES:1.4.0.2
	REL6_5:1.4
	REL6_4:1.2.0.2
	release-6-3:1.1;
locks; strict;
comment	@# @;


1.67
date	2010.08.17.04.37.21;	author petere;	state Exp;
branches;
next	1.66;

1.66
date	2010.02.24.15.54.31;	author momjian;	state Exp;
branches
	1.66.4.1;
next	1.65;

1.65
date	2010.02.24.03.33.49;	author momjian;	state Exp;
branches;
next	1.64;

1.64
date	2008.12.07.23.46.39;	author alvherre;	state Exp;
branches;
next	1.63;

1.63
date	2008.05.16.16.31.01;	author tgl;	state Exp;
branches;
next	1.62;

1.62
date	2008.04.14.17.05.32;	author tgl;	state Exp;
branches;
next	1.61;

1.61
date	2007.12.02.04.36.40;	author tgl;	state Exp;
branches;
next	1.60;

1.60
date	2007.04.25.19.48.27;	author neilc;	state Exp;
branches;
next	1.59;

1.59
date	2007.02.06.04.38.31;	author tgl;	state Exp;
branches;
next	1.58;

1.58
date	2007.02.01.00.28.18;	author momjian;	state Exp;
branches;
next	1.57;

1.57
date	2007.01.31.20.56.20;	author momjian;	state Exp;
branches;
next	1.56;

1.56
date	2007.01.23.20.45.28;	author tgl;	state Exp;
branches;
next	1.55;

1.55
date	2007.01.20.23.13.01;	author tgl;	state Exp;
branches;
next	1.54;

1.54
date	2007.01.09.02.14.10;	author tgl;	state Exp;
branches;
next	1.53;

1.53
date	2006.12.01.23.46.46;	author tgl;	state Exp;
branches;
next	1.52;

1.52
date	2006.10.23.18.10.32;	author petere;	state Exp;
branches;
next	1.51;

1.51
date	2006.09.21.15.09.38;	author teodor;	state Exp;
branches;
next	1.50;

1.50
date	2006.09.21.15.03.53;	author teodor;	state Exp;
branches;
next	1.49;

1.49
date	2006.09.18.12.11.36;	author teodor;	state Exp;
branches;
next	1.48;

1.48
date	2006.09.16.00.30.16;	author momjian;	state Exp;
branches;
next	1.47;

1.47
date	2006.09.14.13.40.28;	author teodor;	state Exp;
branches;
next	1.46;

1.46
date	2006.09.14.11.16.27;	author teodor;	state Exp;
branches;
next	1.45;

1.45
date	2006.09.05.03.09.56;	author momjian;	state Exp;
branches;
next	1.44;

1.44
date	2006.09.04.20.10.53;	author momjian;	state Exp;
branches;
next	1.43;

1.43
date	2006.03.10.19.10.49;	author momjian;	state Exp;
branches;
next	1.42;

1.42
date	2005.11.07.17.36.44;	author tgl;	state Exp;
branches;
next	1.41;

1.41
date	2005.07.19.01.27.59;	author neilc;	state Exp;
branches;
next	1.40;

1.40
date	2005.06.24.20.53.30;	author tgl;	state Exp;
branches;
next	1.39;

1.39
date	2005.02.13.03.04.15;	author tgl;	state Exp;
branches;
next	1.38;

1.38
date	2005.01.23.00.30.18;	author momjian;	state Exp;
branches;
next	1.37;

1.37
date	2004.11.15.06.32.14;	author neilc;	state Exp;
branches
	1.37.4.1;
next	1.36;

1.36
date	2003.11.29.19.51.38;	author pgsql;	state Exp;
branches;
next	1.35;

1.35
date	2003.11.12.21.15.45;	author tgl;	state Exp;
branches;
next	1.34;

1.34
date	2003.11.01.01.56.29;	author petere;	state Exp;
branches;
next	1.33;

1.33
date	2003.10.21.23.28.42;	author tgl;	state Exp;
branches;
next	1.32;

1.32
date	2003.08.31.17.32.21;	author petere;	state Exp;
branches;
next	1.31;

1.31
date	2003.08.17.22.09.00;	author tgl;	state Exp;
branches;
next	1.30;

1.30
date	2003.04.13.09.57.35;	author petere;	state Exp;
branches
	1.30.2.1;
next	1.29;

1.29
date	2002.09.21.18.32.54;	author petere;	state Exp;
branches;
next	1.28;

1.28
date	2002.07.30.17.34.37;	author tgl;	state Exp;
branches;
next	1.27;

1.27
date	2002.07.30.05.24.56;	author tgl;	state Exp;
branches;
next	1.26;

1.26
date	2002.06.21.03.25.53;	author momjian;	state Exp;
branches;
next	1.25;

1.25
date	2002.05.29.17.36.40;	author tgl;	state Exp;
branches;
next	1.24;

1.24
date	2002.04.17.20.57.56;	author tgl;	state Exp;
branches;
next	1.23;

1.23
date	2002.03.27.19.19.23;	author petere;	state Exp;
branches;
next	1.22;

1.22
date	2002.01.07.02.29.14;	author petere;	state Exp;
branches;
next	1.21;

1.21
date	2001.11.21.06.09.45;	author thomas;	state Exp;
branches;
next	1.20;

1.20
date	2001.10.26.21.17.03;	author tgl;	state Exp;
branches;
next	1.19;

1.19
date	2001.09.13.15.55.23;	author petere;	state Exp;
branches;
next	1.18;

1.18
date	2001.09.10.21.58.47;	author petere;	state Exp;
branches;
next	1.17;

1.17
date	2001.08.31.04.17.13;	author ishii;	state Exp;
branches;
next	1.16;

1.16
date	2001.08.21.16.35.59;	author tgl;	state Exp;
branches;
next	1.15;

1.15
date	2001.05.17.21.50.17;	author petere;	state Exp;
branches;
next	1.14;

1.14
date	2001.03.24.23.03.26;	author petere;	state Exp;
branches;
next	1.13;

1.13
date	2001.01.13.23.58.55;	author petere;	state Exp;
branches;
next	1.12;

1.12
date	2000.12.26.00.10.37;	author petere;	state Exp;
branches;
next	1.11;

1.11
date	2000.03.31.03.27.41;	author thomas;	state Exp;
branches;
next	1.10;

1.10
date	2000.03.28.02.59.55;	author tgl;	state Exp;
branches;
next	1.9;

1.9
date	2000.03.28.02.53.02;	author tgl;	state Exp;
branches;
next	1.8;

1.8
date	2000.02.17.03.39.39;	author tgl;	state Exp;
branches;
next	1.7;

1.7
date	2000.01.24.07.16.49;	author tgl;	state Exp;
branches;
next	1.6;

1.6
date	2000.01.22.23.50.08;	author tgl;	state Exp;
branches;
next	1.5;

1.5
date	99.07.22.15.11.05;	author thomas;	state Exp;
branches;
next	1.4;

1.4
date	99.05.27.15.44.54;	author thomas;	state Exp;
branches;
next	1.3;

1.3
date	98.12.29.02.24.21;	author thomas;	state Exp;
branches;
next	1.2;

1.2
date	98.07.29.06.50.04;	author thomas;	state Exp;
branches;
next	1.1;

1.1
date	98.03.01.08.16.16;	author thomas;	state Exp;
branches;
next	;

1.30.2.1
date	2003.09.07.04.36.44;	author momjian;	state Exp;
branches;
next	;

1.37.4.1
date	2005.01.23.00.37.31;	author momjian;	state Exp;
branches;
next	;

1.66.4.1
date	2010.08.17.04.37.19;	author petere;	state Exp;
branches;
next	;


desc
@@


1.67
log
@Spell and markup checking
@
text
@<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.66 2010/02/24 15:54:31 momjian Exp $ -->

<sect1 id="xindex">
 <title>Interfacing Extensions To Indexes</title>

 <indexterm zone="xindex">
  <primary>index</primary>
  <secondary>for user-defined data type</secondary>
 </indexterm>

  <para>
   The procedures described thus far let you define new types, new
   functions, and new operators. However, we cannot yet define an
   index on a column of a new data type.  To do this, we must define an
   <firstterm>operator class</> for the new data type.  Later in this
   section, we will illustrate this concept in an example: a new
   operator class for the B-tree index method that stores and sorts
   complex numbers in ascending absolute value order.
  </para>

  <para>
   Operator classes can be grouped into <firstterm>operator families</>
   to show the relationships between semantically compatible classes.
   When only a single data type is involved, an operator class is sufficient,
   so we'll focus on that case first and then return to operator families.
  </para>

 <sect2 id="xindex-opclass">
  <title>Index Methods and Operator Classes</title>

  <para>
   The <classname>pg_am</classname> table contains one row for every
   index method (internally known as access method).  Support for
   regular access to tables is built into
   <productname>PostgreSQL</productname>, but all index methods are
   described in <classname>pg_am</classname>.  It is possible to add a
   new index method by defining the required interface routines and
   then creating a row in <classname>pg_am</classname> &mdash; but that is
   beyond the scope of this chapter (see <xref linkend="indexam">).
  </para>

  <para>
   The routines for an index method do not directly know anything
   about the data types that the index method will operate on.
   Instead, an <firstterm>operator
   class</><indexterm><primary>operator class</></indexterm>
   identifies the set of operations that the index method needs to use
   to work with a particular data type.  Operator classes are so
   called because one thing they specify is the set of
   <literal>WHERE</>-clause operators that can be used with an index
   (i.e., can be converted into an index-scan qualification).  An
   operator class can also specify some <firstterm>support
   procedures</> that are needed by the internal operations of the
   index method, but do not directly correspond to any
   <literal>WHERE</>-clause operator that can be used with the index.
  </para>

  <para>
   It is possible to define multiple operator classes for the same
   data type and index method.  By doing this, multiple
   sets of indexing semantics can be defined for a single data type.
   For example, a B-tree index requires a sort ordering to be defined
   for each data type it works on.
   It might be useful for a complex-number data type
   to have one B-tree operator class that sorts the data by complex
   absolute value, another that sorts by real part, and so on.
   Typically, one of the operator classes will be deemed most commonly
   useful and will be marked as the default operator class for that
   data type and index method.
  </para>

  <para>
   The same operator class name
   can be used for several different index methods (for example, both B-tree
   and hash index methods have operator classes named
   <literal>int4_ops</literal>), but each such class is an independent
   entity and must be defined separately.
  </para>
 </sect2>

 <sect2 id="xindex-strategies">
  <title>Index Method Strategies</title>

  <para>
   The operators associated with an operator class are identified by
   <quote>strategy numbers</>, which serve to identify the semantics of
   each operator within the context of its operator class.
   For example, B-trees impose a strict ordering on keys, lesser to greater,
   and so operators like <quote>less than</> and <quote>greater than or equal
   to</> are interesting with respect to a B-tree.
   Because
   <productname>PostgreSQL</productname> allows the user to define operators,
   <productname>PostgreSQL</productname> cannot look at the name of an operator
   (e.g., <literal>&lt;</> or <literal>&gt;=</>) and tell what kind of
   comparison it is.  Instead, the index method defines a set of
   <quote>strategies</>, which can be thought of as generalized operators.
   Each operator class specifies which actual operator corresponds to each
   strategy for a particular data type and interpretation of the index
   semantics.
  </para>

  <para>
   The B-tree index method defines five strategies, shown in <xref
   linkend="xindex-btree-strat-table">.
  </para>

   <table tocentry="1" id="xindex-btree-strat-table">
    <title>B-tree Strategies</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Operation</entry>
       <entry>Strategy Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>less than</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>less than or equal</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>equal</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry>greater than or equal</entry>
       <entry>4</entry>
      </row>
      <row>
       <entry>greater than</entry>
       <entry>5</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   Hash indexes support only equality comparisons, and so they use only one
   strategy, shown in <xref linkend="xindex-hash-strat-table">.
  </para>

   <table tocentry="1" id="xindex-hash-strat-table">
    <title>Hash Strategies</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Operation</entry>
       <entry>Strategy Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>equal</entry>
       <entry>1</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   GiST indexes are more flexible: they do not have a fixed set of
   strategies at all.  Instead, the <quote>consistency</> support routine
   of each particular GiST operator class interprets the strategy numbers
   however it likes.  As an example, several of the built-in GiST index
   operator classes index two-dimensional geometric objects, providing
   the <quote>R-tree</> strategies shown in
   <xref linkend="xindex-rtree-strat-table">.  Four of these are true
   two-dimensional tests (overlaps, same, contains, contained by);
   four of them consider only the X direction; and the other four
   provide the same tests in the Y direction.
  </para>

   <table tocentry="1" id="xindex-rtree-strat-table">
    <title>GiST Two-Dimensional <quote>R-tree</> Strategies</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Operation</entry>
       <entry>Strategy Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>strictly left of</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>does not extend to right of</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>overlaps</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry>does not extend to left of</entry>
       <entry>4</entry>
      </row>
      <row>
       <entry>strictly right of</entry>
       <entry>5</entry>
      </row>
      <row>
       <entry>same</entry>
       <entry>6</entry>
      </row>
      <row>
       <entry>contains</entry>
       <entry>7</entry>
      </row>
      <row>
       <entry>contained by</entry>
       <entry>8</entry>
      </row>
      <row>
       <entry>does not extend above</entry>
       <entry>9</entry>
      </row>
      <row>
       <entry>strictly below</entry>
       <entry>10</entry>
      </row>
      <row>
       <entry>strictly above</entry>
       <entry>11</entry>
      </row>
      <row>
       <entry>does not extend below</entry>
       <entry>12</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   GIN indexes are similar to GiST indexes in flexibility: they don't have a
   fixed set of strategies. Instead the support routines of each operator
   class interpret the strategy numbers according to the operator class's
   definition. As an example, the strategy numbers used by the built-in
   operator classes for arrays are
   shown in <xref linkend="xindex-gin-array-strat-table">.
  </para>

   <table tocentry="1" id="xindex-gin-array-strat-table">
    <title>GIN Array Strategies</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Operation</entry>
       <entry>Strategy Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>overlap</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>contains</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>is contained by</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry>equal</entry>
       <entry>4</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   Notice that all strategy operators return Boolean values.  In
   practice, all operators defined as index method strategies must
   return type <type>boolean</type>, since they must appear at the top
   level of a <literal>WHERE</> clause to be used with an index.
  </para>
 </sect2>

 <sect2 id="xindex-support">
  <title>Index Method Support Routines</title>

  <para>
   Strategies aren't usually enough information for the system to figure
   out how to use an index.  In practice, the index methods require
   additional support routines in order to work. For example, the B-tree
   index method must be able to compare two keys and determine whether one
   is greater than, equal to, or less than the other.  Similarly, the
   hash index method must be able to compute hash codes for key values.
   These operations do not correspond to operators used in qualifications in
   SQL commands;  they are administrative routines used by
   the index methods, internally.
  </para>

  <para>
   Just as with strategies, the operator class identifies which specific
   functions should play each of these roles for a given data type and
   semantic interpretation.  The index method defines the set
   of functions it needs, and the operator class identifies the correct
   functions to use by assigning them to the <quote>support function numbers</>
   specified by the index method.
  </para>

  <para>
   B-trees require a single support function, shown in <xref
   linkend="xindex-btree-support-table">.
  </para>

   <table tocentry="1" id="xindex-btree-support-table">
    <title>B-tree Support Functions</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>
        Compare two keys and return an integer less than zero, zero, or
        greater than zero, indicating whether the first key is less than,
        equal to, or greater than the second
       </entry>
       <entry>1</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   Hash indexes likewise require one support function, shown in <xref
   linkend="xindex-hash-support-table">.
  </para>

   <table tocentry="1" id="xindex-hash-support-table">
    <title>Hash Support Functions</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>Compute the hash value for a key</entry>
       <entry>1</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   GiST indexes require seven support functions,
   shown in <xref linkend="xindex-gist-support-table">.
  </para>

   <table tocentry="1" id="xindex-gist-support-table">
    <title>GiST Support Functions</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>consistent - determine whether key satisfies the 
        query qualifier</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>union - compute union of a set of keys</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>compress - compute a compressed representation of a key or value
        to be indexed</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry>decompress - compute a decompressed representation of a 
        compressed key</entry>
       <entry>4</entry>
      </row>
      <row>
       <entry>penalty - compute penalty for inserting new key into subtree 
       with given subtree's key</entry>
       <entry>5</entry>
      </row>
      <row>
       <entry>picksplit - determine which entries of a page are to be moved
       to the new page and compute the union keys for resulting pages</entry>
       <entry>6</entry>
      </row>
      <row>
       <entry>equal - compare two keys and return true if they are equal</entry>
       <entry>7</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   GIN indexes require four support functions,
   shown in <xref linkend="xindex-gin-support-table">.
  </para>

   <table tocentry="1" id="xindex-gin-support-table">
    <title>GIN Support Functions</title>
    <tgroup cols="3">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Description</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry><function>compare</></entry>
       <entry>
        compare two keys and return an integer less than zero, zero,
        or greater than zero, indicating whether the first key is less than,
        equal to, or greater than the second
       </entry>
       <entry>1</entry>
      </row>
      <row>
       <entry><function>extractValue</></entry>
       <entry>extract keys from a value to be indexed</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry><function>extractQuery</></entry>
       <entry>extract keys from a query condition</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry><function>consistent</></entry>
       <entry>determine whether value matches query condition</entry>
       <entry>4</entry>
      </row>
      <row>
       <entry><function>comparePartial</></entry>
       <entry>
        (optional method) compare partial key from
        query and key from index, and return an integer less than zero, zero,
        or greater than zero, indicating whether GIN should ignore this index
        entry, treat the entry as a match, or stop the index scan
       </entry>
       <entry>5</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
   Unlike strategy operators, support functions return whichever data
   type the particular index method expects; for example in the case
   of the comparison function for B-trees, a signed integer.  The number
   and types of the arguments to each support function are likewise
   dependent on the index method.  For B-tree and hash the support functions
   take the same input data types as do the operators included in the operator
   class, but this is not the case for most GIN and GiST support functions.
  </para>
 </sect2>

 <sect2 id="xindex-example">
  <title>An Example</title>

  <para>
   Now that we have seen the ideas, here is the promised example of
   creating a new operator class.
   (You can find a working copy of this example in
   <filename>src/tutorial/complex.c</filename> and
   <filename>src/tutorial/complex.sql</filename> in the source
   distribution.)
   The operator class encapsulates
   operators that sort complex numbers in absolute value order, so we
   choose the name <literal>complex_abs_ops</literal>.  First, we need
   a set of operators.  The procedure for defining operators was
   discussed in <xref linkend="xoper">.  For an operator class on
   B-trees, the operators we require are:

   <itemizedlist spacing="compact">
    <listitem><simpara>absolute-value less-than (strategy 1)</></>
    <listitem><simpara>absolute-value less-than-or-equal (strategy 2)</></>
    <listitem><simpara>absolute-value equal (strategy 3)</></>
    <listitem><simpara>absolute-value greater-than-or-equal (strategy 4)</></>
    <listitem><simpara>absolute-value greater-than (strategy 5)</></>
   </itemizedlist>
  </para>

  <para>
   The least error-prone way to define a related set of comparison operators
   is to write the B-tree comparison support function first, and then write the
   other functions as one-line wrappers around the support function.  This
   reduces the odds of getting inconsistent results for corner cases.
   Following this approach, we first write:

<programlisting><![CDATA[
#define Mag(c)  ((c)->x*(c)->x + (c)->y*(c)->y)

static int
complex_abs_cmp_internal(Complex *a, Complex *b)
{
    double      amag = Mag(a),
                bmag = Mag(b);

    if (amag < bmag)
        return -1;
    if (amag > bmag)
        return 1;
    return 0;
}
]]>
</programlisting>

   Now the less-than function looks like:

<programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_abs_lt);

Datum
complex_abs_lt(PG_FUNCTION_ARGS)
{
    Complex    *a = (Complex *) PG_GETARG_POINTER(0);
    Complex    *b = (Complex *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
}
]]>
</programlisting>

   The other four functions differ only in how they compare the internal
   function's result to zero.
  </para>

  <para>
   Next we declare the functions and the operators based on the functions
   to SQL:

<programlisting>
CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
    AS '<replaceable>filename</replaceable>', 'complex_abs_lt'
    LANGUAGE C IMMUTABLE STRICT;

CREATE OPERATOR &lt; (
   leftarg = complex, rightarg = complex, procedure = complex_abs_lt,
   commutator = &gt; , negator = &gt;= ,
   restrict = scalarltsel, join = scalarltjoinsel
);
</programlisting>
   It is important to specify the correct commutator and negator operators,
   as well as suitable restriction and join selectivity
   functions, otherwise the optimizer will be unable to make effective
   use of the index.  Note that the less-than, equal, and
   greater-than cases should use different selectivity functions.
  </para>

  <para>
   Other things worth noting are happening here:

  <itemizedlist>
   <listitem>
    <para>
     There can only be one operator named, say, <literal>=</literal>
     and taking type <type>complex</type> for both operands.  In this
     case we don't have any other operator <literal>=</literal> for
     <type>complex</type>, but if we were building a practical data
     type we'd probably want <literal>=</literal> to be the ordinary
     equality operation for complex numbers (and not the equality of
     the absolute values).  In that case, we'd need to use some other
     operator name for <function>complex_abs_eq</>.
    </para>
   </listitem>

   <listitem>
    <para>
     Although <productname>PostgreSQL</productname> can cope with
     functions having the same SQL name as long as they have different
     argument data types, C can only cope with one global function
     having a given name.  So we shouldn't name the C function
     something simple like <filename>abs_eq</filename>.  Usually it's
     a good practice to include the data type name in the C function
     name, so as not to conflict with functions for other data types.
    </para>
   </listitem>

   <listitem>
    <para>
     We could have made the SQL name
     of the function <filename>abs_eq</filename>, relying on
     <productname>PostgreSQL</productname> to distinguish it by
     argument data types from any other SQL function of the same name.
     To keep the example simple, we make the function have the same
     names at the C level and SQL level.
    </para>
   </listitem>
  </itemizedlist>
  </para>

  <para>
   The next step is the registration of the support routine required
   by B-trees.  The example C code that implements this is in the same
   file that contains the operator functions.  This is how we declare
   the function:

<programlisting>
CREATE FUNCTION complex_abs_cmp(complex, complex)
    RETURNS integer
    AS '<replaceable>filename</replaceable>'
    LANGUAGE C IMMUTABLE STRICT;
</programlisting>
  </para>

  <para>
   Now that we have the required operators and support routine,
   we can finally create the operator class:

<programlisting><![CDATA[
CREATE OPERATOR CLASS complex_abs_ops
    DEFAULT FOR TYPE complex USING btree AS
        OPERATOR        1       < ,
        OPERATOR        2       <= ,
        OPERATOR        3       = ,
        OPERATOR        4       >= ,
        OPERATOR        5       > ,
        FUNCTION        1       complex_abs_cmp(complex, complex);
]]>
</programlisting>
  </para>

  <para>
   And we're done!  It should now be possible to create
   and use B-tree indexes on <type>complex</type> columns.
  </para>

  <para>
   We could have written the operator entries more verbosely, as in:
<programlisting>
        OPERATOR        1       &lt; (complex, complex) ,
</programlisting>
   but there is no need to do so when the operators take the same data type
   we are defining the operator class for.
  </para>

  <para>
   The above example assumes that you want to make this new operator class the
   default B-tree operator class for the <type>complex</type> data type.
   If you don't, just leave out the word <literal>DEFAULT</>.
  </para>
 </sect2>

 <sect2 id="xindex-opfamily">
  <title>Operator Classes and Operator Families</title>

  <para>
   So far we have implicitly assumed that an operator class deals with
   only one data type.  While there certainly can be only one data type in
   a particular index column, it is often useful to index operations that
   compare an indexed column to a value of a different data type.  Also,
   if there is use for a cross-data-type operator in connection with an
   operator class, it is often the case that the other data type has a
   related operator class of its own.  It is helpful to make the connections
   between related classes explicit, because this can aid the planner in
   optimizing SQL queries (particularly for B-tree operator classes, since
   the planner contains a great deal of knowledge about how to work with them).
  </para>

  <para>
   To handle these needs, <productname>PostgreSQL</productname>
   uses the concept of an <firstterm>operator
   family</><indexterm><primary>operator family</></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</>
   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</>, which includes operator
   classes <literal>int8_ops</>, <literal>int4_ops</>, and
   <literal>int2_ops</> for indexes on <type>bigint</> (<type>int8</>),
   <type>integer</> (<type>int4</>), and <type>smallint</> (<type>int2</>)
   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) ;

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) ;

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) ;

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, int2) ,
  OPERATOR 5 > (int8, int2) ,
  FUNCTION 1 btint82cmp(int8, int2) ,

  -- cross-type comparisons int8 vs int4
  OPERATOR 1 < (int8, int4) ,
  OPERATOR 2 <= (int8, int4) ,
  OPERATOR 3 = (int8, int4) ,
  OPERATOR 4 >= (int8, int4) ,
  OPERATOR 5 > (int8, int4) ,
  FUNCTION 1 btint84cmp(int8, int4) ,

  -- cross-type comparisons int4 vs int2
  OPERATOR 1 < (int4, int2) ,
  OPERATOR 2 <= (int4, int2) ,
  OPERATOR 3 = (int4, int2) ,
  OPERATOR 4 >= (int4, int2) ,
  OPERATOR 5 > (int4, int2) ,
  FUNCTION 1 btint42cmp(int4, int2) ,

  -- cross-type comparisons int4 vs int8
  OPERATOR 1 < (int4, int8) ,
  OPERATOR 2 <= (int4, int8) ,
  OPERATOR 3 = (int4, int8) ,
  OPERATOR 4 >= (int4, int8) ,
  OPERATOR 5 > (int4, int8) ,
  FUNCTION 1 btint48cmp(int4, int8) ,

  -- cross-type comparisons int2 vs int8
  OPERATOR 1 < (int2, int8) ,
  OPERATOR 2 <= (int2, int8) ,
  OPERATOR 3 = (int2, int8) ,
  OPERATOR 4 >= (int2, int8) ,
  OPERATOR 5 > (int2, int8) ,
  FUNCTION 1 btint28cmp(int2, int8) ,

  -- cross-type comparisons int2 vs int4
  OPERATOR 1 < (int2, int4) ,
  OPERATOR 2 <= (int2, int4) ,
  OPERATOR 3 = (int2, int4) ,
  OPERATOR 4 >= (int2, int4) ,
  OPERATOR 5 > (int2, int4) ,
  FUNCTION 1 btint24cmp(int2, int4) ;
]]>
</programlisting>

   Notice that this definition <quote>overloads</> the operator strategy and
   support function numbers: each number occurs multiple times within the
   family.  This is allowed so long as each instance of a
   particular number has distinct input data types.  The instances that have
   both input types equal to an operator class's input type are the
   primary operators and support functions for that operator class,
   and in most cases should be declared as part of the operator class rather
   than as loose members of the family.
  </para>

  <para>
   In a B-tree operator family, all the operators in the family must sort
   compatibly, meaning that the transitive laws hold across all the data types
   supported by the family: <quote>if A = B and B = C, then A =
   C</>, and <quote>if A &lt; B and B &lt; C, then A &lt; C</>.  For each
   operator in the family there must be a support function having the same
   two input data types as the operator.  It is recommended that a family be
   complete, i.e., for each combination of data types, all operators are
   included.  Each operator class should include just the non-cross-type
   operators and support function for its data type.
  </para>

  <para>
   To build a multiple-data-type hash operator family, compatible hash
   support functions must be created for each data type supported by the
   family.  Here compatibility means that the functions are guaranteed to
   return the same hash code for any two values that are considered equal
   by the family's equality operators, even when the values are of different
   types.  This is usually difficult to accomplish when the types have
   different physical representations, but it can be done in some cases.
   Notice that there is only one support function per data type, not one
   per equality operator.  It is recommended that a family be complete, i.e.,
   provide an equality operator for each combination of data types.
   Each operator class should include just the non-cross-type equality
   operator and the support function for its data type.
  </para>

  <para>
   GIN and GiST indexes do not have any explicit notion of cross-data-type
   operations.  The set of operators supported is just whatever the primary
   support functions for a given operator class can handle.
  </para>

  <note>
   <para>
    Prior to <productname>PostgreSQL</productname> 8.3, there was no concept
    of operator families, and so any cross-data-type operators intended to be
    used with an index had to be bound directly into the index's operator
    class.  While this approach still works, it is deprecated because it
    makes an index's dependencies too broad, and because the planner can
    handle cross-data-type comparisons more effectively when both data types
    have operators in the same operator family.
   </para>
  </note>
 </sect2>

 <sect2 id="xindex-opclass-dependencies">
  <title>System Dependencies on Operator Classes</title>

   <indexterm>
    <primary>ordering operator</primary>
   </indexterm>

  <para>
   <productname>PostgreSQL</productname> uses operator classes to infer the
   properties of operators in more ways than just whether they can be used
   with indexes.  Therefore, you might want to create operator classes
   even if you have no intention of indexing any columns of your data type.
  </para>

  <para>
   In particular, there are SQL features such as <literal>ORDER BY</> and
   <literal>DISTINCT</> that require comparison and sorting of values.
   To implement these features on a user-defined data type,
   <productname>PostgreSQL</productname> looks for the default B-tree operator
   class for the data type.  The <quote>equals</> member of this operator
   class defines the system's notion of equality of values for
   <literal>GROUP BY</> and <literal>DISTINCT</>, and the sort ordering
   imposed by the operator class defines the default <literal>ORDER BY</>
   ordering.
  </para>

  <para>
   Comparison of arrays of user-defined types also relies on the semantics
   defined by the default B-tree operator class.
  </para>

  <para>
   If there is no default B-tree operator class for a data type, the system
   will look for a default hash operator class.  But since that kind of
   operator class only provides equality, in practice it is only enough
   to support array equality.
  </para>

  <para>
   When there is no default operator class for a data type, you will get
   errors like <quote>could not identify an ordering operator</> if you
   try to use these SQL features with the data type.
  </para>

   <note>
    <para>
     In <productname>PostgreSQL</productname> versions before 7.4,
     sorting and grouping operations would implicitly use operators named
     <literal>=</>, <literal>&lt;</>, and <literal>&gt;</>.  The new
     behavior of relying on default operator classes avoids having to make
     any assumption about the behavior of operators with particular names.
    </para>
   </note>

  <para>
   Another important point is that an operator that
   appears in a hash operator family is a candidate for hash joins,
   hash aggregation, and related optimizations.  The hash operator family
   is essential here since it identifies the hash function(s) to use.
  </para>
 </sect2>

 <sect2 id="xindex-opclass-features">
  <title>Special Features of Operator Classes</title>

  <para>
   There are two special features of operator classes that we have
   not discussed yet, mainly because they are not useful
   with the most commonly used index methods.
  </para>

  <para>
   Normally, declaring an operator as a member of an operator class
   (or family) means that the index method can retrieve exactly the set of rows
   that satisfy a <literal>WHERE</> condition using the operator.  For example:
<programlisting>
SELECT * FROM table WHERE integer_column &lt; 4;
</programlisting>
   can be satisfied exactly by a B-tree index on the integer column.
   But there are cases where an index is useful as an inexact guide to
   the matching rows.  For example, if a GiST index stores only bounding boxes
   for geometric objects, then it cannot exactly satisfy a <literal>WHERE</> 
   condition that tests overlap between nonrectangular objects such as
   polygons.  Yet we could use the index to find objects whose bounding
   box overlaps the bounding box of the target object, and then do the
   exact overlap test only on the objects found by the index.  If this
   scenario applies, the index is said to be <quote>lossy</> for the
   operator.  Lossy index searches are implemented by having the index
   method return a <firstterm>recheck</> flag when a row might or might
   not really satisfy the query condition.  The core system will then
   test the original query condition on the retrieved row to see whether
   it should be returned as a valid match.  This approach works if
   the index is guaranteed to return all the required rows, plus perhaps
   some additional rows, which can be eliminated by performing the original
   operator invocation.  The index methods that support lossy searches
   (currently, GiST and GIN) allow the support functions of individual
   operator classes to set the recheck flag, and so this is essentially an
   operator-class feature.
  </para>

  <para>
   Consider again the situation where we are storing in the index only
   the bounding box of a complex object such as a polygon.  In this
   case there's not much value in storing the whole polygon in the index
   entry &mdash; we might as well store just a simpler object of type
   <type>box</>.  This situation is expressed by the <literal>STORAGE</>
   option in <command>CREATE OPERATOR CLASS</>: we'd write something like:

<programlisting>
CREATE OPERATOR CLASS polygon_ops
    DEFAULT FOR TYPE polygon USING gist AS
        ...
        STORAGE box;
</programlisting>

   At present, only the GiST and GIN index methods support a
   <literal>STORAGE</> type that's different from the column data type.
   The GiST <function>compress</> and <function>decompress</> support
   routines must deal with data-type conversion when <literal>STORAGE</>
   is used.  In GIN, the <literal>STORAGE</> type identifies the type of
   the <quote>key</> values, which normally is different from the type
   of the indexed column &mdash; for example, an operator class for
   integer-array columns might have keys that are just integers.  The
   GIN <function>extractValue</> and <function>extractQuery</> support
   routines are responsible for extracting keys from indexed values.
  </para>
 </sect2>

</sect1>
@


1.66
log
@Revert removal of pre-7.4 documenation behavior mentions.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.64 2008/12/07 23:46:39 alvherre Exp $ -->
d419 1
a419 1
    <tgroup cols="2">
d423 1
d429 1
d431 1
a431 1
        compare - compare two keys and return an integer less than zero, zero,
d438 2
a439 1
       <entry>extractValue - extract keys from a value to be indexed</entry>
d443 2
a444 1
       <entry>extractQuery - extract keys from a query condition</entry>
d448 2
a449 1
       <entry>consistent - determine whether value matches query condition</entry>
d453 3
a455 1
       <entry>comparePartial - (optional method) compare partial key from
d458 2
a459 1
        entry, treat the entry as a match, or stop the index scan</entry>
@


1.66.4.1
log
@Spell and markup checking
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.66 2010/02/24 15:54:31 momjian Exp $ -->
d419 1
a419 1
    <tgroup cols="3">
a422 1
       <entry>Description</entry>
a427 1
       <entry><function>compare</></entry>
d429 1
a429 1
        compare two keys and return an integer less than zero, zero,
d436 1
a436 2
       <entry><function>extractValue</></entry>
       <entry>extract keys from a value to be indexed</entry>
d440 1
a440 2
       <entry><function>extractQuery</></entry>
       <entry>extract keys from a query condition</entry>
d444 1
a444 2
       <entry><function>consistent</></entry>
       <entry>determine whether value matches query condition</entry>
d448 1
a448 3
       <entry><function>comparePartial</></entry>
       <entry>
        (optional method) compare partial key from
d451 1
a451 2
        entry, treat the entry as a match, or stop the index scan
       </entry>
@


1.65
log
@Remove pre-7.4 documentaiton mentions, now that 8.0 is the oldest
supported release.
@
text
@d898 10
@


1.64
log
@Desultorily enclose programlisting tags in CDATA, to get rid of some obnoxious
SGML-escaping.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.63 2008/05/16 16:31:01 tgl Exp $ -->
a897 10
   <note>
    <para>
     In <productname>PostgreSQL</productname> versions before 7.4,
     sorting and grouping operations would implicitly use operators named
     <literal>=</>, <literal>&lt;</>, and <literal>&gt;</>.  The new
     behavior of relying on default operator classes avoids having to make
     any assumption about the behavior of operators with particular names.
    </para>
   </note>

@


1.63
log
@Extend GIN to support partial-match searches, and extend tsquery to support
prefix matching using this facility.

Teodor Sigaev and Oleg Bartunov
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.62 2008/04/14 17:05:32 tgl Exp $ -->
d502 2
a503 2
<programlisting>
#define Mag(c)  ((c)-&gt;x*(c)-&gt;x + (c)-&gt;y*(c)-&gt;y)
d511 1
a511 1
    if (amag &lt; bmag)
d513 1
a513 1
    if (amag &gt; bmag)
d517 1
d522 1
a522 1
<programlisting>
d531 1
a531 1
    PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) &lt; 0);
d533 1
d622 1
a622 1
<programlisting>
d625 2
a626 2
        OPERATOR        1       &lt; ,
        OPERATOR        2       &lt;= ,
d628 2
a629 2
        OPERATOR        4       &gt;= ,
        OPERATOR        5       &gt; ,
d631 1
d714 1
a714 1
<programlisting>
d720 2
a721 2
  OPERATOR 1 &lt; ,
  OPERATOR 2 &lt;= ,
d723 2
a724 2
  OPERATOR 4 &gt;= ,
  OPERATOR 5 &gt; ,
d730 2
a731 2
  OPERATOR 1 &lt; ,
  OPERATOR 2 &lt;= ,
d733 2
a734 2
  OPERATOR 4 &gt;= ,
  OPERATOR 5 &gt; ,
d740 2
a741 2
  OPERATOR 1 &lt; ,
  OPERATOR 2 &lt;= ,
d743 2
a744 2
  OPERATOR 4 &gt;= ,
  OPERATOR 5 &gt; ,
d749 2
a750 2
  OPERATOR 1 &lt; (int8, int2) ,
  OPERATOR 2 &lt;= (int8, int2) ,
d752 2
a753 2
  OPERATOR 4 &gt;= (int8, int2) ,
  OPERATOR 5 &gt; (int8, int2) ,
d757 2
a758 2
  OPERATOR 1 &lt; (int8, int4) ,
  OPERATOR 2 &lt;= (int8, int4) ,
d760 2
a761 2
  OPERATOR 4 &gt;= (int8, int4) ,
  OPERATOR 5 &gt; (int8, int4) ,
d765 2
a766 2
  OPERATOR 1 &lt; (int4, int2) ,
  OPERATOR 2 &lt;= (int4, int2) ,
d768 2
a769 2
  OPERATOR 4 &gt;= (int4, int2) ,
  OPERATOR 5 &gt; (int4, int2) ,
d773 2
a774 2
  OPERATOR 1 &lt; (int4, int8) ,
  OPERATOR 2 &lt;= (int4, int8) ,
d776 2
a777 2
  OPERATOR 4 &gt;= (int4, int8) ,
  OPERATOR 5 &gt; (int4, int8) ,
d781 2
a782 2
  OPERATOR 1 &lt; (int2, int8) ,
  OPERATOR 2 &lt;= (int2, int8) ,
d784 2
a785 2
  OPERATOR 4 &gt;= (int2, int8) ,
  OPERATOR 5 &gt; (int2, int8) ,
d789 2
a790 2
  OPERATOR 1 &lt; (int2, int4) ,
  OPERATOR 2 &lt;= (int2, int4) ,
d792 2
a793 2
  OPERATOR 4 &gt;= (int2, int4) ,
  OPERATOR 5 &gt; (int2, int4) ,
d795 1
@


1.62
log
@Push index operator lossiness determination down to GIST/GIN opclass
"consistent" functions, and remove pg_amop.opreqcheck, as per recent
discussion.  The main immediate benefit of this is that we no longer need
8.3's ugly hack of requiring @@@@@@ rather than @@@@ to test weight-using tsquery
searches on GIN indexes.  In future it should be possible to optimize some
other queries better than is done now, by detecting at runtime whether the
index match is exact or not.

Tom Lane, after an idea of Heikki's, and with some help from Teodor.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.61 2007/12/02 04:36:40 tgl Exp $ -->
d447 7
@


1.61
log
@Mention hash opclasses in 'System Dependencies on Operator Classes',
which previously only talked about btree opclasses.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.60 2007/04/25 19:48:27 neilc Exp $ -->
d916 1
a916 2
   (or family) means
   that the index method can retrieve exactly the set of rows
d923 2
a924 2
   the matching rows.  For example, if a GiST index stores only
   bounding boxes for objects, then it cannot exactly satisfy a <literal>WHERE</>
d930 11
a940 5
   operator, and we add <literal>RECHECK</> to the <literal>OPERATOR</> clause
   in the <command>CREATE OPERATOR CLASS</> command.
   <literal>RECHECK</> is valid if the index is guaranteed to return
   all the required rows, plus perhaps some additional rows, which
   can be eliminated by performing the original operator invocation.
@


1.60
log
@Minor consistency tweak for SGML docs.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.59 2007/02/06 04:38:31 tgl Exp $ -->
d896 7
d960 1
a960 1
   integer array columns might have keys that are just integers.  The
@


1.59
log
@Docs updates for cross-type hashing.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.58 2007/02/01 00:28:18 momjian Exp $ -->
d329 1
a329 1
        equal to, or greater than the second.
@


1.58
log
@Consistenly use colons before '<programlisting>' blocks, where
appropriate.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.57 2007/01/31 20:56:20 momjian Exp $ -->
d142 1
a142 1
   Hash indexes express only bitwise equality, and so they use only one
d165 1
a165 1
   GiST indexes are even more flexible: they do not have a fixed set of
d805 1
a805 1
   included.  An operator class should include just the non-cross-type
d810 12
a821 3
   At this writing, hash indexes do not support cross-type operations,
   and so there is little use for a hash operator family larger than one
   operator class.  This is expected to be relaxed in the future.
@


1.57
log
@Update documentation on may/can/might:

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".

Also update two error messages mentioned in the documenation to match.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.56 2007/01/23 20:45:28 tgl Exp $ -->
d493 1
a493 1
   Following this approach, we first write
d512 1
a512 1
   Now the less-than function looks like
d631 1
a631 1
   We could have written the operator entries more verbosely, as in
d902 1
a902 1
   that satisfy a <literal>WHERE</> condition using the operator.  For example,
d928 1
a928 1
   option in <command>CREATE OPERATOR CLASS</>: we'd write something like
@


1.56
log
@Update xindex.sgml to discuss operator families.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.55 2007/01/20 23:13:01 tgl Exp $ -->
d52 1
a52 1
   operator class may also specify some <firstterm>support
d666 1
a666 1
   An operator family contains one or more operator classes, and may also
d926 1
a926 1
   entry &mdash; we may as well store just a simpler object of type
@


1.55
log
@Simplify pg_am representation of ordering-capable access methods:
provide just a boolean 'amcanorder', instead of fields that specify the
sort operator strategy numbers.  We have decided to require ordering-capable
AMs to use btree-compatible strategy numbers, so the old fields are
overkill (and indeed misleading about what's allowed).
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.54 2007/01/09 02:14:10 tgl Exp $ -->
d21 6
a26 12
  <note>
   <para>
    Prior to <productname>PostgreSQL</productname> release 7.3, it was
    necessary to make manual additions to the system catalogs
    <classname>pg_amop</>, <classname>pg_amproc</>, and
    <classname>pg_opclass</> in order to create a user-defined
    operator class.  That approach is now deprecated in favor of using
    <xref linkend="sql-createopclass" endterm="sql-createopclass-title">,
    which is a much simpler and less error-prone way of creating the
    necessary catalog entries.
   </para>
  </note>
d28 1
a28 1
 <sect2 id="xindex-im">
d279 1
a279 1
   Note that all strategy operators return Boolean values.  In
d306 2
a307 1
   functions to use by assigning them to the <quote>support function numbers</>.
d327 3
a329 3
   Compare two keys and return an integer less than zero, zero, or
   greater than zero, indicating whether the first key is less than, equal to,
   or greater than the second.
d454 5
a458 1
   of the comparison function for B-trees, a signed integer.
d646 2
a647 2
 <sect2 id="xindex-opclass-crosstype">
  <title>Cross-Data-Type Operator Classes</title>
d653 7
a659 2
   compare an indexed column to a value of a different data type.  This is
   presently supported by the B-tree and GiST index methods.
d663 40
a702 6
   B-trees require the left-hand operand of each operator to be the indexed
   data type, but the right-hand operand can be of a different type.  There
   must be a support function having a matching signature.  For example,
   the built-in operator class for type <type>bigint</> (<type>int8</>)
   allows cross-type comparisons to <type>int4</> and <type>int2</>.  It
   could be duplicated by this definition:
d705 2
d708 1
a708 1
DEFAULT FOR TYPE int8 USING btree AS
d715 11
a725 1
  FUNCTION 1 btint8cmp(int8, int8) ,
d727 12
a738 1
  -- cross-type comparisons to int2 (smallint)
d746 1
a746 1
  -- cross-type comparisons to int4 (integer)
d752 33
a784 1
  FUNCTION 1 btint84cmp(int8, int4) ;
d788 19
a806 4
   support function numbers.  This is allowed (for B-tree operator classes
   only) so long as each instance of a particular number has a different
   right-hand data type.  The instances that are not cross-type are the
   default or primary operators of the operator class.
d810 3
a812 7
   GiST indexes do not allow overloading of strategy or support function
   numbers, but it is still possible to get the effect of supporting
   multiple right-hand data types, by assigning a distinct strategy number
   to each operator that needs to be supported.  The <literal>consistent</>
   support function must determine what it needs to do based on the strategy
   number, and must be prepared to accept comparison values of the appropriate
   data types.
d814 18
d899 2
a900 1
   Normally, declaring an operator as a member of an operator class means
@


1.54
log
@Support ORDER BY ... NULLS FIRST/LAST, and add ASC/DESC/NULLS FIRST/NULLS LAST
per-column options for btree indexes.  The planner's support for this is still
pretty rudimentary; it does not yet know how to plan mergejoins with
nondefault ordering options.  The documentation is pretty rudimentary, too.
I'll work on improving that stuff later.

Note incompatible change from prior behavior: ORDER BY ... USING will now be
rejected if the operator is not a less-than or greater-than member of some
btree opclass.  This prevents less-than-sane behavior if an operator that
doesn't actually define a proper sort ordering is selected.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.53 2006/12/01 23:46:46 tgl Exp $ -->
a289 14

  <para>
   By the way, the <structfield>amorderstrategy</structfield> and
   <structfield>amdescorder</structfield> columns in <classname>pg_am</> tell
   whether the index method supports ordered scans.  Zeroes mean it doesn't;
   if it does, <structfield>amorderstrategy</structfield> is the strategy
   number that corresponds to the default ordering operator, and
   <structfield>amdescorder</structfield> is the strategy number for the
   ordering operator of an index column that has the <literal>DESC</> option.
   For example, B-tree has <structfield>amorderstrategy</structfield> = 1,
   which is its <quote>less than</quote> strategy number, and
   <structfield>amdescorder</structfield> = 5, which is its
   <quote>greater than</quote> strategy number.
  </para>
@


1.53
log
@Editorial improvements for GIN documentation.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.52 2006/10/23 18:10:32 petere Exp $ -->
d292 11
a302 7
   By the way, the <structfield>amorderstrategy</structfield> column
   in <classname>pg_am</> tells whether
   the index method supports ordered scans.  Zero means it doesn't; if it
   does, <structfield>amorderstrategy</structfield> is the strategy
   number that corresponds to the ordering operator.  For example, B-tree
   has <structfield>amorderstrategy</structfield> = 1, which is its
   <quote>less than</quote> strategy number.
@


1.52
log
@Spellchecking and such
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.51 2006/09/21 15:09:38 teodor Exp $ -->
d246 6
a251 5
   GIN indexes are similar to GiST's in flexibility: they don't have a fixed
   et of strategies. Instead, the <quote>consistency</> support routine
   interprets the strategy numbers accordingly with operator class
   definition. As an example, strategies of operator class over arrays
   is shown in <xref linkend="xindex-gin-array-strat-table">.
d255 1
a255 1
    <title>GIN Array's Strategies</title>
d392 1
a392 1
		query qualifier</entry>
d396 1
a396 1
       <entry>union - compute union of of a set of given keys</entry>
d400 2
a401 2
       <entry>compress - computes a compressed representation of a key or value
		to be indexed</entry>
d405 2
a406 2
       <entry>decompress - computes a decompressed representation of a 
	   compressed key </entry>
d411 1
a411 1
	   with given subtree's key</entry>
d416 1
a416 1
	   to the new page and compute the union keys for resulting pages </entry>
d420 1
a420 2
       <entry>equal - compare two keys and returns true if they are equal 
		</entry>
d444 4
a447 4
   compare - Compare two keys and return an integer less than zero, zero, or
   greater than zero, indicating whether the first key is less than, equal to,
   or greater than the second.
	   </entry>
d451 1
a451 1
       <entry>extractValue - extract keys from value to be indexed</entry>
d455 1
a455 1
       <entry>extractQuery - extract keys from query</entry>
d459 1
a459 2
       <entry>consistent - determine whether value matches by the
			   query</entry>
d824 1
a824 1
   At present, only the GiST and GIN index method supports a
d826 1
a826 1
   The GiST <literal>compress</> and <literal>decompress</> support
d828 6
a833 2
   is used. Functions named <literal>extractValue</> and <literal>extractQuery</>
   do conversation into internally used types for GIN.
@


1.51
log
@Add comments about STORAGE option for GIN
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.50 2006/09/21 15:03:53 teodor Exp $ -->
d390 1
a390 1
       <entry>consistent - determine whether key satifies the 
@


1.50
log
@Fix table's caption
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.49 2006/09/18 12:11:36 teodor Exp $ -->
d825 1
a825 1
   At present, only the GiST index method supports a
d829 2
a830 1
   is used.
@


1.49
log
@Improve wordings by David Fuhry <dfuhry@@cs.kent.edu>
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.48 2006/09/16 00:30:16 momjian Exp $ -->
d254 1
a254 1
    <title>GiST Two-Dimensional <quote>R-tree</> Strategies</title>
@


1.48
log
@Remove emacs info from footer of SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.47 2006/09/14 13:40:28 teodor Exp $ -->
d246 2
a247 2
   GIN indexes are similar to GiST in flexibility: it hasn't a fixed set
   of strategies. Instead, the <quote>consistency</> support routine
@


1.47
log
@Fix SGML markup
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.46 2006/09/14 11:16:27 teodor Exp $ -->
a833 17

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
@


1.46
log
@GIN documentation and slightly improving GiST docs.
Thanks to  Christopher Kings-Lynne <chris.kingslynne@@gmail.com> for
initial version and Jeff Davis <pgsql@@j-davis.com> for inspection
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.45 2006/09/05 03:09:56 momjian Exp $ -->
a462 1
      </row>
@


1.45
log
@Remove GIN documentation

Christopher Kings-Lynne
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.44 2006/09/04 20:10:53 momjian Exp $ -->
d246 38
d390 2
a391 1
       <entry>consistent</entry>
d395 1
a395 1
       <entry>union</entry>
d399 2
a400 1
       <entry>compress</entry>
d404 2
a405 1
       <entry>decompress</entry>
d409 2
a410 1
       <entry>penalty</entry>
d414 2
a415 1
       <entry>picksplit</entry>
d419 2
a420 1
       <entry>equal</entry>
d428 41
@


1.44
log
@Add GIN documentation.

Christopher Kings-Lynne
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.43 2006/03/10 19:10:49 momjian Exp $ -->
a383 35
   GIN indexes require four support functions,
   shown in <xref linkend="xindex-gin-support-table">.
  </para>

   <table tocentry="1" id="xindex-gin-support-table">
    <title>GIN Support Functions</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>compare</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>extract value</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>extract query</entry>
       <entry>3</entry>
      </row>
      <row>
       <entry>consistent</entry>
       <entry>4</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
@


1.43
log
@Make $PostgreSQL CVS tags consistent for SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.49 2005/04/09 03:52:43 momjian Exp $ -->
d384 35
@


1.42
log
@R-tree is dead ... long live GiST.
@
text
@d1 1
a1 3
<!--
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp $
-->
@


1.41
log
@Documentation tweak: make <command>CREATE OPERATOR CLASS</command> into
an <xref/>.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.40 2005/06/24 20:53:30 tgl Exp $
d173 6
a178 2
   R-tree indexes express relationships in two-dimensional space.
   They use twelve strategies, shown in
d186 1
a186 1
    <title>R-tree Strategies</title>
a247 7
   GiST indexes are even more flexible: they do not have a fixed set of
   strategies at all.  Instead, the <quote>consistency</> support routine
   of each particular GiST operator class interprets the strategy numbers
   however it likes.
  </para>

  <para>
d274 2
a275 3
   R-tree index method must be able to compute
   intersections,  unions, and sizes of rectangles.  These
   operations do not correspond to operators used in qualifications in
a338 31
   R-tree indexes require three support functions,
   shown in <xref linkend="xindex-rtree-support-table">.
  </para>

   <table tocentry="1" id="xindex-rtree-support-table">
    <title>R-tree Support Functions</title>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Function</entry>
       <entry>Support Number</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>union</entry>
       <entry>1</entry>
      </row>
      <row>
       <entry>intersection</entry>
       <entry>2</entry>
      </row>
      <row>
       <entry>size</entry>
       <entry>3</entry>
      </row>
     </tbody>
    </tgroup>
   </table>

  <para>
d714 1
a714 1
   the matching rows.  For example, if an R-tree index stores only
@


1.40
log
@Extend r-tree operator classes to handle Y-direction tests equivalent
to the existing X-direction tests.  An rtree class now includes 4 actual
2-D tests, 4 1-D X-direction tests, and 4 1-D Y-direction tests.
This involved adding four new Y-direction test operators for each of
box and polygon; I followed the PostGIS project's lead as to the names
of these operators.
NON BACKWARDS COMPATIBLE CHANGE: the poly_overleft (&<) and poly_overright
(&>) operators now have semantics comparable to box_overleft and box_overright.
This is necessary to make r-tree indexes work correctly on polygons.
Also, I changed circle_left and circle_right to agree with box_left and
box_right --- formerly they allowed the boundaries to touch.  This isn't
actually essential given the lack of any r-tree opclass for circles, but
it seems best to sync all the definitions while we are at it.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.39 2005/02/13 03:04:15 tgl Exp $
d29 4
a32 3
    operator class.  That approach is now deprecated in favor of
    using <command>CREATE OPERATOR CLASS</>, which is a much simpler
    and less error-prone way of creating the necessary catalog entries.
@


1.39
log
@Write some real documentation about the index access method API.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.38 2005/01/23 00:30:18 momjian Exp $
d172 6
a177 2
   R-tree indexes express rectangle-containment relationships.
   They use eight strategies, shown in <xref linkend="xindex-rtree-strat-table">.
d191 1
a191 1
       <entry>left of</entry>
d195 1
a195 1
       <entry>left of or overlapping</entry>
d199 1
a199 1
       <entry>overlapping</entry>
d203 1
a203 1
       <entry>right of or overlapping</entry>
d207 1
a207 1
       <entry>right of</entry>
d222 16
d421 1
a421 1
   type the particular index method expects, for example in the case
@


1.38
log
@Add tools/find_gt_lt to find < and > in SGML source.

Lowercase some uppercase tags so tools is more reliable at finding
problems.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.37 2004/11/15 06:32:14 neilc Exp $
d46 1
a46 1
   far beyond the scope of this chapter.
d517 1
a517 1
     functions having the same name as long as they have different
d528 1
a528 1
     We could have made the <productname>PostgreSQL</productname> name
d531 1
a531 2
     argument data types from any other
     <productname>PostgreSQL</productname> function of the same name.
d533 1
a533 2
     names at the C level and <productname>PostgreSQL</productname>
     level.
@


1.37
log
@Replace "--" and "---" with "&mdash;" as appropriate, for better-looking
output.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.36 2003/11/29 19:51:38 pgsql Exp $
d703 1
a703 1
     In <ProductName>PostgreSQL</ProductName> versions before 7.4,
@


1.37.4.1
log
@Add tools/find_gt_lt to find < and > in SGML source.

Lowercase some uppercase tags so tools is more reliable at finding
problems.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.37 2004/11/15 06:32:14 neilc Exp $
d703 1
a703 1
     In <productname>PostgreSQL</productname> versions before 7.4,
@


1.36
log
@
$Header: -> $PostgreSQL Changes ...
@
text
@d2 1
a2 1
$PostgreSQL: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.35 2003/11/12 21:15:45 tgl Exp $
d45 1
a45 1
   then creating a row in <classname>pg_am</classname> --- but that is
d748 1
a748 1
   entry --- we may as well store just a simpler object of type
@


1.35
log
@Cross-data-type comparisons are now indexable by btrees, pursuant to my
pghackers proposal of 8-Nov.  All the existing cross-type comparison
operators (int2/int4/int8 and float4/float8) have appropriate support.
The original proposal of storing the right-hand-side datatype as part of
the primary key for pg_amop and pg_amproc got modified a bit in the event;
it is easier to store zero as the 'default' case and only store a nonzero
when the operator is actually cross-type.  Along the way, remove the
long-since-defunct bigbox_ops operator class.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.34 2003/11/01 01:56:29 petere Exp $
@


1.34
log
@Spell checking, consistent terminology.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.33 2003/10/21 23:28:42 tgl Exp $
d83 1
a83 1
   <literal>oid_ops</literal>), but each such class is an independent
d589 65
@


1.33
log
@Ooops, missed updating this part of the complex-datatype example.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 petere Exp $
d434 1
a434 1
   is to write the btree comparison support function first, and then write the
d603 1
a603 1
   even if you have no intention of indexing any columns of your datatype.
d609 1
a609 1
   To implement these features on a user-defined datatype,
d611 1
a611 1
   class for the datatype.  The <quote>equals</> member of this operator
d624 1
a624 1
   If there is no default B-tree operator class for a datatype, the system
d631 1
a631 1
   When there is no default operator class for a datatype, you will get
d633 1
a633 1
   try to use these SQL features with the datatype.
@


1.32
log
@Add/edit index entries.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.31 2003/08/17 22:09:00 tgl Exp $
d411 6
a416 1
   creating a new operator class.  The operator class encapsulates
d433 5
a437 1
   The C code for the equality operator look like this:
d440 1
a440 1
#define Mag(c) ((c)-&gt;x*(c)-&gt;x + (c)-&gt;y*(c)-&gt;y)
d442 2
a443 2
bool
complex_abs_eq(Complex *a, Complex *b)
d445 8
a452 2
    double amag = Mag(a), bmag = Mag(b);
    return (amag == bmag);
d455 18
a472 4
   The other four operators are very similar.  You can find their code
   in <filename>src/tutorial/complex.c</filename> and
   <filename>src/tutorial/complex.sql</filename> in the source
   distribution.
d476 3
a478 1
   Now declare the functions and the operators based on the functions:
d480 8
a487 10
CREATE FUNCTION complex_abs_eq(complex, complex) RETURNS boolean
    AS '<replaceable>filename</replaceable>', 'complex_abs_eq'
    LANGUAGE C;

CREATE OPERATOR = (
    leftarg = complex,
    rightarg = complex,
    procedure = complex_abs_eq,
    restrict = eqsel,
    join = eqjoinsel
d490 2
a491 1
   It is important to specify the restriction and join selectivity
d551 1
a551 1
    LANGUAGE C;
@


1.31
log
@Update documentation to reflect the fact that ORDER BY, GROUP BY, etc
are now driven by the default btree opclass, rather than assuming that
particular operator names have the needed semantics.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.30 2003/04/13 09:57:35 petere Exp $
d8 5
d51 12
a62 9
   about the data types that the index method will operate on.  Instead, an
   <firstterm>operator class</> identifies the set of operations that the
   index method needs to use to work with a particular data type.
   Operator classes are so called because one thing they specify is the set
   of <literal>WHERE</>-clause operators that can be used with an index (i.e., can be
   converted into an index-scan qualification).  An operator class may also
   specify some <firstterm>support procedures</> that are needed by the
   internal operations of the index method, but do not directly
   correspond to any <literal>WHERE</>-clause operator that can be used with the index.
@


1.30
log
@Integrate the operator class section into the comprehensive extending SQL
chapter as well.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.29 2002/09/21 18:32:54 petere Exp $
d455 1
a455 1
   use of the index.  Note that there less-than, equal, and
d554 55
d614 2
a615 2
   not discussed yet, mainly because they are not very useful
   with the default B-tree index method.
@


1.30.2.1
log
@Update this branch to match CVS head, includes WIN32 improvements.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 petere Exp $
a7 5
 <indexterm zone="xindex">
  <primary>index</primary>
  <secondary>for user-defined data type</secondary>
 </indexterm>

d46 9
a54 12
   about the data types that the index method will operate on.
   Instead, an <firstterm>operator
   class</><indexterm><primary>operator class</></indexterm>
   identifies the set of operations that the index method needs to use
   to work with a particular data type.  Operator classes are so
   called because one thing they specify is the set of
   <literal>WHERE</>-clause operators that can be used with an index
   (i.e., can be converted into an index-scan qualification).  An
   operator class may also specify some <firstterm>support
   procedures</> that are needed by the internal operations of the
   index method, but do not directly correspond to any
   <literal>WHERE</>-clause operator that can be used with the index.
d455 1
a455 1
   use of the index.  Note that the less-than, equal, and
a553 55
 <sect2 id="xindex-opclass-dependencies">
  <title>System Dependencies on Operator Classes</title>

   <indexterm>
    <primary>ordering operator</primary>
   </indexterm>

  <para>
   <productname>PostgreSQL</productname> uses operator classes to infer the
   properties of operators in more ways than just whether they can be used
   with indexes.  Therefore, you might want to create operator classes
   even if you have no intention of indexing any columns of your datatype.
  </para>

  <para>
   In particular, there are SQL features such as <literal>ORDER BY</> and
   <literal>DISTINCT</> that require comparison and sorting of values.
   To implement these features on a user-defined datatype,
   <productname>PostgreSQL</productname> looks for the default B-tree operator
   class for the datatype.  The <quote>equals</> member of this operator
   class defines the system's notion of equality of values for
   <literal>GROUP BY</> and <literal>DISTINCT</>, and the sort ordering
   imposed by the operator class defines the default <literal>ORDER BY</>
   ordering.
  </para>

  <para>
   Comparison of arrays of user-defined types also relies on the semantics
   defined by the default B-tree operator class.
  </para>

  <para>
   If there is no default B-tree operator class for a datatype, the system
   will look for a default hash operator class.  But since that kind of
   operator class only provides equality, in practice it is only enough
   to support array equality.
  </para>

  <para>
   When there is no default operator class for a datatype, you will get
   errors like <quote>could not identify an ordering operator</> if you
   try to use these SQL features with the datatype.
  </para>

   <note>
    <para>
     In <ProductName>PostgreSQL</ProductName> versions before 7.4,
     sorting and grouping operations would implicitly use operators named
     <literal>=</>, <literal>&lt;</>, and <literal>&gt;</>.  The new
     behavior of relying on default operator classes avoids having to make
     any assumption about the behavior of operators with particular names.
    </para>
   </note>
 </sect2>

d559 2
a560 2
   not discussed yet, mainly because they are not useful
   with the most commonly used index methods.
@


1.29
log
@Add more appropriate markup.
@
text
@d2 1
a2 2
$Header: /cvsroot/pgsql-server/doc/src/sgml/xindex.sgml,v 1.28 2002/07/30 17:34:37 tgl Exp $
PostgreSQL documentation
d5 1
a5 1
<chapter id="xindex">
a7 3
 <sect1 id="xindex-intro">
  <title>Introduction</title>

d10 6
a15 9
   functions, and new operators. However, we cannot yet define a
   secondary index (such as a B-tree, R-tree, or hash access method)
   over a new type, nor associate operators of a new type with secondary
   indexes.
   To do these things, we must define an <firstterm>operator class</>
   for the new data type.  We will describe operator classes in the
   context of a running example:  a  new  operator
   class for the B-tree access method that stores and
   sorts complex numbers in ascending absolute value order.
d21 1
a21 1
    necessary to make manual additions to
a28 1
 </sect1>
d30 2
a31 2
 <sect1 id="xindex-am">
  <title>Access Methods and Operator Classes</title>
d35 7
a41 6
   index access method.  Support for access to regular tables is
   built into <productname>PostgreSQL</productname>, but all index access
   methods are described in <classname>pg_am</classname>.  It is possible
   to add a new index access method by defining the required interface
   routines and then creating a row in <classname>pg_am</classname> ---
   but that is far beyond the scope of this chapter.
d45 2
a46 2
   The routines for an index access method do not directly know anything
   about the data types the access method will operate on.  Instead, an
d48 1
a48 1
   access method needs to be able to use to work with a particular data type.
d50 2
a51 2
   of WHERE-clause operators that can be used with an index (ie, can be
   converted into an index scan qualification).  An operator class may also
d53 2
a54 2
   internal operations of the index access method, but do not directly
   correspond to any WHERE-clause operator that can be used with the index.
d59 1
a59 1
   input data type and index access method.  By doing this, multiple
d66 1
a66 1
   Typically one of the operator classes will be deemed most commonly
d68 1
a68 1
   data type and index access method.
d73 2
a74 2
   can be used for several different access methods (for example, both B-tree
   and hash access methods have operator classes named
d78 1
a78 1
 </sect1>
d80 2
a81 2
 <sect1 id="xindex-strategies">
  <title>Access Method Strategies</title>
d94 1
a94 1
   comparison it is.  Instead, the index access method defines a set of
d96 1
a96 1
   Each operator class shows which actual operator corresponds to each
d102 1
a102 1
   B-tree indexes define 5 strategies, as shown in <xref
a107 1
    <titleabbrev>B-tree</titleabbrev>
d141 2
a142 2
   Hash indexes express only bitwise similarity, and so they define only 1
   strategy, as shown in <xref linkend="xindex-hash-strat-table">.
a146 1
    <titleabbrev>Hash</titleabbrev>
d165 1
a165 1
   They define 8 strategies, as shown in <xref linkend="xindex-rtree-strat-table">.
a169 1
    <titleabbrev>R-tree</titleabbrev>
d217 1
a217 1
   of a particular GiST operator class interprets the strategy numbers
d222 7
d231 1
a231 1
   the access method supports ordered scan.  Zero means it doesn't; if it
d237 1
d239 2
a240 8
  <para>
   In short, an operator class must specify a set of operators that express
   each of these semantic ideas for the operator class's data type.
  </para>
 </sect1>

 <sect1 id="xindex-support">
  <title>Access Method Support Routines</title>
d244 1
a244 1
   out how to use an index.  In practice, the access methods require
d246 1
a246 1
   access method must be able to compare two keys and determine whether one
d248 1
a248 1
   R-tree access method must be able to compute
d251 2
a252 2
   SQL queries;  they are administrative routines used by
   the access methods, internally.
d256 1
a256 1
   Just as with operators, the operator class identifies which specific
d258 1
a258 1
   semantic interpretation.  The index access method specifies the set
d260 1
a260 1
   functions to use by assigning <quote>support function numbers</> to them.
d264 1
a264 1
   B-trees require a single support function, as shown in <xref
a269 1
    <titleabbrev>B-tree</titleabbrev>
d291 1
a291 1
   Hash indexes likewise require one support function, as shown in <xref
a296 1
    <titleabbrev>Hash</titleabbrev>
d315 1
a315 1
   as shown in <xref linkend="xindex-rtree-support-table">.
a319 1
    <titleabbrev>R-tree</titleabbrev>
d346 1
a346 1
   as shown in <xref linkend="xindex-gist-support-table">.
a350 1
    <titleabbrev>GiST</titleabbrev>
a390 5
 </sect1>

 <sect1 id="xindex-operators">
  <title>Creating the Operators and Support Routines</title>

d392 17
a408 6
   Now that we have seen the ideas, here is the promised example
   of creating a new operator class.  First, we need a set of operators.
   The procedure for
   defining operators was discussed in <xref linkend="xoper">.
   For  the  <literal>complex_abs_ops</literal>  operator  class on B-trees,
   the operators we require are:
d420 1
a420 6
   Suppose the code that implements these functions
   is stored in the file
   <filename><replaceable>PGROOT</replaceable>/src/tutorial/complex.c</filename>,
   which we have compiled into
   <filename><replaceable>PGROOT</replaceable>/src/tutorial/complex.so</filename>.
   Part of the C code looks like this:
d425 6
a430 6
         bool
         complex_abs_eq(Complex *a, Complex *b)
         {
             double amag = Mag(a), bmag = Mag(b);
             return (amag==bmag);
         }
d432 4
a435 4
   (Note that we will only show the equality operator in this text.
   The other four operators are very similar.  Refer to
   <filename>complex.c</filename> or
   <filename>complex.source</filename> for the details.)
d439 1
a439 1
   We make the function known to <productname>PostgreSQL</productname> like this:
d442 1
a442 1
    AS '<replaceable>PGROOT</replaceable>/src/tutorial/complex'
d444 8
d453 4
d460 1
a460 1
   There are some important things that are happening here:
d464 10
a473 10
  <para>
   First, note that operators for less-than, less-than-or-equal, equal,
   greater-than-or-equal, and greater-than for <filename>complex</filename>
   are being defined.  We can only have one operator named, say, = and
   taking type <filename>complex</filename> for both operands.  In this case
   we don't have any other operator = for <filename>complex</filename>,
   but if we were building a practical data type we'd probably want = to
   be the ordinary equality operation for complex numbers.  In that case,
   we'd need to use some other operator name for <function>complex_abs_eq</>.
  </para>
d477 9
a485 8
  <para>
   Second, although <productname>PostgreSQL</productname> can cope with operators having
   the same name as long as they have different input data types, C can only
   cope with one global routine having a given name, period.  So we shouldn't
   name the C function something simple like <filename>abs_eq</filename>.
   Usually it's a good practice to include the data type name in the C
   function name, so as not to conflict with functions for other data types.
  </para>
d489 10
a498 19
  <para>
   Third, we could have made the <productname>PostgreSQL</productname> name of the function
   <filename>abs_eq</filename>, relying on <productname>PostgreSQL</productname> to distinguish it
   by input data types from any other <productname>PostgreSQL</productname> function of the same name.
   To keep the example simple, we make the function have the same names
   at the C level and <productname>PostgreSQL</productname> level.
  </para>
   </listitem>

   <listitem>
  <para>
   Finally, note that these operator functions return Boolean values.
   In practice, all operators defined as index access method
   strategies must return type <type>boolean</type>, since they must
   appear at the top level of a <literal>WHERE</> clause to be used with an index.
   (On the other hand, support functions return whatever the
   particular access method expects -- in the case of the comparison
   function for B-trees, a signed integer.)
  </para>
d504 4
a507 25
   Now we are ready to define the operators:

<programlisting>
CREATE OPERATOR = (
     leftarg = complex, rightarg = complex,
     procedure = complex_abs_eq,
     restrict = eqsel, join = eqjoinsel
         );
</programlisting>

   The important
   things here are the procedure names (which are the C
   functions defined above) and the restriction and join selectivity
   functions.  You should just use the selectivity functions used in
   the example (see <filename>complex.source</filename>).
   Note that there
   are different such functions for the less-than, equal, and greater-than
   cases.  These must be supplied or the optimizer will be unable to
   make effective use of the index.
  </para>

  <para>
   The next step is the registration of the comparison <quote>support
   routine</quote> required by B-trees.  The C code that implements this
   is in the same file that contains the operator procedures:
d512 1
a512 1
    AS '<replaceable>PGROOT</replaceable>/src/tutorial/complex'
a515 4
 </sect1>

 <sect1 id="xindex-opclass">
  <title>Creating the Operator Class</title>
d534 1
a534 1
   And we're done!  (Whew.)  It should now be possible to create
d552 1
a552 1
 </sect1>
d554 1
a554 1
 <sect1 id="xindex-opclass-features">
d560 1
a560 1
   with the default B-tree index access method.
d565 2
a566 2
   that the index access method can retrieve exactly the set of rows
   that satisfy a WHERE condition using the operator.  For example,
d573 1
a573 1
   bounding boxes for objects, then it cannot exactly satisfy a WHERE
d582 2
a583 2
   all the required tuples, plus perhaps some additional tuples, which
   can be eliminated by performing the original operator comparison.
d591 1
a591 1
   <literal>box</>.  This situation is expressed by the <literal>STORAGE</>
d601 1
a601 1
   At present, only the GiST access method supports a
d607 1
a607 1
 </sect1>
d609 1
a609 1
</chapter>
@


1.28
log
@Replace ad-hoc insertions into pg_opclass and friends with CREATE
OPERATOR CLASS commands.  Further tweaking of documentation for same.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.27 2002/07/30 05:24:56 tgl Exp $
d19 1
a19 1
   for the new datatype.  We will describe operator classes in the
d28 1
a28 1
    necesssary to make manual additions to
d58 1
a58 1
   converted into an indexscan qualification).  An operator class may also
d66 2
a67 2
   input datatype and index access method.  By doing this, multiple
   sets of indexing semantics can be defined for a single datatype.
d69 2
a70 2
   for each datatype it works on.
   It might be useful for a complex-number datatype
d75 1
a75 1
   datatype and index access method.
d104 1
a104 1
   strategy for a particular datatype and interpretation of the index
d243 1
a243 1
   each of these semantic ideas for the operator class's datatype.
d265 1
a265 1
   functions should play each of these roles for a given datatype and
d575 1
a575 1
   but there is no need to do so when the operators take the same datatype
d634 1
a634 1
   <literal>STORAGE</> type that's different from the column datatype.
d636 1
a636 1
   routines must deal with datatype conversion when <literal>STORAGE</>
@


1.27
log
@Rewrite xindex.sgml for CREATE OPERATOR CLASS.  catalogs.sgml finally
contains descriptions of every single system table.  Update 'complex'
tutorial example too.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.26 2002/06/21 03:25:53 momjian Exp $
d100 1
a100 1
   (e.g., <literal>&gt;</> or <literal>&lt;</>) and tell what kind of
d282 1
a282 1
       <entry>Operation</entry>
d289 3
a291 5
   Compare two keys and return -1, 0,
   or +1, depending on whether the first key is less than, equal to,
   or greater than the second. (Actually, this routine can
   return any negative int32 value (&lt; 0), zero, or any non-zero positive
   int32 value (&gt; 0).)
d310 1
a310 1
       <entry>Operation</entry>
d316 1
a316 1
       <entry>compute the hash value for a key</entry>
d334 1
a334 1
       <entry>Operation</entry>
d366 1
a366 1
       <entry>Operation</entry>
d443 2
a444 2
   (Note that we will only show the equality operator for the rest of
   the examples.  The other four operators are very similar.  Refer to
d556 2
a557 2
        OPERATOR        1       < ,
        OPERATOR        2       <= ,
d559 2
a560 2
        OPERATOR        4       >= ,
        OPERATOR        5       > ,
d573 1
a573 1
        OPERATOR        1       < (complex, complex) ,
d600 1
a600 1
SELECT * FROM table WHERE integer_column < 4;
d611 2
a612 2
   operator, and we mark the <literal>OPERATOR</> clause in the
   <command>CREATE OPERATOR CLASS</> command with <literal>RECHECK</>.
@


1.26
log
@Document problems with hash indexes compared to btree.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.25 2002/05/29 17:36:40 tgl Exp $
d16 46
a61 1
   over a new type or its operators.
d65 19
a83 10
   Look back at
   <xref linkend="EXTEND-CATALOGS">.
   The right half shows the  catalogs  that we must modify in order to tell
   <productname>PostgreSQL</productname> how to use a user-defined type and/or
   user-defined  operators with an index (i.e., <filename>pg_am, pg_amop,
    pg_amproc, pg_operator</filename> and <filename>pg_opclass</filename>).
   Unfortunately, there is no simple command to do this.  We will demonstrate
   how to modify these catalogs through a running example:  a  new  operator
   class for the B-tree access method that stores and
   sorts complex numbers in ascending absolute value order.
d87 2
a88 2
 <sect1 id="xindex-am">
  <title>Access Methods</title>
d91 16
a106 5
   The <filename>pg_am</filename> table contains one row for every
   index access method.  Support for the heap access method is built
   into <productname>PostgreSQL</productname>, but all other access
   methods are described in <filename>pg_am</filename>.  The schema is
   shown in <xref linkend="xindex-pgam-table">.
d108 4
a111 2
   <table tocentry="1" id="xindex-pgam-table">
    <title>Index Access Method Schema</title>
d113 3
d119 2
a120 2
       <entry>Column</entry>
       <entry>Description</entry>
d125 2
a126 2
       <entry>amname</entry>
       <entry>name of the access method</entry>
d129 2
a130 2
       <entry>amowner</entry>
       <entry>user ID of the owner (currently not used)</entry>
d133 2
a134 2
       <entry>amstrategies</entry>
       <entry>number of strategies for this access method (see below)</entry>
d137 2
a138 2
       <entry>amsupport</entry>
       <entry>number of support routines for this access method (see below)</entry>
d141 2
a142 3
       <entry>amorderstrategy</entry>
       <entry>zero if the index offers no sort order, otherwise the strategy
        number of the strategy operator that describes the sort order</entry>
d144 14
d159 2
a160 2
       <entry>amcanunique</entry>
       <entry>does AM support unique indexes?</entry>
d162 2
d165 2
a166 22
       <entry>amcanmulticol</entry>
       <entry>does AM support multicolumn indexes?</entry>
      </row>
      <row>
       <entry>amindexnulls</entry>
       <entry>does AM support NULL index entries?</entry>
      </row>
      <row>
       <entry>amconcurrent</entry>
       <entry>does AM support concurrent updates?</entry>
      </row>
      <row>
       <entry>amgettuple</entry>
      </row>
      <row>
       <entry>aminsert</entry>
      </row>
      <row>
       <entry>...</entry>
       <entry>procedure  identifiers  for  interface routines to the access
        method.  For example, regproc IDs for opening,  closing,  and
        getting rows from the access method appear here.</entry>
a170 41
  </para>

  <note>
   <para>
    An index AM that supports multiple columns (has
    <structfield>amcanmulticol</structfield> true) <emphasis>must</>
    support indexing nulls in columns after the first, because the planner
    will assume the index can be used for queries on just the first
    column(s).  For example, consider an index on (a,b) and a query
    WHERE a = 4.  The system will assume the index can be used to scan for
    rows with a = 4, which is wrong if the index omits rows where b is null.
    However it is okay to omit rows where the first indexed column is null.
    (GiST currently does so.)
    <structfield>amindexnulls</structfield> should be set true only if the
    index AM indexes all rows, including arbitrary combinations of nulls.
   </para>
  </note>

  <para>
   The <acronym>OID</acronym> of the row in
   <filename>pg_am</filename> is used as a foreign key in a lot of other
   tables.  You  do not  need to  add a new row to this table; all that
   you are interested in is the <acronym>OID</acronym> of the access
   method you want to extend:

<screen>
SELECT oid FROM pg_am WHERE amname = 'btree';

 oid
-----
 403
(1 row)
</screen>

   We will use that query in a <literal>WHERE</literal>
   clause later.
  </para>
 </sect1>

 <sect1 id="xindex-strategies">
  <title>Access Method Strategies</title>
d173 2
a174 17
   The <structfield>amstrategies</structfield> column exists to standardize
   comparisons across data types.  For example, B-trees
   impose a strict ordering on keys, lesser to greater.  Since
   <productname>PostgreSQL</productname> allows the user to define operators,
   <productname>PostgreSQL</productname> cannot look at the name of an operator
   (e.g., <literal>&gt;</> or <literal>&lt;</>) and tell what kind of comparison it is.  In fact,
   some  access methods don't impose any ordering at all.  For example,
   R-trees express a rectangle-containment relationship,
   whereas a hashed data structure expresses only bitwise similarity based
   on the value of a hash function.  <productname>PostgreSQL</productname>
   needs some consistent way of taking a qualification in your query,
   looking at the operator, and then deciding if a usable index exists.  This
   implies that <productname>PostgreSQL</productname> needs to know, for
   example, that the  <literal>&lt;=</>  and  <literal>&gt;</> operators partition a
   B-tree.  <productname>PostgreSQL</productname>
   uses <firstterm>strategies</firstterm> to express these relationships  between
   operators and the way they can be used to scan indexes.
d177 3
a179 14
  <para>
   Defining a new set of strategies is beyond the scope of this
   discussion, but we'll explain how B-tree strategies work because
   you'll need to know that to add a new B-tree operator class. In the
   <classname>pg_am</classname> table, the
   <structfield>amstrategies</structfield> column sets the number of
   strategies defined for this access method. For B-trees, this number
   is 5.  The meanings of these strategies are shown in <xref
   linkend="xindex-btree-table">.
  </para>

   <table tocentry="1" id="xindex-btree-table">
    <title>B-tree Strategies</title>
    <titleabbrev>B-tree</titleabbrev>
d184 1
a184 1
       <entry>Index</entry>
d189 1
a189 1
       <entry>less than</entry>
d193 1
a193 1
       <entry>less than or equal</entry>
d197 1
a197 1
       <entry>equal</entry>
d201 1
a201 1
       <entry>greater than or equal</entry>
d205 1
a205 1
       <entry>greater than</entry>
d208 12
d225 19
a243 8
   The idea is that you'll need to add operators corresponding to these strategies
   to the <classname>pg_amop</classname> relation (see below).
   The access method code can use these strategy numbers, regardless of data
   type, to figure out how to partition the B-tree,
   compute selectivity, and so on.  Don't worry about the details of adding
   operators yet; just understand that there must be a set of these
   operators for <type>int2</>, <type>int4</>, <type>oid</>, and all other
   data types on which a B-tree can operate.
d251 3
a253 3
   Sometimes, strategies aren't enough information for the system to figure
   out how to use an index.  Some access methods require additional support
   routines in order to work. For example, the B-tree
d264 5
a268 10
   In order to manage diverse support routines consistently across all
   <productname>PostgreSQL</productname> access methods,
   <classname>pg_am</classname> includes a column called
   <structfield>amsupport</structfield>.  This column records the
   number of support routines used by an access method.  For B-trees,
   this number is one: the routine to take two keys and return -1, 0,
   or +1, depending on whether the first key is less than, equal to,
   or greater than the second. (Strictly speaking, this routine can
   return a negative number (&lt; 0), zero, or a non-zero positive
   number (&gt; 0).)
d272 2
a273 8
   The <structfield>amstrategies</structfield> entry in
   <classname>pg_am</classname> is just the number of strategies
   defined for the access method in question.  The operators for less
   than, less equal, and so on don't appear in
   <classname>pg_am</classname>.  Similarly,
   <structfield>amsupport</structfield> is just the number of support
   routines required by the access method.  The actual routines are
   listed elsewhere.
d276 25
d302 2
a303 6
   By the way, the <structfield>amorderstrategy</structfield> column tells whether
   the access method supports ordered scan.  Zero means it doesn't; if it
   does, <structfield>amorderstrategy</structfield> is the number of the strategy
   routine that corresponds to the ordering operator.  For example, B-tree
   has <structfield>amorderstrategy</structfield> = 1, which is its
   <quote>less than</quote> strategy number.
a304 1
 </sect1>
d306 18
a323 2
 <sect1 id="xindex-opclass">
  <title>Operator Classes</title>
d326 2
a327 11
   The next table of interest is <classname>pg_opclass</classname>.  This table
   defines operator class names and input data types for each of the operator
   classes supported by a given index access method.  The same class name
   can be used for several different access methods (for example, both B-tree
   and hash access methods have operator classes named
   <literal>oid_ops</literal>), but a separate
   <filename>pg_opclass</filename> row must appear for each access method.
   The OID of the <classname>pg_opclass</classname> row is
   used as a foreign 
   key in other tables to associate specific operators and support routines
   with the operator class.
d330 27
d358 3
a360 3
   You need to add a row with your operator class name (for example,
   <literal>complex_abs_ops</literal>) to
   <classname>pg_opclass</classname>:
d362 42
a403 25
<programlisting>
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
    VALUES (
        (SELECT oid FROM pg_am WHERE amname = 'btree'),
        'complex_abs_ops',
        (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
        1,	-- UID of superuser is hardwired to 1 as of PG 7.3
        (SELECT oid FROM pg_type WHERE typname = 'complex'),
        true,
        0);

SELECT oid, *
    FROM pg_opclass
    WHERE opcname = 'complex_abs_ops';

  oid   | opcamid |     opcname     | opcnamespace | opcowner | opcintype | opcdefault | opckeytype
--------+---------+-----------------+--------------+----------+-----------+------------+------------
 277975 |     403 | complex_abs_ops |           11 |        1 |    277946 | t          |          0
(1 row)
</programlisting>

   Note that the OID for your <classname>pg_opclass</classname> row will
   be different!  Don't worry about this though.  We'll get this number
   from the system later just like we got the OID of the type here.
  </para>
a404 7
  <para>
   The above example assumes that you want to make this new operator class the
   default B-tree operator class for the <type>complex</type> data type.
   If you don't, just set <structfield>opcdefault</structfield> to false instead.
   <structfield>opckeytype</structfield> is not described here; it should always
   be zero for B-tree operator classes.
  </para>
d411 3
a413 2
   So now we have an access method and an operator  class.
   We  still  need  a  set of operators.  The procedure for
d504 3
a506 3
   (On the other hand, the support function returns whatever the
   particular access method expects -- in this case, a signed
   integer.)
a512 7
   The final routine in the file is the <quote>support routine</quote>
   mentioned when we discussed the <structfield>amsupport</> column of the
   <classname>pg_am</classname> table.  We will use this later on.  For
   now, ignore it.
  </para>

  <para>
d535 10
a544 29
   The next step is to add entries for these operators to
   the <classname>pg_amop</classname> relation.  To do this,
   we'll need the OIDs of the operators we just
   defined.  We'll look up the names of all the operators that take
   two operands of type <type>complex</type>, and pick ours out:
   
<screen>
SELECT o.oid AS opoid, o.oprname
    INTO TEMP TABLE complex_ops_tmp
    FROM pg_operator o, pg_type t
    WHERE o.oprleft = t.oid and o.oprright = t.oid
      and t.typname = 'complex';

 opoid  | oprname
--------+---------
 277963 | +
 277970 | &lt;
 277971 | &lt;=
 277972 | =
 277973 | &gt;=
 277974 | &gt;
(6 rows)
</screen>

   (Again, some of your OID numbers will almost
   certainly be different.)  The operators we are interested in are those
   with OIDs 277970 through 277974.  The values you
   get will probably be different, and you should substitute them for the
   values below.  We will do this with a select statement.
d546 4
d552 2
a553 4
   Now we are ready to insert entries into <classname>pg_amop</classname> for
   our new operator class.  These entries must associate the correct
   B-tree strategy numbers with each of the operators we need.
   The command to insert the less-than operator looks like:
d556 8
a563 7
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
    SELECT opcl.oid, 1, false, c.opoid
        FROM pg_opclass opcl, complex_ops_tmp c
        WHERE
            opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
            opcname = 'complex_abs_ops' AND
            c.oprname = '&lt;';
d565 1
d567 3
a569 5
   Now do this for the other operators substituting for the <literal>1</> in the
   second line above and the <literal>&lt;</> in the last line.  Note the order:
   <quote>less than</> is 1, <quote>less than or equal</> is 2,
   <quote>equal</> is 3, <quote>greater than or equal</quote> is 4, and
   <quote>greater than</quote> is 5.
d573 6
a578 2
   The field <filename>amopreqcheck</filename> is not discussed here; it
   should always be false for B-tree operators.
d582 3
a584 5
   The final step is the registration of the <quote>support routine</quote> previously
   described in our discussion of <classname>pg_am</classname>.  The
   OID of this support routine is stored in the
   <classname>pg_amproc</classname> table, keyed by the operator class
   OID and the support routine number.
d586 4
d592 4
a595 4
   First, we need to register the function in
   <productname>PostgreSQL</productname> (recall that we put the
   C code that implements this routine in the bottom of
   the file in which we implemented the operator routines):
d597 4
d602 1
a602 12
CREATE FUNCTION complex_abs_cmp(complex, complex)
    RETURNS integer
    AS '<replaceable>PGROOT</replaceable>/src/tutorial/complex'
    LANGUAGE C;

SELECT oid, proname FROM pg_proc
    WHERE proname = 'complex_abs_cmp';

  oid   |     proname
--------+-----------------
 277997 | complex_abs_cmp
(1 row)
d604 14
a617 2

   (Again, your OID number will probably be different.)
d621 6
a626 1
   We can add the new row as follows:
d629 4
a632 7
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
    SELECT opcl.oid, 1, p.oid
        FROM pg_opclass opcl, pg_proc p
        WHERE
            opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
            opcname = 'complex_abs_ops' AND
            p.proname = 'complex_abs_cmp';
a633 1
  </para>
d635 5
a639 3
  <para>
   And we're done!  (Whew.)  It should now be possible to create
   and use B-tree indexes on <type>complex</type> columns.
@


1.25
log
@Add a note about the interpretation of amcanmulticol and amindexnulls:
a multicolumn-capable index AM *must* support nulls in index columns
after the first one.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.24 2002/04/17 20:57:56 tgl Exp $
d14 3
a16 3
   functions, and new operators.  However, we cannot yet define a secondary
   index (such as a B-tree, R-tree, or
   hash access method) over a new type or its operators.
@


1.24
log
@Opclasses live in namespaces.  I also took the opportunity to create
an 'opclass owner' column in pg_opclass.  Nothing is done with it at
present, but since there are plans to invent a CREATE OPERATOR CLASS
command soon, we'll probably want DROP OPERATOR CLASS too, which
suggests that a notion of ownership would be a good idea.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.23 2002/03/27 19:19:23 petere Exp $
d107 16
@


1.23
log
@Don't mark up as acronym that which is not an acronym.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.22 2002/01/07 02:29:14 petere Exp $
d283 1
a283 1
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype)
d287 2
d297 3
a299 3
  oid   | opcamid |     opcname     | opcintype | opcdefault | opckeytype
--------+---------+-----------------+-----------+------------+------------
 277975 |     403 | complex_abs_ops |    277946 | t          |          0
@


1.22
log
@Editorial review
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.21 2001/11/21 06:09:45 thomas Exp $
d28 1
a28 1
   class for the <acronym>B-tree</acronym> access method that stores and
d109 1
a109 1
   The <acronym>object ID</acronym> of the row in
d112 1
a112 1
   you are interested in is the <acronym>object ID</acronym> of the access
@


1.21
log
@Deprecate 'current' date/time constant.
Purge "Postgres" in favor of "PostgreSQL" in docs. ref/ not yet done.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.20 2001/10/26 21:17:03 tgl Exp $
d6 5
a10 2
 <chapter id="xindex">
  <title>Interfacing Extensions To Indexes</title>
d13 3
a15 3
   The procedures described thus far let you define a new type, new
   functions and new operators.  However, we cannot yet define a secondary
   index (such as a <acronym>B-tree</acronym>, <acronym>R-tree</acronym> or
d31 4
d37 5
a41 4
   The <filename>pg_am</filename> table contains one row for every index
   access method.  Support for the heap access method is built into
   <productname>PostgreSQL</productname>, but every other access method is
   described in <filename>pg_am</filename>.  The schema is
d43 1
a43 1
   <table tocentry="1">
d60 1
a60 1
       <entry>user id of the owner</entry>
d77 1
a77 1
       <entry>does AM support UNIQUE indexes?</entry>
d100 1
a100 1
        method.  For example, regproc ids for opening,  closing,  and
d115 1
a115 1
   <programlisting>
d122 1
a122 1
   </programlisting>
d124 1
a124 1
   We will use that <command>SELECT</command> in a <command>WHERE</command>
d127 4
d133 2
a134 2
   The <filename>amstrategies</filename> column exists to standardize
   comparisons across data types.  For example, <acronym>B-tree</acronym>s
d140 1
a140 1
   <acronym>R-tree</acronym>s express a rectangle-containment relationship,
d144 1
a144 1
   looking at the operator and then deciding if a usable index exists.  This
d147 2
a148 2
   <acronym>B-tree</acronym>.  <productname>PostgreSQL</productname>
   uses strategies to express these relationships  between
d153 2
a154 2
   Defining a new set of strategies is beyond the scope of this discussion,
   but we'll explain how <acronym>B-tree</acronym> strategies work because
d156 6
a161 4
   <filename>pg_am</filename> table, the amstrategies column is the
   number of strategies defined for this access method. For
   <acronym>B-tree</acronym>s, this number is 5.  These strategies
   correspond to
d163 1
a163 1
   <table tocentry="1">
a196 1
  </para>
d199 2
a200 2
   The idea is that you'll need to add operators corresponding to the
   comparisons above to the <filename>pg_amop</filename> relation (see below).
d202 1
a202 1
   type, to figure out how to partition the <acronym>B-tree</acronym>,
d205 2
a206 2
   operators for <filename>int2, int4, oid,</filename> and every other
   data type on which a <acronym>B-tree</acronym> can operate.
d208 4
d216 1
a216 1
   routines in order to work. For example, the <acronym>B-tree</acronym>
d219 1
a219 1
   <acronym>R-tree</acronym> access method must be able to compute
d229 8
a236 13
   <filename>pg_am</filename> includes a column called
   <filename>amsupport</filename>.  This column records the number of
   support routines used by an access method.  For <acronym>B-tree</acronym>s,
   this number is one -- the routine to take two keys and return -1, 0, or
   +1, depending on whether the first key is less than, equal
   to, or greater than the second.

   <note>
    <para>
     Strictly  speaking, this routine can return a negative
     number (&lt; 0), zero, or a non-zero positive number (&gt; 0).
    </para>
   </note>
d240 8
a247 7
   The <filename>amstrategies</filename> entry in <filename>pg_am</filename>
   is just the number
   of strategies defined for the access method in question.  The operators
   for less than, less equal, and so on don't appear in
   <filename>pg_am</filename>.  Similarly, <filename>amsupport</filename>
   is just the number of support routines required by  the  access
   method.  The actual routines are listed elsewhere.
d251 1
a251 1
   By the way, the <filename>amorderstrategy</filename> entry tells whether
d253 1
a253 1
   does, <filename>amorderstrategy</filename> is the number of the strategy
d255 1
a255 1
   has <filename>amorderstrategy</filename> = 1 which is its
d258 4
d264 1
a264 1
   The next table of interest is <filename>pg_opclass</filename>.  This table
d269 1
a269 1
   <filename>oid_ops</filename>), but a separate
d271 1
a271 1
   The <filename>oid</filename> of the <filename>pg_opclass</filename> row is
d278 3
a280 3
   You need to add a row with your opclass name (for example,
   <filename>complex_abs_ops</filename>) to
   <filename>pg_opclass</filename>:
d282 1
a282 1
   <programlisting>
d299 1
a299 1
   </programlisting>
d301 1
a301 1
   Note that the oid for your <filename>pg_opclass</filename> row will
d303 1
a303 1
   from the system later just like we got the oid of the type here.
d307 5
a311 5
   The above example assumes that you want to make this new opclass the
   default B-tree opclass for the <filename>complex</filename> data type.
   If you don't, just set <filename>opcdefault</filename> to false instead.
   <filename>opckeytype</filename> is not described here; it should always
   be zero for B-tree opclasses.
d313 4
d321 2
a322 2
   defining operators was discussed earlier in  this  manual.
   For  the  <filename>complex_abs_ops</filename>  operator  class on B-trees,
d325 7
a331 7
   <programlisting>
        absolute value less-than
        absolute value less-than-or-equal
        absolute value equal
        absolute value greater-than-or-equal
        absolute value greater-than
   </programlisting>
d337 1
a337 1
   <replaceable>PGROOT</replaceable><filename>/tutorial/complex.c</filename>,
d339 2
a340 2
   <replaceable>PGROOT</replaceable><filename>/tutorial/complex.so</filename>.
  </para>
d342 1
a342 7
  <para>
   Part of the C code looks like this: (note that we will only show the
   equality operator for the rest of the examples.  The other four
   operators are very similar.  Refer to <filename>complex.c</filename>
   or <filename>complex.source</filename> for the details.)

   <programlisting>
d351 5
a355 1
   </programlisting>
d360 5
a364 6
   <programlisting>
CREATE FUNCTION complex_abs_eq(complex, complex)
              RETURNS bool
              AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
              LANGUAGE C;
   </programlisting>
d368 1
a368 2
   There are some important things that are happening here.
  </para>
d370 2
d380 1
a380 1
   we'd need to use some other operator name for complex_abs_eq.
d382 1
d384 1
d393 1
d395 1
d403 1
d405 1
d408 9
a416 6
   In practice, all operators defined as index access method strategies
   must return Boolean, since they must appear at the top level of a WHERE
   clause to be used with an index.
   (On the other
   hand, the support function returns whatever the particular access method
   expects -- in this case, a signed integer.)
d420 4
a423 4
   The final routine in the
   file is the <quote>support routine</quote> mentioned when we discussed the amsupport
   column of the <filename>pg_am</filename> table.  We will use this
   later on.  For now, ignore it.
d429 1
a429 1
   <programlisting>
d435 1
a435 1
   </programlisting>
d438 1
a438 1
   things here are the procedure names (which are the <acronym>C</acronym>
d444 1
a444 1
   cases.  These must be supplied, or the optimizer will be unable to
d450 2
a451 2
   the <filename>pg_amop</filename> relation.  To do this,
   we'll need the <filename>oid</filename>s of the operators we just
d453 1
a453 1
   two <filename>complex</filename>es, and pick ours out:
d455 5
a459 5
   <programlisting>
    SELECT o.oid AS opoid, o.oprname
     INTO TEMP TABLE complex_ops_tmp
     FROM pg_operator o, pg_type t
     WHERE o.oprleft = t.oid and o.oprright = t.oid
d471 1
a471 1
   </programlisting>
d473 1
a473 1
   (Again, some of your <filename>oid</filename> numbers will almost
d475 1
a475 1
   with <filename>oid</filename>s 277970 through 277974.  The values you
d481 1
a481 1
   Now we are ready to insert entries into <filename>pg_amop</filename> for
d486 3
a488 3
   <programlisting>
    INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
        SELECT opcl.oid, 1, false, c.opoid
d494 1
a494 1
   </programlisting>
d509 8
a516 5
   The final step is registration of the <quote>support routine</quote> previously
   described in our discussion of <filename>pg_am</filename>.  The
   <filename>oid</filename> of this support routine is stored in the
   <filename>pg_amproc</filename> table, keyed by the operator class
   <filename>oid</filename> and the support routine number.
d519 1
a519 1
   <acronym>C</acronym> code that implements this routine in the bottom of
d522 5
a526 5
   <programlisting>
    CREATE FUNCTION complex_abs_cmp(complex, complex)
     RETURNS int4
     AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
     LANGUAGE C;
d528 2
a529 2
    SELECT oid, proname FROM pg_proc
     WHERE proname = 'complex_abs_cmp';
d535 4
a538 1
   </programlisting>
d540 1
a540 1
   (Again, your <filename>oid</filename> number will probably be different.)
d543 3
a545 3
   <programlisting>
    INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
        SELECT opcl.oid, 1, p.oid
d551 1
a551 1
   </programlisting>
d556 1
a556 1
   and use B-tree indexes on <filename>complex</filename> columns.
d558 1
d560 1
a560 1
 </chapter>
@


1.20
log
@More cleanup of CREATE FUNCTION examples.
@
text
@d2 2
a3 2
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.19 2001/09/13 15:55:23 petere Exp $
Postgres documentation
d20 1
a20 1
   <productname>Postgres</productname> how to use a user-defined type and/or
d32 1
a32 1
   <productname>Postgres</productname>, but every other access method is
d124 2
a125 2
   <productname>Postgres</productname> allows the user to define operators,
   <productname>Postgres</productname> cannot look at the name of an operator
d130 1
a130 1
   on the value of a hash function.  <productname>Postgres</productname>
d133 1
a133 1
   implies that <productname>Postgres</productname> needs to know, for
d135 1
a135 1
   <acronym>B-tree</acronym>.  <productname>Postgres</productname>
d211 1
a211 1
   <productname>Postgres</productname> access methods,
d340 1
a340 1
   We make the function known to Postgres like this:
d365 1
a365 1
   Second, although Postgres can cope with operators having
d374 3
a376 3
   Third, we could have made the Postgres name of the function
   <filename>abs_eq</filename>, relying on Postgres to distinguish it
   by input data types from any other Postgres function of the same name.
d378 1
a378 1
   at the C level and Postgres level.
d487 1
a487 1
   <productname>Postgres</productname> (recall that we put the
@


1.19
log
@Replace ASCII-quotes with proper markup.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.18 2001/09/10 21:58:47 petere Exp $
d316 3
a318 1
   <filename>PGROOT/src/tutorial/complex.c</filename>.
d344 2
a345 2
              AS 'PGROOT/tutorial/obj/complex.so'
              LANGUAGE 'c';
d494 2
a495 2
     AS 'PGROOT/tutorial/obj/complex.so'
     LANGUAGE 'c';
@


1.18
log
@Markup and spell-check run over Programmer's Guide (rather incomplete still).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.17 2001/08/31 04:17:13 ishii Exp $
d126 1
a126 1
   (e.g., "&gt;" or "&lt;") and tell what kind of comparison it is.  In fact,
d134 1
a134 1
   example, that the  "&lt;="  and  "&gt;" operators partition a
d243 1
a243 1
   "less than" strategy number.
d391 1
a391 1
   file is the "support routine" mentioned when we discussed the amsupport
d466 5
a470 4
   Now do this for the other operators substituting for the "1" in the
   second line above and the "&lt;" in the last line.  Note the order:
   "less than" is 1, "less than or equal" is 2, "equal" is 3, "greater
   than or equal" is 4, and "greater than" is 5.
d479 1
a479 1
   The final step is registration of the "support routine" previously
@


1.17
log
@Add ; to the create operator.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.16 2001/08/21 16:35:59 tgl Exp $
d73 1
a73 1
       <entry>does AM support multi-column indexes?</entry>
d291 1
a291 1
   default B-tree opclass for the <filename>complex</filename> datatype.
d357 1
a357 1
   but if we were building a practical datatype we'd probably want = to
d364 1
a364 1
   the same name as long as they have different input datatypes, C can only
d367 2
a368 2
   Usually it's a good practice to include the datatype name in the C
   function name, so as not to conflict with functions for other datatypes.
d374 1
a374 1
   by input datatypes from any other Postgres function of the same name.
@


1.16
log
@Restructure pg_opclass, pg_amop, and pg_amproc per previous discussions in
pgsql-hackers.  pg_opclass now has a row for each opclass supported by each
index AM, not a row for each opclass name.  This allows pg_opclass to show
directly whether an AM supports an opclass, and furthermore makes it possible
to store additional information about an opclass that might be AM-dependent.
pg_opclass and pg_amop now store "lossy" and "haskeytype" information that we
previously expected the user to remember to provide in CREATE INDEX commands.
Lossiness is no longer an index-level property, but is associated with the
use of a particular operator in a particular index opclass.

Along the way, IndexSupportInitialize now uses the syscaches to retrieve
pg_amop and pg_amproc entries.  I find this reduces backend launch time by
about ten percent, at the cost of a couple more special cases in catcache.c's
IndexScanOK.

Initial work by Oleg Bartunov and Teodor Sigaev, further hacking by Tom Lane.

initdb forced.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.15 2001/05/17 21:50:17 petere Exp $
d404 1
a404 1
         )
@


1.15
log
@Change "indices" to "indexes", per OED.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.14 2001/03/24 23:03:26 petere Exp $
d30 2
a31 2
   The <filename>pg_am</filename> table contains one row for every user
   defined access method.  Support for the heap access method is built into
d33 1
a33 1
   described here.  The schema is
d36 1
a36 1
    <title>Index Schema</title>
d68 16
d92 2
a93 2
	method.  For example, regproc ids for opening,  closing,  and
	getting rows from the access method appear here.</entry>
d103 1
a103 1
   tables.  You  do not  need to  add a new rows to this table; all that
d105 1
a105 1
   method row you want to extend:
d143 1
a143 1
   you'll need to know that to add a new operator class. In the
d186 1
a186 1
   The idea is that you'll need to add procedures corresponding to the
d191 2
a192 2
   procedures yet; just understand that there must be a set of these
   procedures for <filename>int2, int4, oid,</filename> and every other
d198 1
a198 1
   out how to use an index.  Some access methods require other support
d204 1
a204 1
   operations do not correspond to user qualifications in
d222 1
a222 1
     number (&lt; 0), 0, or a non-zero positive number (&gt; 0).
d230 1
a230 1
   of strategies defined for the access method in question.  The procedures
d241 1
a241 1
   routine that corresponds to the ordering operator.  For example, btree
d248 14
a261 4
   exists only to associate an operator class name and perhaps a default type
   with an operator class oid. Some existing opclasses are <filename>int2_ops,
   int4_ops,</filename> and <filename>oid_ops</filename>.  You need to add a
   row with your opclass name (for example,
d263 1
a263 3
   <filename>pg_opclass</filename>.  The <filename>oid</filename> of
   this row will be a foreign key in other tables, notably
   <filename>pg_amop</filename>.
d266 7
a272 2
INSERT INTO pg_opclass (opcname, opcdeftype)
    SELECT 'complex_abs_ops', oid FROM pg_type WHERE typname = 'complex';
d274 1
a274 1
SELECT oid, opcname, opcdeftype
d278 3
a280 3
  oid   |     opcname     | opcdeftype
--------+-----------------+------------
 277975 | complex_abs_ops |     277946
d291 4
a294 8
   default index opclass for the <filename>complex</filename> datatype.
   If you don't, just insert zero into <filename>opcdeftype</filename>,
   rather than inserting the datatype's oid:

   <programlisting>
INSERT INTO pg_opclass (opcname, opcdeftype) VALUES ('complex_abs_ops', 0);
   </programlisting>

d301 1
a301 1
   For  the  <filename>complex_abs_ops</filename>  operator  class on Btrees,
d314 1
a314 1
   Suppose the code that implements the functions  defined
d316 1
a316 1
   <filename>PGROOT/src/tutorial/complex.c</filename>
d381 4
a384 1
   The access methods rely on this fact.  (On the other
d386 5
a390 1
   expects -- in this case, a signed integer.) The final routine in the
d427 1
a427 1
     INTO TABLE complex_ops_tmp
d451 4
a454 4
   Now we are ready to update <filename>pg_amop</filename> with our new
   operator class.  The most important thing in this entire discussion
   is that the operators are ordered, from less than through greater
   than, in <filename>pg_amop</filename>.  We add the rows we need:
d457 5
a461 4
    INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
        SELECT am.oid, opcl.oid, c.opoid, 1
        FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
        WHERE amname = 'btree' AND
d467 1
a467 1
   third line above and the "&lt;" in the last line.  Note the order:
d473 6
a478 1
   The next step is registration of the "support routine" previously
d481 2
a482 2
   <filename>pg_amproc</filename> table, keyed by the access method
   <filename>oid</filename> and the operator class <filename>oid</filename>.
d507 7
a513 6
    INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
        SELECT a.oid, b.oid, c.oid, 1
            FROM pg_am a, pg_opclass b, pg_proc c
            WHERE a.amname = 'btree' AND
                b.opcname = 'complex_abs_ops' AND
                c.proname = 'complex_abs_cmp';
d519 1
a519 1
   and use btree indexes on <filename>complex</filename> columns.
@


1.14
log
@minor copy editing
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.13 2001/01/13 23:58:55 petere Exp $
d7 1
a7 1
  <title>Interfacing Extensions To Indices</title>
d37 1
a37 1
    <titleabbrev>Indices</titleabbrev>
d121 1
a121 1
   operators and the way they can be used to scan indices.
@


1.13
log
@Terminology cleanup: class -> table, instance -> row, attribute -> column,
etc.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.12 2000/12/26 00:10:37 petere Exp $
d110 1
a110 1
   (eg, "&gt;" or "&lt;") and tell what kind of comparison it is.  In fact,
@


1.12
log
@Fix some cross reference links.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.11 2000/03/31 03:27:41 thomas Exp $
d30 1
a30 1
   The <filename>pg_am</filename> class contains one instance for every user
d41 1
a41 1
       <entry>Attribute</entry>
d52 1
a52 1
       <entry>object id of the owner's instance in pg_user</entry>
d77 1
a77 1
	getting instances from the access method appear here.</entry>
d85 5
a89 5
   The <acronym>object ID</acronym> of the instance in
   <filename>pg_am</filename> is used as a foreign key in lots of other
   classes.  You  don't  need to  add a new instance to this class; all
   you're interested in is the <acronym>object ID</acronym> of the access
   method instance you want to extend:
d105 1
a105 1
   The <filename>amstrategies</filename> attribute exists to standardize
d128 1
a128 1
   <filename>pg_am</filename> class, the amstrategies attribute is the
d196 2
a197 2
   <filename>pg_am</filename> includes an attribute called
   <filename>amsupport</filename>.  This attribute records the number of
d231 1
a231 1
   The next class of interest is <filename>pg_opclass</filename>.  This class
d234 2
a235 2
   int4_ops,</filename> and <filename>oid_ops</filename>.  You need to add an
   instance with your opclass name (for example,
d238 1
a238 1
   this instance will be a foreign key in other classes, notably
d255 1
a255 1
   Note that the oid for your <filename>pg_opclass</filename> instance will
d360 1
a360 1
   attribute of the <filename>pg_am</filename> class.  We will use this
d419 1
a419 1
   Now we're ready to update <filename>pg_amop</filename> with our new
d422 1
a422 1
   than, in <filename>pg_amop</filename>.  We add the instances we need:
d443 1
a443 1
   <filename>pg_amproc</filename> class, keyed by the access method
d466 1
a466 1
   We can add the new instance as follows:
@


1.11
log
@Minor markup changes. Refer to (".../catalog") in the emacs hints.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.10 2000/03/28 02:59:55 tgl Exp $
d18 1
a18 1
   <xref endterm="EXTEND-CATALOGS" linkend="EXTEND-CATALOGS">.
@


1.10
log
@Oops, missed some < and > that need to be &lt; and &gt; ...
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.9 2000/03/28 02:53:02 tgl Exp $
d487 1
a487 1
mode: sgml
d497 1
a497 1
sgml-local-catalogs:"/usr/lib/sgml/catalog"
@


1.9
log
@Clean up major bogosity in description of creating a new index operator
class.  This chapter was apparently sewed together from several
inconsistent examples... and perhaps from old docs that no longer
apply at all.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.8 2000/02/17 03:39:39 tgl Exp $
d110 1
a110 1
   (eg, ">" or "<") and tell what kind of comparison it is.  In fact,
d118 1
a118 1
   example, that the  "<="  and  ">" operators partition a
d206 1
a206 1
     number (< 0), 0, or a non-zero positive number (> 0).
d430 1
a430 1
            c.oprname = '<';
d434 1
a434 1
   third line above and the "<" in the last line.  Note the order:
@


1.8
log
@Finish repairing 6.5's problems with r-tree indexes: create appropriate
selectivity functions and make the r-tree operators use them.  The
estimation functions themselves are just stubs, unfortunately, but
perhaps someday someone will make them compute realistic estimates.
Change pg_am so that the optimizer can reliably tell the difference
between ordered and unordered indexes --- before it would think that
an r-tree index can be scanned in '<<' order, which is not right AFAIK.
Repair broken negator links for network_sup and related ops.
Initdb forced.  This might be my last initdb force for 7.0 ... hope so
anyway ...
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.7 2000/01/24 07:16:49 tgl Exp $
d94 4
a97 5
         +----+
         |oid |
         +----+
         |403 |
         +----+
d212 2
a213 1
   The <filename>amstrategies</filename> entry in pg_am is just the number
d231 6
a236 6
   The next class of interest is pg_opclass.  This class exists only to
   associate a name and default type with an oid.  In pg_amop, every
   <acronym>B-tree</acronym> operator class has a set of procedures, one
   through five, above. Some existing opclasses are <filename>int2_ops,
    int4_ops, and oid_ops</filename>.  You need to add an instance with your
   opclass name (for example, <filename>complex_abs_ops</filename>) to
d238 2
a239 1
   this instance is a foreign key in other classes.
d243 1
a243 1
    SELECT 'complex_abs_ops', oid FROM pg_type WHERE typname = 'complex_abs';
d249 4
a252 5
         +------+-----------------+------------+
         |oid   | opcname         | opcdeftype |
         +------+-----------------+------------+
         |17314 | complex_abs_ops |      29058 |
         +------+-----------------+------------+
d261 12
d274 1
a274 1
   We  still  need  a  set of operators; the procedure for
d276 1
a276 1
   For  the  complex_abs_ops  operator  class on Btrees,
d295 1
a295 1
   Part of the code look like this: (note that we will only show the
d313 7
a319 1
   There are a couple of important things that are happening below.
d323 1
a323 15
   First, note that operators for less-than, less-than-or equal, equal,
   greater-than-or-equal, and greater-than for <filename>int4</filename>
   are being defined.  All of these operators are already defined for
   <filename>int4</filename> under the names &lt;, &lt;=, =, &gt;=,
   and &gt;. The new operators behave differently, of course.  In order
   to guarantee that <productname>Postgres</productname> uses these
   new operators rather than the old ones, they need to be named differently
   from the old ones.  This is a key point: you can overload operators in
   <productname>Postgres</productname>, but only if the operator isn't
   already defined for the argument types.  That is, if you have &lt;
   defined for (int4, int4), you can't define it again.
   <productname>Postgres</productname> does not check this when you define
   your operator, so be careful.  To avoid this problem, odd names will be
   used for the operators.  If you get this wrong, the access methods
   are likely to crash when you try to do scans.
d327 8
a334 7
   The other important point is that all the operator functions return
   Boolean values.  The access methods rely on this fact.  (On the other
   hand, the support function returns whatever the particular access method
   expects -- in this case, a signed integer.) The final routine in the
   file is the "support routine" mentioned when we discussed the amsupport
   attribute of the <filename>pg_am</filename> class.  We will use this
   later on.  For now, ignore it.
d338 6
a343 6
   <programlisting>
CREATE FUNCTION complex_abs_eq(complex_abs, complex_abs)
              RETURNS bool
              AS 'PGROOT/tutorial/obj/complex.so'
              LANGUAGE 'c';
   </programlisting>
d347 6
a352 15
   Now define the operators that use them.  As noted, the operator names
   must be unique among all operators that take two <filename>int4</filename>
   operands.  In order to see if the operator names listed below are taken,
   we can do a query  on <filename>pg_operator</filename>:

   <programlisting>
    /*
     * this query uses the regular expression operator (~)
     * to find three-character operator names that end in
     * the character &amp;
     */
    SELECT *
     FROM pg_operator
     WHERE oprname ~ '^..&amp;$'::text;
   </programlisting>
d354 8
d365 1
a365 8
   to see if your name is taken for the types you want.  The important
   things here are the procedure (which are the <acronym>C</acronym>
   functions defined above) and the restriction and join selectivity
   functions.  You should just use the ones used below--note that there
   are different such functions for the less-than, equal, and greater-than
   cases.  These must be supplied, or the access method will crash when it
   tries to use the operator.  You should copy the names for restrict and
   join, but use the procedure names you defined in the last step.
d369 1
a369 1
     leftarg = complex_abs, rightarg = complex_abs,
a373 1
  </para>
d375 9
a383 3
  <para>
   Notice that five operators corresponding to less,  less equal, equal,
   greater, and greater equal are defined.
d387 3
a389 38
   We're just about finished. the last thing we need to do is to update
   the <filename>pg_amop</filename> relation.  To do this, we need the
   following attributes:

   <table tocentry="1">
    <title><filename>pg_amproc</filename> Schema</title>
    <titleabbrev><filename>pg_amproc</filename></titleabbrev>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>Attribute</entry>
       <entry>Description</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>amopid</entry>
       <entry>the <filename>oid</filename> of the <filename>pg_am</filename> instance
	for  B-tree (== 403, see above)</entry>
      </row>
      <row>
       <entry>amopclaid</entry>
       <entry>the <filename>oid</filename> of the
	<filename>pg_opclass</filename>  instance for <filename>complex_abs_ops</filename>
	(== whatever you got instead  of <filename>17314</filename>, see above)</entry>
      </row>
      <row>
       <entry>amopopr</entry>
       <entry>the <filename>oid</filename>s of the  operators  for the opclass
	(which we'll get in just a minute)</entry>
      </row>
     </tbody>
    </tgroup>
   </table>
  </para>

  <para>
   So we need the <filename>oid</filename>s of the operators we just
d398 1
a398 1
      and t.typname = 'complex_abs';
d400 9
a408 13
         +------+---------+
         |oid   | oprname |
         +------+---------+
         |17321 | &lt;       |
         +------+---------+
         |17322 | &lt;=      |
         +------+---------+
         |17323 |  =      |
         +------+---------+
         |17324 | &gt;=      |
         +------+---------+
         |17325 | &gt;       |
         +------+---------+
d413 1
a413 1
   with <filename>oid</filename>s 17321 through 17325.  The values you
d421 2
a422 2
   is that the operators are ordered, from less equal through greater
   equal, in <filename>pg_amop</filename>.  We add the instances we need:
d427 1
a427 1
        FROM pg_am am, pg_opclass opcl, complex_abs_ops_tmp c
d459 4
a462 5
         +------+-----------------+
         |oid   | proname         |
         +------+-----------------+
         |17328 | complex_abs_cmp |
         +------+-----------------+
d465 1
a465 2
   (Again, your <filename>oid</filename> number will probably be different
   and you should substitute the value you see for the value below.)
d479 2
a480 70
   Now we need to add a hashing strategy to allow the type to be indexed.
   We do this by using another type in pg_am but we reuse the same ops.

   <programlisting>
    INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
        SELECT am.oid, opcl.oid, c.opoid, 1
        FROM pg_am am, pg_opclass opcl, complex_abs_ops_tmp c
        WHERE amname = 'hash' AND
            opcname = 'complex_abs_ops' AND
            c.oprname = '=';
   </programlisting>
  </para>

  <para>
   In order to use this index in a where clause, we need to modify the
   <filename>pg_operator</filename> class as follows.

   <programlisting>
    UPDATE pg_operator
        SET oprrest = 'eqsel'::regproc, oprjoin = 'eqjoinsel'
        WHERE oprname = '=' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'neqsel'::regproc, oprjoin = 'neqjoinsel'
        WHERE oprname = '<filename>' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'neqsel'::regproc, oprjoin = 'neqjoinsel'
        WHERE oprname = '<filename>' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'scalarltsel'::regproc, oprjoin = 'scalarltjoinsel'
        WHERE oprname = '<' AND 
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'scalarltsel'::regproc, oprjoin = 'scalarltjoinsel'
        WHERE oprname = '<=' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'scalargtsel'::regproc, oprjoin = 'scalargtjoinsel'
        WHERE oprname = '>' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');
    
    UPDATE pg_operator
        SET oprrest = 'scalargtsel'::regproc, oprjoin = 'scalargtjoinsel'
        WHERE oprname = '>=' AND
            oprleft = oprright AND
            oprleft = (SELECT oid FROM pg_type WHERE typname = 'complex_abs');</filename></filename>
   </programlisting> 
  </para>

  <para>
   And last (Finally!) we register a description of this type.

   <programlisting>
    INSERT INTO pg_description (objoid, description) 
    SELECT oid, 'Two part G/L account'
	    FROM pg_type WHERE typname = 'complex_abs';
   </programlisting> 
@


1.7
log
@First cut at making useful selectivity estimates for range queries
(ie, WHERE x > lowbound AND x < highbound).  It's not very bright yet
but it does something useful.  Also, rename intltsel/intgtsel to
scalarltsel/scalargtsel to reflect usage better.  Extend convert_to_scalar
to do something a little bit useful with string data types.  Still need
to make it do something with date/time datatypes, but I'll wait for
Thomas's datetime unification dust to settle first.  Eventually the
routine ought not have any type-specific knowledge at all; it ought to
be calling a type-dependent routine found via a pg_type column; but
that's a task for another day.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.6 2000/01/22 23:50:08 tgl Exp $
a54 4
       <entry>amkind</entry>
       <entry>not used at present, but set to 'o' as a place holder</entry>
      </row>
      <row>
d63 5
d219 9
@


1.6
log
@Revise handling of index-type-specific indexscan cost estimation, per
pghackers discussion of 5-Jan-2000.  The amopselect and amopnpages
estimators are gone, and in their place is a per-AM amcostestimate
procedure (linked to from pg_am, not pg_amop).
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.5 1999/07/22 15:11:05 thomas Exp $
d545 1
a545 1
        SET oprrest = 'intltsel'::regproc, oprjoin = 'intltjoinsel'
d551 1
a551 1
        SET oprrest = 'intltsel'::regproc, oprjoin = 'intltjoinsel'
d557 1
a557 1
        SET oprrest = 'intgtsel'::regproc, oprjoin = 'intgtjoinsel'
d563 1
a563 1
        SET oprrest = 'intgtsel'::regproc, oprjoin = 'intgtjoinsel'
@


1.5
log
@Complete merge of all old man page information.
lisp.sgml is a placeholder for Eric Marsden's upcoming contribution.
catalogs.sgml is not yet marked up or integrated.
 It should perhaps become an appendix.
@
text
@d2 1
a2 1
$Header$
a405 4
      <row>
       <entry>amopselect, amopnpages</entry>
       <entry>cost functions</entry>
      </row>
a408 7

   The cost functions are used by the query optimizer to decide whether or
   not to use a given index in a scan.  Fortunately, these already exist.
   The two functions we'll use are <filename>btreesel</filename>, which
   estimates the selectivity of the <acronym>B-tree</acronym>, and
   <filename>btreenpage</filename>, which estimates the number of pages a
   search will touch in the tree.
d452 2
a453 4
    INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
                amopselect, amopnpages) 
        SELECT am.oid, opcl.oid, c.opoid, 1,
                'btreesel'::regproc, 'btreenpage'::regproc
d509 1
a509 1
   We do this by using another type in pg_am but we reuse the sames ops.
d512 2
a513 4
    INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
                amopselect, amopnpages)
        SELECT am.oid, opcl.oid, c.opoid, 1,
                'hashsel'::regproc, 'hashnpage'::regproc
@


1.4
log
@Significant update from Vince Vielhaber.
@
text
@d1 5
@


1.3
log
@Clean up to ensure tag completion as required by the newest versions
 of Norm's Modular Style Sheets and jade/docbook.
From Vince Vielhaber <vev@@michvhf.com>.
@
text
@d1 2
a2 2
<Chapter Id="xindex">
<Title>Interfacing Extensions To Indices</Title>
d4 80
a83 79
<Para>
     The procedures described thus far let you define a  new
     type,  new  functions  and  new operators.  However, we
     cannot yet define a secondary index (such as a  <Acronym>B-tree</Acronym>,
     <Acronym>R-tree</Acronym>  or  hash  access method) over a new type or its
     operators.
</Para>

<Para>
     Look back at
<XRef LinkEnd="EXTEND-CATALOGS" EndTerm="EXTEND-CATALOGS">.
     The right half shows the  catalogs  
     that we must modify in order to tell <ProductName>Postgres</ProductName> how
     to use a user-defined type and/or  user-defined  operators 
     with an index (i.e., <FileName>pg_am, pg_amop, pg_amproc</FileName> and
     <FileName>pg_opclass</FileName>).  Unfortunately, there is no simple command
     to  do  this.   We will demonstrate how to modify these
     catalogs through a  running  example:  a  new  operator
     class  for the <Acronym>B-tree</Acronym> access method that sorts integers
     in ascending absolute value order.
</Para>

<Para>
     The <FileName>pg_am</FileName> class contains one instance for  every  user
     defined  access  method.   Support  for the heap access
     method is built into <ProductName>Postgres</ProductName>, but every  other  access
     method is described here.  The schema is

<TABLE TOCENTRY="1">
<Title>Index Schema</Title>
<TitleAbbrev>Indices</TitleAbbrev>
<TGroup Cols="2">
<THead>
<Row>
  <Entry>Attribute</Entry>
  <Entry>Description</Entry>
</Row>
</THead>
<TBody>
<Row>
  <Entry>amname</Entry>
  <Entry>name of the access method</Entry>
</Row>
<Row>
<Entry>amowner</Entry>
<Entry>object id of the owner's instance in pg_user</Entry>
</Row>
<Row>
<Entry>amkind</Entry>
<Entry>not used at present, but set to 'o' as a place holder</Entry>
</Row>
<Row>
<Entry>amstrategies</Entry>
<Entry>number of strategies for this access method (see below)</Entry>
</Row>
<Row>
<Entry>amsupport</Entry>
<Entry>number of support routines for this access method (see below)</Entry>
</Row>
<Row>
<Entry>amgettuple
    aminsert
    ...</Entry>

<Entry>procedure  identifiers  for  interface routines to the access
    method.  For example, regproc ids for opening,  closing,  and
    getting instances from the access method appear here. </Entry>
</Row>
</TBody>
</TGroup>
</TABLE>
</Para>

<Para>
     The  <Acronym>object  ID</Acronym>  of  the instance in <FileName>pg_am</FileName> is used as a
     foreign key in lots of other classes.  You  don't  need
     to  add a new instance to this class; all you're interested in 
     is the <Acronym>object ID</Acronym> of the access method instance
     you want to extend:
d85 1
a85 1
<ProgramListing>
d93 1
a93 2
</ProgramListing>
</Para>
d95 133
a227 123
<Para>
     The  <FileName>amstrategies</FileName>  attribute exists to standardize 
     comparisons  across  data  types.   For  example,  <Acronym>B-tree</Acronym>s
     impose  a  strict  ordering on keys, lesser to greater.
     Since <ProductName>Postgres</ProductName> allows the  user  to  define  operators,
     <ProductName>Postgres</ProductName>  cannot look at the name of an operator (eg, ">"
     or "<") and tell what kind of comparison it is.  In fact,
     some  access  methods don't impose any ordering at all.
     For example, <Acronym>R-tree</Acronym>s  express  a  rectangle-containment
     relationship, whereas a hashed data structure expresses
     only bitwise similarity based on the value  of  a  hash
     function.  <ProductName>Postgres</ProductName> needs some consistent way of taking
     a qualification in your query, looking at the  operator
     and  then  deciding  if  a  usable  index exists.  This
     implies that <ProductName>Postgres</ProductName> needs to know, for example,  that
     the  "<="  and  ">" operators partition a <Acronym>B-tree</Acronym>.  <ProductName>Postgres</ProductName>
     uses strategies to express these relationships  between
     operators and the way they can be used to scan indices.
</Para>

<Para>
     Defining a new set of strategies is beyond the scope of
     this  discussion,  but we'll explain how <Acronym>B-tree</Acronym> strategies 
     work because you'll need to know that to add a new
     operator  class.   In the <FileName>pg_am</FileName> class, the amstrategies
     attribute is the number of strategies defined for  this
     access  method.   For <Acronym>B-tree</Acronym>s, this number is 5.  These
     strategies correspond to

<TABLE TOCENTRY="1">
<Title>B-tree Strategies</Title>
<TitleAbbrev>B-tree</TitleAbbrev>
<TGroup Cols="2">
<THead>
<Row>
<Entry>Operation</Entry>
<Entry>Index</Entry>
</Row>
</THead>
<TBody>
<Row>
<Entry>less than</Entry>
<Entry>1</Entry>
</Row>
<Row>
<Entry>less than or equal</Entry>
<Entry>2</Entry>
</Row>
<Row>
<Entry>equal</Entry>
<Entry>3</Entry>
</Row>
<Row>
<Entry>greater than or equal</Entry>
<Entry>4</Entry>
</Row>
<Row>
<Entry>greater than</Entry>
<Entry>5</Entry>
</Row>
</TBody>
</TGroup>
</TABLE>
</Para>

<Para>
     The idea is that you'll need to add  procedures  corresponding  
     to the comparisons above to the <FileName>pg_amop</FileName> relation 
     (see below).  The access method code can use these
     strategy  numbers,  regardless  of data type, to figure
     out how to partition the <Acronym>B-tree</Acronym>,  compute  selectivity,
     and  so  on.   Don't  worry about the details of adding
     procedures yet; just understand that there  must  be  a
     set  of these procedures for <FileName>int2, int4, oid,</FileName> and every
     other data type on which a <Acronym>B-tree</Acronym> can operate.

     Sometimes, strategies aren't enough information for the
     system  to figure out how to use an index.  Some access
     methods require other  support  routines  in  order  to
     work.   For  example,  the <Acronym>B-tree</Acronym> access method must be
     able to compare two keys and determine whether  one  is
     greater  than, equal to, or less than the other.  
     Similarly, the <Acronym>R-tree</Acronym> access method must be able to compute
     intersections,  unions, and sizes of rectangles.  These
     operations do not correspond to user qualifications  in
     SQL  queries;  they are administrative routines used by
     the access methods, internally.
</Para>

<Para>
     In order to manage  diverse  support  routines  
     consistently   across  all  <ProductName>Postgres</ProductName>  access  methods,  <FileName>pg_am</FileName>
     includes an attribute called <FileName>amsupport</FileName>.  This attribute
     records  the  number  of  support  routines  used by an
     access method.  For <Acronym>B-tree</Acronym>s, this number is one --  the
     routine  to  take  two  keys  and  return -1, 0, or +1,
     depending on whether the first key is less than,  equal
     to, or greater than the second.
<Note>
<Para>
Strictly  speaking, this routine can return a negative
number (< 0), 0, or a non-zero positive number (> 0).
</Para>
</Note>
</para>
<Para>
     The <FileName>amstrategies</FileName> entry in pg_am is just the  number  of
     strategies  defined  for the access method in question.
     The procedures for less than, less  equal,  and  so  on
     don't  appear  in  <FileName>pg_am</FileName>.  Similarly, <FileName>amsupport</FileName> is just
     the number of support routines required by  the  access
     method.  The actual routines are listed elsewhere.
</Para>

<Para>
     The  next  class of interest is pg_opclass.  This class
     exists only to  associate  a  name  with  an  oid.   In
     pg_amop,  every <Acronym>B-tree</Acronym> operator class has a set of 
     procedures,  one  through  five,  above.   Some   existing
     opclasses  are  <FileName>int2_ops,  int4_ops,  and oid_ops</FileName>.  You
     need to add an instance with  your  opclass  name  (for
     example,  <FileName>complex_abs_ops</FileName>)  to  <FileName>pg_opclass</FileName>.  The <FileName>oid</FileName> of
     this instance is a foreign key in other classes.
d229 1
a229 4
<ProgramListing>
INSERT INTO pg_opclass (opcname) VALUES ('complex_abs_ops');

SELECT oid, opcname
d233 18
a250 18
         +------+--------------+
         |oid   | opcname      |
         +------+--------------+
         |17314 | int4_abs_ops |
         +------+--------------+
</ProgramListing>

     Note that the oid for your <FileName>pg_opclass</FileName> instance will  be
     different!   You should substitute your value for 17314
     wherever it appears in this discussion.
</Para>

<Para>
     So now we have an access method and an operator  class.
     We  still  need  a  set of operators; the procedure for
     defining operators was discussed earlier in  this  manual.   
     For  the  complex_abs_ops  operator  class on Btrees, 
     the operators we require are:
d252 1
a252 1
<ProgramListing>
d258 2
a259 2
</ProgramListing>
</Para>
d261 11
a271 11
<Para>
     Suppose the code that implements the functions  defined
     is stored in the file
<FileName>PGROOT/src/tutorial/complex.c</FileName>
</Para>

<Para>
     Part  of  the  code  look like this: (note that we will
     only show the equality operator for  the  rest  of  the
     examples.  The  other  four operators are very similar.
     Refer to <FileName>complex.c</FileName> or <FileName>complex.sql</FileName> for the details.)
d273 1
a273 1
<ProgramListing>
d282 2
a283 2
</ProgramListing>
</Para>
d285 35
a319 38
<Para>
     There are a couple of important things that are happening below.
</Para>

<Para>
     First, note that operators for less-than, less-than-or
     equal, equal, greater-than-or-equal,  and  greater-than
     for <FileName>int4</FileName> are being defined.  All of these operators are
     already defined for <FileName>int4</FileName> under the names &lt;, &lt;=, =,  &gt;=,
     and  &gt;.   The  new  operators  behave  differently,  of
     course.  In order to guarantee that <ProductName>Postgres</ProductName> uses these
     new operators rather than the old ones, they need to be
     named differently from the old ones.   This  is  a  key
     point: you can overload operators in <ProductName>Postgres</ProductName>, but only
     if the operator isn't already defined for the  argument
     types.   That  is,  if  you  have  &lt; defined for (int4,
     int4), you can't define it again.   <ProductName>Postgres</ProductName>  does  not
     check  this  when you define your operator, so be careful.  
     To avoid this problem, odd names will be used for
     the operators.  If you get this wrong, the access methods 
     are likely to crash when you try to do scans.
</Para>

<Para>
     The other important point  is  that  all  the  operator
     functions  return  Boolean  values.  The access methods
     rely on this fact.  (On the  other  hand,  the  support
     function  returns whatever the particular access method
     expects -- in this case, a signed integer.)
     The final routine in the file is the "support  routine"
     mentioned  when we discussed the amsupport attribute of
     the <FileName>pg_am</FileName> class.  We will use this later on.  For  now,
     ignore it.
</Para>

<Para>
<ProgramListing>
CREATE FUNCTION complex_abs_eq(complex, complex)
d323 2
a324 2
</ProgramListing>
</Para>
d326 5
a330 6
<Para>
     Now  define the operators that use them.  As noted, the
     operator names must be unique among all operators  that
     take  two <FileName>int4</FileName> operands.  In order to see if the 
     operator names listed below are taken, we can do a query  on
     <FileName>pg_operator</FileName>:
d332 1
a332 1
<ProgramListing>
d341 1
a341 1
</ProgramListing>
d343 1
a343 1
</Para>
d345 9
a353 11
<Para>
     to  see  if  your name is taken for the types you want.
     The important things here are the procedure (which  are
     the  <Acronym>C</Acronym> functions defined above) and the restriction and
     join selectivity functions.  You should  just  use  the
     ones  used  below--note  that  there are different such
     functions for the less-than,  equal,  and  greater-than
     cases.   These  must  be supplied, or the access method
     will crash when it tries  to  use  the  operator.   You
     should  copy  the  names for restrict and join, but use
     the procedure names you defined in the last step.
d355 1
a355 1
<ProgramListing>
d357 1
a357 1
     leftarg = complex, rightarg = complex,
d361 2
a362 60
</ProgramListing>
</Para>

<Para>
     Notice that five operators corresponding to less,  less
     equal, equal, greater, and greater equal are defined.
</Para>

<Para>
     We're just about finished. the last thing we need to do
     is to update the <FileName>pg_amop</FileName> relation.  To do this, we need
     the following attributes:
     
<TABLE TOCENTRY="1">
<Title><FileName>pg_amproc</FileName> Schema</Title>
<TitleAbbrev><FileName>pg_amproc</FileName></TitleAbbrev>
<TGroup Cols="2">
<THead>
<Row>
<Entry>Attribute</Entry>
<Entry>Description</Entry>
</Row>
</THead>
<TBody>
<Row>
<Entry>amopid</Entry>
<Entry>the <FileName>oid</FileName> of the <FileName>pg_am</FileName> instance
 for  B-tree (== 403, see above)</Entry>
</Row>
<Row>
<Entry>amopclaid</Entry>
<Entry>the <FileName>oid</FileName> of the 
<FileName>pg_opclass</FileName>  instance for <FileName>int4_abs_ops</FileName>
 (== whatever you got instead  of <FileName>17314</FileName>, see above)</Entry>
</Row>
<Row>
<Entry>amopopr</Entry>
<Entry>the <FileName>oid</FileName>s of the  operators  for the opclass
  (which we'll get in just a minute)</Entry>
</Row>
<Row>
<Entry>amopselect, amopnpages</Entry>
<Entry>cost functions</Entry>
</Row>
</TBody>
</TGroup>
</TABLE>

     The cost functions are used by the query  optimizer  to
     decide  whether  or not to use a given index in a scan.
     Fortunately, these already exist.   The  two  functions
     we'll use are <FileName>btreesel</FileName>, which estimates the selectivity
     of the <Acronym>B-tree</Acronym>, and <FileName>btreenpage</FileName>, which estimates the 
     number of pages a search will touch in the tree.
</Para>

<Para>
     So  we  need the <FileName>oid</FileName>s of the operators we just defined.
     We'll look up the names of all the operators that  take
     two <FileName>int4</FileName>s, and pick ours out:
d364 59
a422 1
<ProgramListing>
d427 1
a427 1
      and t.typname = 'complex';
d442 1
a442 1
</ProgramListing>
d444 40
a483 41
     (Again,  some of your <FileName>oid</FileName> numbers will almost certainly
     be different.)  The operators we are interested in  are
     those  with  <FileName>oid</FileName>s  17321 through 17325.  The values you
     get will probably be different, and you should  
     substitute  them  for  the  values below.  We can look at the
     operator names and pick out the ones we just added.
</Para>

<Para>
     Now we're ready to update <FileName>pg_amop</FileName> with our new operator
     class.  The most important thing in this entire 
     discussion is that the operators are ordered, from less equal
     through   greater   equal,  in  <FileName>pg_amop</FileName>.   We  add  the
     instances we need:

<ProgramListing>
    INSERT INTO pg_amop (amopid, amopclaid,
     amopopr, amopstrategy,
     amopselect, amopnpages)
    SELECT am.oid, opcl.oid, c.opoid, 3,
     'btreesel'::regproc, 'btreenpage'::regproc
    FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
    WHERE amname = 'btree'
     and opcname = 'complex_abs_ops'
     and c.oprname = '=';
</ProgramListing>

     Note the order: "less than" is 1, "less than or  equal"
     is  2,  "equal" is 3, "greater than or equal" is 4, and
     "greater than" is 5.
</Para>

<Para>
     The last step (finally!) is registration of  the  
     "support routine" previously described in our discussion of
     <FileName>pg_am</FileName>.  The <FileName>oid</FileName> of this support routine  is  stored  in
     the <FileName>pg_amproc</FileName> class, keyed by the access method <FileName>oid</FileName> and
     the operator class <FileName>oid</FileName>.  First, we need to register the
     function  in  <ProductName>Postgres</ProductName>  (recall  that we put the <Acronym>C</Acronym> code
     that implements this routine in the bottom of the  file
     in which we implemented the operator routines):
d485 2
a486 2
<ProgramListing>
    CREATE FUNCTION int4_abs_cmp(int4, int4)
d492 1
a492 1
     WHERE prname = 'int4_abs_cmp';
d494 10
a503 12
         +------+--------------+
         |oid   | proname      |
         +------+--------------+
         |17328 | int4_abs_cmp |
         +------+--------------+
</ProgramListing>

     (Again,  your <FileName>oid</FileName> number will probably be different and
     you should substitute the value you see for  the  value
     below.)   Recalling  that  the <Acronym>B-tree</Acronym> instance's oid is
     403 and that of <FileName>int4_abs_ops</FileName> is 17314, we can  add  the
     new instance as follows:
d505 1
a505 1
<ProgramListing>
d507 101
a607 7
     VALUES ('403'::oid, -- btree oid
     '17314'::oid,       --  pg_opclass tuple
     '17328'::oid,       -- new pg_proc oid
     '1'::int2);
</ProgramListing>
</Para>
</Chapter>
@


1.2
log
@Add id field to chapter and book tags to allow output file names
 to be meaningful.
@
text
@d199 1
a199 1

@


1.1
log
@SGML source for new documentation.
@
text
@d1 1
a1 1
<Chapter>
@
