65.3. Extensibility

BRIN 接口具有很高的抽象度,要求访问方法实现者仅实现被访问数据类型的语义。 BRIN 层本身负责并发,记录和搜索索引结构。

使 BRIN 访问方法正常工作所需要做的就是实现一些用户定义的方法,这些方法定义了存储在索引中的摘要值的行为以及它们与扫描键的交互方式。简而言之,BRIN 将可扩展性与通用性,代码重用和干净的界面结合在一起。

BRIN 的操作员类必须提供四种方法:

  • BrinOpcInfo *opcInfo(Oid type_oid)

    • 返回有关索引列的摘要数据的内部信息。返回值必须指向具有以下定义的 palloc BrinOpcInfo
typedef struct BrinOpcInfo
{
    /* Number of columns stored in an index column of this opclass */
    uint16      oi_nstored;

    /* Opaque pointer for the opclass' private use */
    void       *oi_opaque;

    /* Type cache entries of the stored columns */
    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;

BrinOpcInfo。操作员类例程可以使用oi_opaque在索引扫描期间在支持过程之间传递信息。

  • bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey key)

    • 返回 ScanKey 是否与给定范围的索引值一致。要使用的属性编号作为扫描键的一部分传递。
  • bool addValue(BrinDesc *bdesc, BrinValues *column, Datum newval, bool isnull)

    • 给定一个索引 Tuples 和一个索引值,修改 Tuples 的指示属性,使其另外表示新值。如果对 Tuples 进行了任何修改,则返回true
  • bool unionTuples(BrinDesc *bdesc, BrinValues *a, BrinValues *b)

    • 合并两个索引 Tuples。给定两个索引 Tuples,修改它们中第一个的指示属性,使其代表两个 Tuples。第二个 Tuples 未修改。

核心发行版包括对两种类型的运算符类别的支持:minmax 和 include。使用它们的运算符类定义适用于核心数据类型。用户可以使用等效定义为其他数据类型定义其他运算符类,而无需编写任何源代码;声明适当的目录条目就足够了。请注意,有关运算符策略语义的假设已嵌入支持程序的源代码中。

如果编写了上述四个主要支持过程的实现,则实现完全不同语义的运算符类也是可能的。请注意,不能保证主要版本之间的向后兼容性:例如,更高版本中可能需要其他支持过程。

要为实现完全有序集的数据类型编写一个运算符类,可以将 minmax 支持过程与相应的运算符一起使用,如Table 65.2所示。所有操作员类别的成员(程序和操作员)都是强制性的。

表 65.2. Minmax 操作员等级的程序和支持编号

操作员班成员Object
支持程序 1内部功能brin_minmax_opcinfo()
支持程序 2内部功能brin_minmax_add_value()
支持程序 3内部功能brin_minmax_consistent()
支持程序 4内部功能brin_minmax_union()
运算符策略 1operator less-than
运算符策略 2operator less-than-or-equal-to
运算符策略 3operator equal-to
运算符策略 4operator greater-than-or-equal-to
运算符策略 5operator greater-than

要为复杂的数据类型编写一个运算符类,该值在另一种类型中包含值,可以在相应的运算符旁边使用包含支持过程,如Table 65.3所示。它只需要一个附加功能,就可以用任何语言编写。可以为更多功能定义更多功能。所有运算符都是可选的。一些运算符需要其他运算符,如对表的依赖性所示。

表 65.3. 包含运算符类别的过程和支持编号

操作员班成员ObjectDependency
支持程序 1内部功能brin_inclusion_opcinfo()
支持程序 2内部功能brin_inclusion_add_value()
支持程序 3内部功能brin_inclusion_consistent()
支持程序 4内部功能brin_inclusion_union()
支持程序 11合并两个元素的功能
支持程序 12可选功能,用于检查两个元素是否可合并
支持程序 13检查一个元素是否包含在另一个元素中的可选函数
支持程序 14可选功能,用于检查元素是否为空
运算符策略 1operator left-of运算符策略 4
运算符策略 2operator does-not-extend-to-the-right-of运算符策略 5
运算符策略 3operator overlaps
运算符策略 4operator does-not-extend-to-the-left-of运算符策略 1
运算符策略 5operator right-of运算符策略 2
运算符策略 6,18operator same-as-or-equal-to运算符策略 7
运算符策略 7,13,16,24,25operator contains-or-equal-to
运算符策略 8,14,26,27operator is-contained-by-or-equal-to运算符策略 3
运算符策略 9operator does-not-extend-above运算符策略 11
运算符策略 10operator is-below运算符策略 12
运算符策略 11operator is-above运算符策略 9
运算符策略 12operator does-not-extend-below运算符策略 10
运算符战略 20operator less-than运算符策略 5
运算符战略 21operator less-than-or-equal-to运算符策略 5
运算符战略 22operator greater-than运算符策略 1
运算符战略 23operator greater-than-or-equal-to运算符策略 1

支持过程编号 1-10 是为 BRIN 内部函数保留的,因此 SQL 级别函数以 11 开始。支持功能 11 是构建索引所需的主要功能。它应该接受与运算符类具有相同数据类型的两个参数,并返回它们的并集。如果用STORAGE参数定义,则包含运算符类可以存储具有不同数据类型的并集值。联合函数的返回值应与STORAGE数据类型匹配。

提供支持程序编号 12 和 14 以支持内置数据类型的不规则性。程序编号 12 用于支持不可合并的不同系列的网络地址。过程编号 14 用于支持空范围。过程号 13 是可选的但建议使用,它允许在将新值传递给并集函数之前对其进行检查。由于 BRIN 框架可以在不更改并集的情况下简化某些操作,因此使用此功能可以提高索引性能。

尽管 maxmax 和 include 运算符类都支持跨数据类型的运算符,但是随着这些依赖关系变得更加复杂。 minmax 运算符类要求使用两个具有相同数据类型的参数来定义完整的运算符集。通过定义额外的运算符集,它允许支持其他数据类型。包含运算符类别的运算符策略取决于Table 65.3中所示的另一个运算符策略,或与它们自己相同的运算符策略。它们要求将依赖项运算符定义为STORAGE数据类型作为左侧参数,将其他受支持的数据类型定义为所支持运算符的右侧参数。参见float4_minmax_ops作为 minmax 的示例,参见box_inclusion_ops作为包含的示例。