59.3. 执行自定义扫描

执行CustomScan时,其执行状态由CustomScanState表示,声明如下:

typedef struct CustomScanState
{
    ScanState ss;
    uint32    flags;
    const CustomExecMethods *methods;
} CustomScanState;

与其他任何扫描状态一样,初始化ss,但是如果扫描是针对联接而不是基本关系的,则ss.ss_currentRelation保留为 NULL。 flags是位掩码,其含义与CustomPathCustomScan中的含义相同。 methods必须指向实现所需的自定义扫描状态方法的(通常是静态分配的)对象,下面将对其进行详细说明。通常,不需要支持copyObjectCustomScanState实际上将是一个较大的结构,将上面的内容嵌入为它的第一个成员。

59 .3.1. 自定义扫描执行回调

void (*BeginCustomScan) (CustomScanState *node,
                         EState *estate,
                         int eflags);

完成提供的CustomScanState的初始化。标准字段已通过ExecInitCustomScan初始化,但是任何私有字段都应在此处初始化。

TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);

获取下一个扫描 Tuples。如果还有任何 Tuples,则应在当前扫描方向上用下一个 Tuples 填充ps_ResultTupleSlot,然后返回该 Tuples 插槽。如果不是,则应返回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之前调用,但最好不要依赖该 Sequences。

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中的公共数据,例如目标列表和扫描关系,但是该回调允许显示其他私有状态。