カスタムスキャンプロバイダは、典型的には、以下のフックを設定することでベースリレーションのためのパスを追加します。 このフックはコアのコードがそのリレーションへのすべてのアクセスパスを生成した後で呼び出されます。 (フックの呼び出しの後に作成されるギャザーパス(Gather path)を除きます。フックが追加した部分パスをギャザーパスが利用できるようにするためです。)
typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte); extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
このフックはコアシステムが生成したパスを検査し、修正し、あるいは削除するために使うことができますが、カスタムスキャンプロバイダは、典型的にはCustomPath
オブジェクトを生成し、add_path
を使ってそれをrel
に追加することのみを行います。
カスタムスキャンプロバイダはCustomPath
オブジェクトの初期化を担当します。
このオブジェクトは以下のように宣言されています。
typedef struct CustomPath { Path path; uint32 flags; List *custom_paths; List *custom_private; const CustomPathMethods *methods; } CustomPath;
path
は、他のすべてのパスと同じく、行数の推定値、開始とトータルのコスト、このパスで提供されるソート順を含めて初期化される必要があります。
flags
はビットマスクで、カスタムパスが逆向きスキャンをサポートできるならCUSTOMPATH_SUPPORT_BACKWARD_SCAN
を、マークとリストアがサポートできるならCUSTOMPATH_SUPPORT_MARK_RESTORE
を含めます。
いずれの機能も必須ではありません。
オプションのcustom_paths
はこのカスタムパスのノードで使用されるPath
のノードのリストです。
プランナがこれをPlan
のノードに変換します。
custom_private
はカスタムパスのプライベートデータを格納するために使うことができます。
プライベートデータはnodeToString
が処理できるような形式で格納してください。
そうすることで、カスタムパスを出力するデバッグルーチンが設計通りに動作します。
methods
は要求されるカスタムパスのメソッドのオブジェクト(通常は静的に割り当てられる)を指している必要があり、現在は1つのみとなります。
カスタムスキャンプロバイダは結合(join)のパスを提供することもできます。
ベースのリレーションの場合と同様、そのようなパスは置換される結合が普通に生成したであろうものと同じ結果を生成しなければなりません。
そのために、結合のプロバイダは以下のフックをセットし、フック関数内で結合リレーション用にCustomPath
のパスを作成します。
typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
このフックは、同じ結合リレーションについて、内側あるいは外側のリレーションとの様々な組み合わせで繰り返し呼び出されます。 繰り返しの作業を最小化するのはフック側の責任です。
Plan *(*PlanCustomPath) (PlannerInfo *root, RelOptInfo *rel, CustomPath *best_path, List *tlist, List *clauses, List *custom_plans);
カスタムパスを完成した計画に変換します。
戻り値は一般的にはCustomScan
オブジェクトで、その領域はコールバックが割り当てて初期化しなければなりません。
詳しくは59.2を参照してください。