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