On this page
63.3. B 树支持功能
如Table 38.8所示,btree 定义了一个必需的功能和两个可选的支持功能。
对于 btree 运算符系列为其提供比较运算符的数据类型的每种组合,它必须提供一个比较支持功能,该功能在pg_amproc
中注册,其支持功能编号为 1,而amproclefttype
/amprocrighttype
等于用于比较的左右数据类型(即,与匹配运算符在pg_amop
中注册的数据类型相同)。比较函数必须采用两个非空值* A
和 B
,并在 A
* <
* B
, A
* =
* B
或 A
* >
* B
*。不允许为空结果:数据类型的所有值都必须是可比较的。有关示例,请参见src/backend/access/nbtree/nbtcompare.c
。
如果比较的值是可归类的数据类型,则将使用标准的PG_GET_COLLATION()
机制将适当的归类 OID 传递给比较支持功能。
可选地,btree 运算符家族可以提供排序支持功能,这些功能在支持功能编号 2 下注册。与单纯调用比较支持功能相比,这些功能允许以更有效的方式实现用于排序目的的比较。与此相关的 API 在src/include/utils/sortsupport.h
中定义。
btree 运算符家族可以选择提供* in_range 支持功能,这些功能已在支持功能编号 3 下注册。这些功能在 btree 索引操作期间不会使用;相反,它们扩展了运算符家族的语义,以便它可以支持包含RANGE
* offset
* PRECEDING
和RANGE
* offset
* FOLLOWING
框架绑定类型的窗口子句(请参见Section 4.2.8)。从根本上讲,提供的额外信息是如何以与系列的数据排序兼容的方式添加或减去 offset
*值。
in_range
函数必须具有签名
in_range(val type1, base type1, offset type2, sub bool, less bool)
returns bool
val
和base
必须为同一类型,即操作员系列支持的一种类型(即为其提供 Order 的类型)。但是,offset
可能是其他类型,可能是该系列不支持的类型。一个示例是内置的time_ops
系列提供了具有offset
类型interval
的in_range
函数。一个家族可以为其任何受支持的类型以及一个或多个offset
*类型提供in_range
函数。每个in_range
函数应在pg_amproc
中 Importing,其中amproclefttype
等于type1
和amprocrighttype
等于type2
。
in_range
函数的基本语义取决于两个布尔标志参数。它应加或减* base
和 offset
,然后将 val
*与结果进行比较,如下所示:
如果
!
*sub
和!
*less
,则返回val
*>=
(base
*+
*offset
*)如果
!
*sub
和less
,则返回val
*<=
(*base
*+
*offset
*)如果*
sub
和!
*less
,则返回val
*>=
(base
*-
*offset
*)如果*
sub
和less
,则返回val
*<=
(*base
*-
*offset
*)
在执行此操作之前,该函数应检查* offset
*的符号:如果它小于零,请使用错误文本(例如“窗口函数中的前一个或后一个无效大小”)引发错误ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE
(22013)。 (这是 SQL 标准所必需的,尽管非标准的运算符家族可能选择忽略此限制,因为它似乎没有什么语义上的必要.)此要求委托给in_range
函数,以便核心代码无需理解对于特定的数据类型,“小于零”意味着什么。
另一个期望是,如果可行,in_range
函数应避免在* base
* +
* offset
或 base
* -
* offset
*溢出时引发错误。即使该值超出数据类型的范围,也可以确定正确的比较结果。请注意,如果数据类型包含“无穷大”或“ NaN”之类的概念,则可能需要格外小心,以确保in_range
的结果与运算符族的正常排序 Sequences 一致。
in_range
函数的结果必须与操作员系列强加的排序 Sequences 一致。确切地说,给定* offset
和 sub
*的任何固定值,则:
如果对于某些*
val1
和base
为in_range
且less
* = true,则对于具有相同*base
的每个val2
*<=
*val1
*必须为 true。如果对于某些*
val1
和base
为in_range
且less
* = true 为 false,则对于具有相同*base
的每个val2
*>=
*val1
*必须为 false。如果对于某些*
val
和base1
为in_range
且less
* = true,则对于具有相同*val
的每个base2
*>=
*base1
*必须为 true。如果对于某些*
val
和base1
为in_range
且less
* = true 为 false,则对于具有相同*val
的每个base2
*<=
*base1
*必须为 false。
当* less
* = false 时,具有相反条件的类似语句成立。
如果要排序的类型(type1
)是可排序的,则将使用标准 PG_GET_COLLATION()机制将适当的排序规则 OID 传递给in_range
函数。
in_range
函数不需要处理 NULLImporting,通常会标记为严格。