在执行一个CustomScan
时,它的执行状态由一个CustomScanState
表示,其定义如下:
typedef struct CustomScanState { ScanState ss; uint32 flags; const CustomExecMethods *methods; } CustomScanState;
ss
和任何其他扫描状态一样被初始化,不过如果该扫描是用于连接而不是基本关系,则ss.ss_currentRelation
会被留成 NULL。flags
是一个位掩码,它的含义与CustomPath
和CustomScan
中的一样。methods
必须指向一个实现了所需自定义扫描状态方法的对象(通常是静态分配的),将进一步在下文详细介绍。通常一个CustomScanState
(不需要支持copyObject
)实际将是一个较大的结构,上面的结构将嵌入在其中作为第一个成员。
void (*BeginCustomScan) (CustomScanState *node, EState *estate, int eflags);
完成所提供的CustomScanState
的初始化。标准的域已经被ExecInitCustomScan
初始化,但是任何私有的域应该在这里被初始化。
TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
取下一个扫描元组。如果还有任何元组剩余,它应该用当前扫描方向的下一个元组填充ps_ResultTupleSlot
,并且接着返回该元组槽。如果没有,则用NULL
填充或者返回一个空槽。
void (*EndCustomScan) (CustomScanState *node);
清除任何与CustomScanState
相关的私有数据。这个方法是必需的,但是如果没有相关的数据或者相关数据将被自动清除,则它不需要做任何事情。
void (*ReScanCustomScan) (CustomScanState *node);
把当前扫描倒回到开始处,并且准备重新扫描该关系。
void (*MarkPosCustomScan) (CustomScanState *node);
保存当前的扫描位置,这样可以在以后由RestrPosCustomScan
回调函数恢复。这个回调函数是可选的,只有在CUSTOMPATH_SUPPORT_MARK_RESTORE
标志被设置时才需要提供。
void (*RestrPosCustomScan) (CustomScanState *node);
恢复由MarkPosCustomScan
回调函数保存的扫描位置。这个回调函数是可选的,只有在CUSTOMPATH_SUPPORT_MARK_RESTORE
标志被设置时才需要提供。
Size (*EstimateDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt);
估计并行操作所需要的动态共享内存的数量。这可能会比实际使用的量更大,但是绝不能更低。返回值的单位是字节。这个回调是可选的,只有在这个自定义扫描提供者支持并行执行时才必须提供这个回调。
void (*InitializeDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt, void *coordinate);
初始化并行操作所需的动态共享内存,coordinate
指向一块共享内存区域,其尺寸等于EstimateDSMCustomScan
的返回值。这个回调是可选的,只有在这个自定义扫描提供者支持并行执行时才必须提供这个回调。
void (*ReInitializeDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt, void *coordinate);
在将要重新扫描自定义扫描计划节点时,重新初始化并行操作所需的动态共享内存。这个回调是可选的,并且仅当自定义扫描提供者支持并行执行时才需要提供。建议的规程是这个回调仅重置共享状态,而ReScanCustomScan
回调仅重置本地状态。当前,这个回调将在ReScanCustomScan
之前被调用,但最好不要依赖这一顺序。
void (*InitializeWorkerCustomScan) (CustomScanState *node, shm_toc *toc, void *coordinate);
基于领导者在InitializeDSMCustomScan
期间建立的共享状态初始化一个并行工作者的本地状态。这个回调是可选的,并且仅当自定义扫描提供者支持并行执行时才需要提供。
void (*ShutdownCustomScan) (CustomScanState *node);
在节点不会被执行到结束时释放资源。并非所有的情况都会调用这个回调,有时候会在没有先调用这个函数之前调用EndCustomScan
。由于并行查询所使用的DSM段会在这个回调被调用之后销毁,所以希望在DSM段消失前采取某些行动的自定义扫描提供者应该是先这个方法。
void (*ExplainCustomScan) (CustomScanState *node, List *ancestors, ExplainState *es);
为一个自定义扫描计划节点的EXPLAIN
输出额外的信息。这个回调函数是可选的。即使没有这个回调函数,被存储在ScanState
中的公共的数据(例如目标列表和扫描关系)也将被显示,但是该回调函数允许显示额外的信息(例如私有状态)。