2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5

60.2. 创建自定义扫描计划 #

自定义扫描在最终的计划树中表示为以下结构

typedef struct CustomScan
{
    Scan      scan;
    uint32    flags;
    List     *custom_plans;
    List     *custom_exprs;
    List     *custom_private;
    List     *custom_scan_tlist;
    Bitmapset *custom_relids;
    const CustomScanMethods *methods;
} CustomScan;

scan 必须像任何其他扫描一样进行初始化,包括估算成本、目标列表、限定条件等。flags 是一个位掩码,其含义与 CustomPath 中的相同。custom_plans 可用于存储子 Plan 节点。custom_exprs 应用于存储需要由 setrefs.csubselect.c 进行修复的表达式树,而 custom_private 应用于存储仅由自定义扫描提供程序自身使用的其他私有数据。custom_scan_tlist 在扫描基表时可以为 NIL,表示自定义扫描返回的扫描元组与基表的行类型匹配。否则,它是一个描述实际扫描元组的目标列表。custom_scan_tlist 必须为连接提供,如果自定义扫描提供程序可以计算一些非 Var 表达式,也可以为扫描提供。custom_relids 由核心代码设置为该扫描节点处理的关联(范围表索引)集合;除非该扫描替换了连接,否则它将只有一个成员。methods 必须指向一个(通常是静态分配的)实现所需自定义扫描方法的对象,这些方法将在下面进一步详细说明。

CustomScan 扫描单个关系时,scan.scanrelid 必须是要扫描的表的范围表索引。当它替换连接时,scan.scanrelid 应为零。

计划树必须能够使用 copyObject 进行复制,因此存储在“custom”字段中的所有数据必须由该函数可以处理的节点组成。此外,自定义扫描提供程序不能用嵌入 CustomScan 的较大结构替换该结构本身,就像 CustomPathCustomScanState 那样。

60.2.1. 自定义扫描计划回调 #

Node *(*CreateCustomScanState) (CustomScan *cscan);

为这个 CustomScan 分配一个 CustomScanState。实际的分配通常会比普通的 CustomScanState 大,因为许多提供程序希望将其作为更大的结构的第一字段嵌入。返回值必须设置节点标签和 methods,但在此时其他字段应保留为零;在 ExecInitCustomScan 执行基本初始化后,将调用 BeginCustomScan 回调,为自定义扫描提供程序提供执行其他所需操作的机会。

提交更正

如果您在文档中看到任何不正确、与您在使用特定功能时的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。