9.3 9.4 9.5 9.6 10 11 12 13
阿里云PostgreSQL 问题报告 纠错本页面

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

56.2.1. 自定义扫描计划回调

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

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

void (*TextOutCustomScan) (StringInfo str,
                           const CustomScan *node);

当在此自定义计划节点调用nodeToString时,生成额外的输出。 这个回调是可选的。因为nodeToString会自动转储结构中的所有字段, 包括"custom"字段的子结构,所以通常不需要这个回调。

<
/BODY >