他のバージョンの文書 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

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

カスタムスキャンプロバイダは、典型的には、以下のフックを設定することでベースリレーションのためのパスを追加します。 このフックはコアのコードがそのリレーションへのすべてのアクセスパスを生成した後で呼び出されます。 (フックの呼び出しの後に作成されるギャザーパス(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を、プロジェクションを実行できるならCUSTOMPATH_SUPPORT_PROJECTIONflagsに含めます。 (CUSTOMPATH_SUPPORT_PROJECTIONが設定されていなければ、スキャンノードはスキャンされるリレーションのVarを生成するよう依頼されるだけです。一方、そのフラグが設定されていれば、スキャンノードはこのVarのスカラ式を評価できないといけません。) オプションのcustom_pathsはこのカスタムパスのノードで使用されるPathのノードのリストです。 プランナがこれをPlanのノードに変換します。 custom_privateはカスタムパスのプライベートデータを格納するために使うことができます。 プライベートデータはnodeToStringが処理できるような形式で格納してください。 そうすることで、カスタムパスを出力するデバッグルーチンが設計通りに動作します。 methodsは要求されるカスタムパスのメソッドのオブジェクト(通常は静的に割り当てられる)を指している必要があり、以下でさらに詳しく説明します。

カスタムスキャンプロバイダは結合(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;

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

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

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

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

List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
                                          List *custom_private,
                                          RelOptInfo *child_rel);

このコールバックは、指定された子リレーションchild_relの最上位の親によりパラメータ化されたパスを子リレーションによりパラメータ化されるよう変換する時に呼び出されます。 コールバックはパスを再パラメータ化したり、CustomPathの指定されたcustom_privateメンバーに保存されている式ノードを変換したりするのに使われます。 コールバックは必要に応じてreparameterize_path_by_childadjust_appendrel_attrsまたはadjust_appendrel_attrs_multilevelを使います。