| PostgreSQL 9.5.3 文档 | |||
|---|---|---|---|
| 上一页 | 上一级 | 章 56. 编写自定义扫描提供程序 | 下一页 | 
自定义扫描在完成的计划树中使用以下结构表示:
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是可能的。
  
Node *(*CreateCustomScanState) (CustomScan *cscan);
    为该CustomScan分配CustomScanState。
    实际分配通常大于普通CustomScanState所需的分配,
    因为许多提供者希望将其嵌入为较大结构的第一个字段。
    返回的值必须正确设置节点标签和methods,
    但在此阶段其他字段应为零;在ExecInitCustomScan执行基本初始化之后,
    将调用BeginCustomScan回调,以使自定义扫描提供程序有机会执行所需的任何操作。
   
void (*TextOutCustomScan) (StringInfo str,
                           const CustomScan *node);
    当在此自定义计划节点调用nodeToString时,生成额外的输出。
    这个回调是可选的。因为nodeToString会自动转储结构中的所有字段,
    包括"custom"字段的子结构,所以通常不需要这个回调。