自定义扫描在最终的计划树中表示为以下结构
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
回调,为自定义扫描提供程序提供执行其他所需操作的机会。
如果您在文档中看到任何不正确、与您在使用特定功能时的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。