## 59.3.执行自定义扫描 [59.3.1. 自定义扫描执行回调](custom-scan-execution.html#CUSTOM-SCAN-EXECUTION-CALLBACKS) 当`客户扫描`执行时,其执行状态由`自定义扫描状态`,声明如下: ``` typedef struct CustomScanState { ScanState ss; uint32 flags; const CustomExecMethods *methods; } CustomScanState; ``` `党卫军`与任何其他扫描状态一样初始化,但如果扫描是针对连接而不是基关系,`党卫军。ss_关系`被保留为空。`旗帜`是一个与中的含义相同的位掩码`自定义路径`和`客户扫描`.`方法`必须指向一个(通常是静态分配的)对象,该对象实现了所需的自定义扫描状态方法,下面将进一步详细介绍。通常情况下`自定义扫描状态`,不需要支持`copyObject`,实际上将是一个更大的结构,嵌入上述结构作为其第一个成员。 ### 59.3.1.自定义扫描执行回调 ``` void (*BeginCustomScan) (CustomScanState *node, EState *estate, int eflags); ``` 完成所提供数据的初始化`自定义扫描状态`.标准字段已由初始化`ExeinitCustomScan`,但任何私有字段都应在此处初始化。 ``` TupleTableSlot *(*ExecCustomScan) (CustomScanState *node); ``` 获取下一个扫描元组。如果有任何元组仍然存在,它应该填充`ps_ResultTupleSlot`使用当前扫描方向上的下一个元组,然后返回元组槽。如果不是,`无效的`或者应该返回一个空插槽。 ``` void (*EndCustomScan) (CustomScanState *node); ``` 清理与`自定义扫描状态`。此方法是必需的,但如果没有相关数据,则无需执行任何操作,否则将自动清除。 ``` void (*ReScanCustomScan) (CustomScanState *node); ``` 将当前扫描倒回到开头,准备重新扫描关系。 ``` void (*MarkPosCustomScan) (CustomScanState *node); ``` 保存当前扫描位置,以便随后可由`重新定位自定义扫描`回拨。此回调是可选的,仅当`自定义路径\u支持\u标记\u恢复`国旗升起了。 ``` void (*RestrPosCustomScan) (CustomScanState *node); ``` 将上一个扫描位置恢复为`MarkPosCustomScan`回拨。此回调是可选的,仅当`自定义路径\u支持\u标记\u恢复`国旗升起了。 ``` Size (*EstimateDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt); ``` 估计并行操作所需的动态共享内存量。这可能高于实际使用量,但不得低于实际使用量。返回值以字节为单位。此回调是可选的,仅当此自定义扫描提供程序支持并行执行时才需要提供。 ``` void (*InitializeDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt, void *coordinate); ``` 初始化并行操作所需的动态共享内存。`坐标`指向大小等于返回值的共享内存区域`估计数据扫描`。此回调是可选的,仅当此自定义扫描提供程序支持并行执行时才需要提供。 ``` void (*ReInitializeDSMCustomScan) (CustomScanState *node, ParallelContext *pcxt, void *coordinate); ``` 当要重新扫描自定义扫描计划节点时,重新初始化并行操作所需的动态共享内存。此回调是可选的,仅当此自定义扫描提供程序支持并行执行时才需要提供。建议的做法是,此回调仅重置共享状态,而`救援海关`回调只重置本地状态。当前,此回调将在之前调用`救援海关`,但最好不要依赖这种顺序。 ``` void (*InitializeWorkerCustomScan) (CustomScanState *node, shm_toc *toc, void *coordinate); ``` 根据领导者在任务期间设置的共享状态初始化并行工作程序的本地状态`初始化的SMCustomScan`。此回调是可选的,仅当此自定义扫描提供程序支持并行执行时才需要提供。 ``` void (*ShutdownCustomScan) (CustomScanState *node); ``` 当预期节点不会执行到完成时释放资源。并不是所有情况下都这样;有时`EndCustomScan`可以在没有先调用此函数的情况下调用。由于并行查询使用的DSM段在调用此回调后立即被销毁,因此希望在DSM段消失之前采取一些操作的自定义扫描提供程序应该实现此方法。 ``` void (*ExplainCustomScan) (CustomScanState *node, List *ancestors, ExplainState *es); ``` 输出附加信息`解释`自定义扫描计划节点的。此回调是可选的。存储在`扫描状态`,例如目标列表和扫描关系,即使没有此回调也会显示,但回调允许显示其他私有状态。