Executing Custom Scans
Executing Custom Scans
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 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.
Custom Scan Execution Callbacks
void (*BeginCustomScan) (CustomScanState *node,
EState *estate,
int eflags);
CustomScanState. Standard fields have been initialized by ExecInitCustomScan, but any private fields should be initialized here.
TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
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. 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);
void (*MarkPosCustomScan) (CustomScanState *node);
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 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);
void (*InitializeDSMCustomScan) (CustomScanState *node,
ParallelContext *pcxt,
void *coordinate);
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 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. This callback is optional, and need only be supplied if this custom scan provider supports parallel execution.
void (*ShutdownCustomScan) (CustomScanState *node);
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 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.