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,通常会标记为严格。