他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

56.1. カスタムスキャンパスの作成

カスタムスキャンプロバイダは、典型的には、以下のフックを設定することでベースのリレーションのためのパスを追加します。 このフックはコアのコードがリレーションへの完全で正しいアクセスパスの集合であると信じるものを生成した後で呼び出されます。

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;

このフックは、同じ結合リレーションについて、内側あるいは外側のリレーションとの様々な組み合わせで繰り返し呼び出されます。 繰り返しの作業を最小化するのはフック側の責任です。

56.1.1. カスタムスキャンパスのコールバック

Plan *(*PlanCustomPath) (PlannerInfo *root,
                         RelOptInfo *rel,
                         CustomPath *best_path,
                         List *tlist,
                         List *clauses,
                         List *custom_plans);

カスタムパスを完成した計画に変換します。 戻り値は一般的にはCustomScanオブジェクトで、その領域はコールバックが割り当てて初期化しなければなりません。 詳しくは56.2. カスタムスキャン計画の作成を参照してください。

void (*TextOutCustomPath) (StringInfo str,
                           const CustomPath *node);

nodeToStringがこのカスタムパス上で呼び出されたときに、追加の出力を生成します。 このコールバックは必須ではありません。 nodeToStringは、custom_privateを含め、それが見ることができる構造体のすべてのフィールドを自動的にダンプするため、これはCustomPathが、追加フィールドを含むより大きな構造体に組み込まれている時にのみ役に立ちます。