Postgresql 中文操作指南

61.3. Executing Custom Scans #

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

When a CustomScan is executed, its execution state is represented by a CustomScanState, which is declared as follows:

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

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

ss is initialized as for any other scan state, except that if the scan is for a join rather than a base relation, ss.ss_currentRelation is left NULL. flags is a bit mask with the same meaning as in CustomPath and CustomScan. methods must point to a (usually statically allocated) object implementing the required custom scan state methods, which are further detailed below. Typically, a CustomScanState, which need not support copyObject, will actually be a larger structure embedding the above as its first member.

61.3.1. Custom Scan Execution Callbacks #

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

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

Complete initialization of the supplied CustomScanState. Standard fields have been initialized by ExecInitCustomScan, but any private fields should be initialized here.

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

获取下一个扫描元组。如果剩下任何元组,它应使用当前扫描方向的下一个元组填充 ps_ResultTupleSlot,然后返回元组槽。如果没有,则应返回 NULL 或空槽。

Fetch the next scan tuple. If any tuples remain, it should fill ps_ResultTupleSlot with the next tuple in the current scan direction, and then return the tuple slot. If not, NULL or an empty slot should be returned.

void (*EndCustomScan) (CustomScanState *node);

清理与 CustomScanState 关联的任何私有数据。此方法是必需的,但如果不存在关联数据或将自动清理,则它不需要执行任何操作。

Clean up any private data associated with the CustomScanState. This method is required, but it does not need to do anything if there is no associated data or it will be cleaned up automatically.

void (*ReScanCustomScan) (CustomScanState *node);

将当前扫描倒回到起点,准备重新扫描关系。

Rewind the current scan to the beginning and prepare to rescan the relation.

void (*MarkPosCustomScan) (CustomScanState *node);

保存当前扫描位置,以便稍后可以通过 RestrPosCustomScan 回调恢复该位置。此回调是可选的,并且仅当设置了 CUSTOMPATH_SUPPORT_MARK_RESTORE 标志时才需要提供。

Save the current scan position so that it can subsequently be restored by the RestrPosCustomScan callback. This callback is optional, and need only be supplied if the CUSTOMPATH_SUPPORT_MARK_RESTORE flag is set.

void (*RestrPosCustomScan) (CustomScanState *node);

恢复以前由 MarkPosCustomScan 回调保存的扫描位置。此回调是可选的,并且仅当设置了 CUSTOMPATH_SUPPORT_MARK_RESTORE 标志时才需要提供。

Restore the previous scan position as saved by the MarkPosCustomScan callback. This callback is optional, and need only be supplied if the CUSTOMPATH_SUPPORT_MARK_RESTORE flag is set.

Size (*EstimateDSMCustomScan) (CustomScanState *node,
                               ParallelContext *pcxt);

估计并行操作所需的动态共享内存量。这可能高于实际使用的量,但不得低于实际使用的量。返回值以字节为单位。此回调是可选的,并且仅当此自定义扫描提供程序支持并行执行时才需要提供。

Estimate the amount of dynamic shared memory that will be required for parallel operation. This may be higher than the amount that will actually be used, but it must not be lower. The return value is in bytes. This callback is optional, and need only be supplied if this custom scan provider supports parallel execution.

void (*InitializeDSMCustomScan) (CustomScanState *node,
                                 ParallelContext *pcxt,
                                 void *coordinate);

初始化并行操作所需的动态共享内存。 coordinate 指向大小等于 EstimateDSMCustomScan 返回值共享内存区域。此回调是可选的,并且仅当此自定义扫描提供程序支持并行执行时才需要提供。

Initialize the dynamic shared memory that will be required for parallel operation. coordinate points to a shared memory area of size equal to the return value of EstimateDSMCustomScan. This callback is optional, and need only be supplied if this custom scan provider supports parallel execution.

void (*ReInitializeDSMCustomScan) (CustomScanState *node,
                                   ParallelContext *pcxt,
                                   void *coordinate);

当自定义扫描计划节点即将被重新扫描时,重新初始化并行操作所需的动态共享内存。此回调是可选的,并且仅当此自定义扫描提供程序支持并行执行时才需要提供。建议做法是此回调仅重置共享状态,而 ReScanCustomScan 回调仅重置本地状态。目前,此回调将在 ReScanCustomScan 之前调用,但最好不要依赖该顺序。

Re-initialize the dynamic shared memory required for parallel operation when the custom-scan plan node is about to be re-scanned. This callback is optional, and need only be supplied if this custom scan provider supports parallel execution. Recommended practice is that this callback reset only shared state, while the ReScanCustomScan callback resets only local state. Currently, this callback will be called before ReScanCustomScan, but it’s best not to rely on that ordering.

void (*InitializeWorkerCustomScan) (CustomScanState *node,
                                    shm_toc *toc,
                                    void *coordinate);

基于领导者在 InitializeDSMCustomScan 期间设置的共享状态,初始化并行工作进程的本地状态。此回调是可选的,并且仅当此自定义扫描提供程序支持并行执行时才需要提供。

Initialize a parallel worker’s local state based on the shared state set up by the leader during InitializeDSMCustomScan. This callback is optional, and need only be supplied if this custom scan provider supports parallel execution.

void (*ShutdownCustomScan) (CustomScanState *node);

当预见到节点无法执行到完成时,释放资源。并非在所有情况下都会调用此资源;有时,可能会在没有首先调用此函数的情况下调用 EndCustomScan。由于并行查询使用的 DSM 段在此回调被调用后立即被销毁,因此希望在 DSM 段消失前执行某些操作的自定义扫描提供程序应该实现此方法。

Release resources when it is anticipated the node will not be executed to completion. This is not called in all cases; sometimes, EndCustomScan may be called without this function having been called first. Since the DSM segment used by parallel query is destroyed just after this callback is invoked, custom scan providers that wish to take some action before the DSM segment goes away should implement this method.

void (*ExplainCustomScan) (CustomScanState *node,
                           List *ancestors,
                           ExplainState *es);

输出自定义扫描计划节点的 EXPLAIN 更多信息。此回调是可选的。存储在 ScanState 中的常用数据(例如目标列表和扫描关系)即使没有此回调也会显示,但此回调可以显示其他私有状态。

Output additional information for EXPLAIN of a custom-scan plan node. This callback is optional. Common data stored in the ScanState, such as the target list and scan relation, will be shown even without this callback, but the callback allows the display of additional, private state.