PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

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

60.2.1. 自定义扫描计划回调

自定义扫描在完成的计划树中用以下结构表示:

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.c 与 subselect.c 修正的表达式树,而 custom_private 应被用来存储只由自定义扫描提供者自身使用的其他私有数据。 custom_scan_tlist 在扫描基础关系时可以为 NIL,表示自定义扫描返回与该基础关系行类型匹配的扫描元组。否则它是一个描述实际扫描元组的目标列表。对连接必须提供 custom_scan_tlist;如果自定义扫描提供者能计算某些非 Var 表达式,对扫描也可以提供。 custom_relids 由核心代码设置为该扫描节点处理的关系(范围表索引)集合;除非该扫描正在替代一个连接,否则它将只有一个成员。 methods 必须指向一个(通常是静态分配的)实现所需自定义扫描方法的对象,下文将详细说明。

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

计划树必须能用 copyObject 复制,因此存储在 “custom” 字段中的所有数据都必须由该函数能处理的节点构成。此外,自定义扫描提供者不能把 CustomScan 嵌入一个更大的结构来替代该结构本身,而 CustomPath 或 CustomScanState 是可以这样做的。

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

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

为该 CustomScan 分配一个 CustomScanState。实际分配往往比普通 CustomScanState 所需的更大,因为许多提供者会希望把它作为更大结构的第一个字段嵌入。返回的值必须正确设置节点标记与 methods,但其他字段在此阶段应保持为零;在 ExecInitCustomScan 完成基本初始化之后,会调用 BeginCustomScan 回调,给自定义扫描提供者一个机会去做其他任何需要的事情。