61.3. 执行自定义扫描#
执行CustomScan时,其执行状态由CustomScanState表示,它声明如下
typedef struct CustomScanState
{
ScanState ss;
uint32 flags;
const CustomExecMethods *methods;
} CustomScanState;ss的初始化与任何其他扫描状态类似,但如果扫描是针对联接而不是基本关系,则ss.ss_currentRelation保留为 NULL。flags是一个位掩码,其含义与CustomPath和CustomScan中的含义相同。methods必须指向实现所需自定义扫描状态方法的(通常是静态分配的)对象,这些方法将在下面进一步详细介绍。通常,不需要支持copyObject的CustomScanState实际上将是一个更大的结构,将上述内容作为其第一个成员嵌入其中。
61.3.1. 自定义扫描执行回调#
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中的常见数据(如目标列表和扫描关系)即使没有此回调也会显示,但此回调允许显示其他私有状态。
