支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5

59.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 是可能的。

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

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

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

提交更正

如果您发现文档中有任何不正确的地方,与您使用特定功能的体验不符或需要进一步澄清,请使用此表单报告文档问题。