diff --git a/doc/src/sgml/btree.sgml b/doc/src/sgml/btree.sgml
new file mode 100644
index 0000000000..9f39edc742
--- /dev/null
+++ b/doc/src/sgml/btree.sgml
@@ -0,0 +1,267 @@
+
+
+
+B-Tree Indexes
+
+
+ index
+ B-Tree
+
+
+
+ Introduction
+
+
+ PostgreSQL includes an implementation of the
+ standard btree (multi-way binary tree) index data
+ structure. Any data type that can be sorted into a well-defined linear
+ order can be indexed by a btree index. The only limitation is that an
+ index entry cannot exceed approximately one-third of a page (after TOAST
+ compression, if applicable).
+
+
+
+ Because each btree operator class imposes a sort order on its data type,
+ btree operator classes (or, really, operator families) have come to be
+ used as PostgreSQL's general representation
+ and understanding of sorting semantics. Therefore, they've acquired
+ some features that go beyond what would be needed just to support btree
+ indexes, and parts of the system that are quite distant from the
+ btree AM make use of them.
+
+
+
+
+
+ Behavior of B-Tree Operator Classes
+
+
+ As shown in , a btree operator
+ class must provide five comparison operators,
+ <,
+ <=,
+ =,
+ >= and
+ >.
+ One might expect that <> should also be part of
+ the operator class, but it is not, because it would almost never be
+ useful to use a <> WHERE clause in an index
+ search. (For some purposes, the planner treats <>
+ as associated with a btree operator class; but it finds that operator via
+ the = operator's negator link, rather than
+ from pg_amop.)
+
+
+
+ When several data types share near-identical sorting semantics, their
+ operator classes can be grouped into an operator family. Doing so is
+ advantageous because it allows the planner to make deductions about
+ cross-type comparisons. Each operator class within the family should
+ contain the single-type operators (and associated support functions)
+ for its input data type, while cross-type comparison operators and
+ support functions are loose
in the family. It is
+ recommendable that a complete set of cross-type operators be included
+ in the family, thus ensuring that the planner can represent any
+ comparison conditions that it deduces from transitivity.
+
+
+
+ There are some basic assumptions that a btree operator family must
+ satisfy:
+
+
+
+
+
+ An = operator must be an equivalence relation; that
+ is, for all non-null values A,
+ B, C of the
+ data type:
+
+
+
+
+ A =
+ A is true
+ (reflexive law)
+
+
+
+
+ if A =
+ B,
+ then B =
+ A
+ (symmetric law)
+
+
+
+
+ if A =
+ B and B
+ = C,
+ then A =
+ C
+ (transitive law)
+
+
+
+
+
+
+
+
+ A < operator must be a strong ordering relation;
+ that is, for all non-null values A,
+ B, C:
+
+
+
+
+ A <
+ A is false
+ (irreflexive law)
+
+
+
+
+ if A <
+ B
+ and B <
+ C,
+ then A <
+ C
+ (transitive law)
+
+
+
+
+
+
+
+
+ Furthermore, the ordering is total; that is, for all non-null
+ values A, B:
+
+
+
+
+ exactly one of A <
+ B, A
+ = B, and
+ B <
+ A is true
+ (trichotomy law)
+
+
+
+
+ (The trichotomy law justifies the definition of the comparison support
+ function, of course.)
+
+
+
+
+
+ The other three operators are defined in terms of =
+ and < in the obvious way, and must act consistently
+ with them.
+
+
+
+ For an operator family supporting multiple data types, the above laws must
+ hold when A, B,
+ C are taken from any data types in the family.
+ The transitive laws are the trickiest to ensure, as in cross-type
+ situations they represent statements that the behaviors of two or three
+ different operators are consistent.
+ As an example, it would not work to put float8
+ and numeric into the same operator family, at least not with
+ the current semantics that numeric values are converted
+ to float8 for comparison to a float8. Because
+ of the limited accuracy of float8, this means there are
+ distinct numeric values that will compare equal to the
+ same float8 value, and thus the transitive law would fail.
+
+
+
+ Another requirement for a multiple-data-type family is that any implicit
+ or binary-coercion casts that are defined between data types included in
+ the operator family must not change the associated sort ordering.
+
+
+
+ It should be fairly clear why a btree index requires these laws to hold
+ within a single data type: without them there is no ordering to arrange
+ the keys with. Also, index searches using a comparison key of a
+ different data type require comparisons to behave sanely across two
+ data types. The extensions to three or more data types within a family
+ are not strictly required by the btree index mechanism itself, but the
+ planner relies on them for optimization purposes.
+
+
+
+
+
+ B-Tree Support Functions
+
+
+ As shown in , btree defines
+ one required and one optional support function.
+
+
+
+ For each combination of data types that a btree operator family provides
+ comparison operators for, it must provide a comparison support function,
+ registered in pg_amproc with support function
+ number 1 and
+ amproclefttype/amprocrighttype
+ equal to the left and right data types for the comparison (i.e., the
+ same data types that the matching operators are registered with
+ in pg_amop).
+ The comparison function must take two non-null values
+ A and B and
+ return an int32 value that
+ is < 0, 0,
+ or > 0
+ when A <
+ B, A
+ = B,
+ or A >
+ B, respectively. The function must not
+ return INT_MIN for the A
+ < B case,
+ since the value may be negated before being tested for sign. A null
+ result is disallowed, too.
+ See src/backend/access/nbtree/nbtcompare.c for
+ examples.
+
+
+
+ If the compared values are of a collatable data type, the appropriate
+ collation OID will be passed to the comparison support function, using
+ the standard PG_GET_COLLATION() mechanism.
+
+
+
+ Optionally, a btree operator family may provide sort
+ support function(s), registered under support function number
+ 2. These functions allow implementing comparisons for sorting purposes
+ in a more efficient way than naively calling the comparison support
+ function. The APIs involved in this are defined in
+ src/include/utils/sortsupport.h.
+
+
+
+
+
+ Implementation
+
+
+ An introduction to the btree index implementation can be found in
+ src/backend/access/nbtree/README.
+
+
+
+
+
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index a72c50eadb..732b8ab7d0 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -83,6 +83,7 @@
+
diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml
index 041afdbd86..054347b17d 100644
--- a/doc/src/sgml/postgres.sgml
+++ b/doc/src/sgml/postgres.sgml
@@ -252,6 +252,7 @@
&geqo;
&indexam;
&generic-wal;
+ &btree;
&gist;
&spgist;
&gin;
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
index 81c0cdc4f8..e40131473f 100644
--- a/doc/src/sgml/xindex.sgml
+++ b/doc/src/sgml/xindex.sgml
@@ -35,7 +35,7 @@
PostgreSQL, but all index methods are
described in pg_am. It is possible to add a
new index access method by writing the necessary code and
- then creating a row in pg_am — but that is
+ then creating an entry in pg_am — but that is
beyond the scope of this chapter (see ).
@@ -404,6 +404,8 @@
B-trees require a single support function, and allow a second one to be
supplied at the operator class author's option, as shown in .
+ The requirements for these support functions are explained further in
+ .
@@ -426,8 +428,8 @@
- Return the addresses of C-callable sort support function(s),
- as documented in utils/sortsupport.h (optional)
+ Return the addresses of C-callable sort support function(s)
+ (optional)
2
@@ -1056,11 +1058,8 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD
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: if A = B and B = C, then A = C
,
- and if A < B and B < C, then A < C
. Moreover, implicit
- or binary coercion casts between types represented in the operator family
- must not change the associated sort ordering. For each
+ compatibly, as is specified in detail in .
+ 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
diff --git a/src/backend/access/nbtree/README b/src/backend/access/nbtree/README
index a3f11da8d5..34f78b2f50 100644
--- a/src/backend/access/nbtree/README
+++ b/src/backend/access/nbtree/README
@@ -623,56 +623,3 @@ routines must treat it accordingly. The actual key stored in the
item is irrelevant, and need not be stored at all. This arrangement
corresponds to the fact that an L&Y non-leaf page has one more pointer
than key.
-
-Notes to Operator Class Implementors
-------------------------------------
-
-With this implementation, we require each supported combination of
-datatypes to supply us with a comparison procedure via pg_amproc.
-This procedure must take two nonnull values A and B and return an int32 < 0,
-0, or > 0 if A < B, A = B, or A > B, respectively. The procedure must
-not return INT_MIN for "A < B", since the value may be negated before
-being tested for sign. A null result is disallowed, too. See nbtcompare.c
-for examples.
-
-There are some basic assumptions that a btree operator family must satisfy:
-
-An = operator must be an equivalence relation; that is, for all non-null
-values A,B,C of the datatype:
-
- A = A is true reflexive law
- if A = B, then B = A symmetric law
- if A = B and B = C, then A = C transitive law
-
-A < operator must be a strong ordering relation; that is, for all non-null
-values A,B,C:
-
- A < A is false irreflexive law
- if A < B and B < C, then A < C transitive law
-
-Furthermore, the ordering is total; that is, for all non-null values A,B:
-
- exactly one of A < B, A = B, and B < A is true trichotomy law
-
-(The trichotomy law justifies the definition of the comparison support
-procedure, of course.)
-
-The other three operators are defined in terms of these two in the obvious way,
-and must act consistently with them.
-
-For an operator family supporting multiple datatypes, the above laws must hold
-when A,B,C are taken from any datatypes in the family. The transitive laws
-are the trickiest to ensure, as in cross-type situations they represent
-statements that the behaviors of two or three different operators are
-consistent. As an example, it would not work to put float8 and numeric into
-an opfamily, at least not with the current semantics that numerics are
-converted to float8 for comparison to a float8. Because of the limited
-accuracy of float8, this means there are distinct numeric values that will
-compare equal to the same float8 value, and thus the transitive law fails.
-
-It should be fairly clear why a btree index requires these laws to hold within
-a single datatype: without them there is no ordering to arrange the keys with.
-Also, index searches using a key of a different datatype require comparisons
-to behave sanely across two datatypes. The extensions to three or more
-datatypes within a family are not strictly required by the btree index
-mechanism itself, but the planner relies on them for optimization purposes.