CustomScan
が実行されるとき、その実行状態はCustomScanState
で表現されます。
これは次のように宣言されています。
typedef struct CustomScanState { ScanState ss; uint32 flags; const CustomExecMethods *methods; } CustomScanState;
ss
は他のすべてのスキャン状態と同じく初期化されますが、スキャンがベースリレーションではなく結合を対象にしているときは例外で、ss.ss_currentRelation
はNULLのままになります。
flags
はCustomPath
およびCustomScan
と同じ意味のビットマスクです。
methods
は必要なカスタムスキャン状態のメソッドを実装するオブジェクト(通常は静的に割り当てられる)を指していなければなりません。
これについては以下で詳しく説明します。
CustomScanState
はcopyObject
をサポートしなくてもよく、典型的には上記を先頭のメンバーとして組み込んだより大きな構造体になっています。
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
に格納される共通データは、このコールバックがなくても表示されますが、このコールバックにより、追加のプライベートな状態が表示できるようになります。