当 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 中的公共数据(例如目标列表与扫描关系)即使没有该回调也会显示,但该回调允许显示额外的私有状态。