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"字段的子结构,所以通常不需要这个回调。