カスタムスキャンプロバイダは、典型的には、以下のフックを設定することでベースのリレーションのためのパスを追加します。 このフックはコアのコードがリレーションへの完全で正しいアクセスパスの集合であると信じるものを生成した後で呼び出されます。
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
は要求されるカスタムパスのメソッドのオブジェクト(通常は静的に割り当てられる)を指している必要があります。
メソッドは以下で詳細に説明する通り、現在は2つだけあるうちの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
オブジェクトで、その領域はコールバックが割り当てて初期化しなければなりません。
詳しくは「カスタムスキャン計画の作成」を参照してください。
void (*TextOutCustomPath) (StringInfo str, const CustomPath *node);
nodeToString
がこのカスタムパス上で呼び出されたときに、追加の出力を生成します。
このコールバックは必須ではありません。
nodeToString
は、custom_private
を含め、それが見ることができる構造体のすべてのフィールドを自動的にダンプするため、これはCustomPath
が、追加フィールドを含むより大きな構造体に組み込まれている時にのみ役に立ちます。