mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Doc: move info for btree opclass implementors into main documentation.
Up to now, useful info for writing a new btree opclass has been buried in the backend's nbtree/README file. Let's move it into the SGML docs, in preparation for extending it with info about "in_range" functions in the upcoming window RANGE patch. To do this, I chose to create a new chapter for btree indexes in Part VII (Internals), parallel to the chapters that exist for the newer index AMs. This is a pretty short chapter as-is. At some point somebody might care to flesh it out with more detail about btree internals, but that is beyond the scope of my ambition for today. Discussion: https://postgr.es/m/23141.1517874668@sss.pgh.pa.us
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user