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 * PRECEDINGRANGE * 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 类型intervalin_range函数。一个家族可以为其任何受支持的类型以及一个或多个 offset *类型提供in_range函数。每个in_range函数应在pg_amproc中 Importing,其中amproclefttype等于type1amprocrighttype等于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,通常会标记为严格。