A custom scan provider will typically add paths for a base relation by setting the following hook, which is called after the core code has generated all the access paths it can for the relation (except for Gather and Gather Merge paths, which are made after this call so that they can use partial paths added by the hook): カスタムスキャンプロバイダは、典型的には、以下のフックを設定することでベースリレーションのためのパスを追加します。 このフックはコアのコードがそのリレーションへのすべてのアクセスパスを生成した後で呼び出されます(フックが追加した部分パスを利用できるようにするためにフックの呼び出しの後に作成される、ギャザーパス(Gather path)とギャザーマージパス(Gather Merge 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;
Although this hook function can be used to examine, modify, or remove
paths generated by the core system, a custom scan provider will typically
confine itself to generating <structname>CustomPath</structname> objects and adding
them to <literal>rel</literal> using <function>add_path</function>, or
<function>add_partial_path</function> if they are partial paths. The
custom scan provider is responsible for initializing the
<structname>CustomPath</structname> object, which is declared like this:
このフックはコアシステムが生成したパスを検査し、修正し、あるいは削除するために使うことができますが、カスタムスキャンプロバイダは、典型的にはCustomPath
オブジェクトを生成し、add_path
、または、部分パスであるならadd_partial_path
を使って、それをrel
に追加することのみを行います。
カスタムスキャンプロバイダはCustomPath
オブジェクトの初期化を担当します。
このオブジェクトは以下のように宣言されています。
typedef struct CustomPath { Path path; uint32 flags; List *custom_paths; List *custom_restrictinfo; List *custom_private; const CustomPathMethods *methods; } CustomPath;
<structfield>path</structfield> must be initialized as for any other path, including
the row-count estimate, start and total cost, and sort ordering provided
by this path. <structfield>flags</structfield> is a bit mask, which
specifies whether the scan provider can support certain optional
capabilities. <structfield>flags</structfield> should include
<literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</literal> if the custom path can support
a backward scan, <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
can support mark and restore,
and <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> if it can perform
projections. (If <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> is not
set, the scan node will only be asked to produce Vars of the scanned
relation; while if that flag is set, the scan node must be able to
evaluate scalar expressions over these Vars.)
An optional <structfield>custom_paths</structfield> is a list of <structname>Path</structname>
nodes used by this custom-path node; these will be transformed into
<structname>Plan</structname> nodes by planner.
As described below, custom paths can be created for join relations as
well. In such a case, <structfield>custom_restrictinfo</structfield>
should be used to store the set of join clauses to apply to the join the
custom path replaces. Otherwise it should be NIL.
<structfield>custom_private</structfield> can be used to store the custom path's
private data. Private data should be stored in a form that can be handled
by <literal>nodeToString</literal>, so that debugging routines that attempt to
print the custom path will work as designed. <structfield>methods</structfield> must
point to a (usually statically allocated) object implementing the required
custom path methods, which are further detailed below.
path
は、他のすべてのパスと同じく、行数の推定値、開始とトータルのコスト、このパスで提供されるソート順を含めて初期化される必要があります。
flags
はビットマスクで、スキャンプロバイダが特定のオプションをサポートできるかどうかを指定します。
カスタムパスが逆向きスキャンをサポートできるならCUSTOMPATH_SUPPORT_BACKWARD_SCAN
を、マークとリストアをサポートできるならCUSTOMPATH_SUPPORT_MARK_RESTORE
を、プロジェクションを実行できるならCUSTOMPATH_SUPPORT_PROJECTION
をflags
に含めます。
(CUSTOMPATH_SUPPORT_PROJECTION
が設定されていなければ、スキャンノードはスキャンされるリレーションのVarを生成するよう依頼されるだけです。一方、そのフラグが設定されていれば、スキャンノードはこのVarのスカラ式を評価できないといけません。)
オプションのcustom_paths
はこのカスタムパスのノードで使用されるPath
のノードのリストです。
プランナがこれをPlan
のノードに変換します。
後述するように、結合リレーションに対してもカスタムパスを作成できます。
このような場合には、カスタムパスが置き換える結合に適用する結合句の集合を格納するために、custom_restrictinfo
を使用する必要があります。
それ以外の場合はNILです。
custom_private
はカスタムパスのプライベートデータを格納するために使うことができます。
プライベートデータはnodeToString
が処理できるような形式で格納してください。
そうすることで、カスタムパスを出力するデバッグルーチンが設計通りに動作します。
methods
は要求されるカスタムパスのメソッドのオブジェクト(通常は静的に割り当てられる)を指している必要があり、以下でさらに詳しく説明します。
A custom scan provider can also provide join paths. Just as for base
relations, such a path must produce the same output as would normally be
produced by the join it replaces. To do this, the join provider should
set the following hook, and then within the hook function,
create <structname>CustomPath</structname> path(s) for the join relation.
カスタムスキャンプロバイダは結合(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;
This hook will be invoked repeatedly for the same join relation, with different combinations of inner and outer relations; it is the responsibility of the hook to minimize duplicated work. このフックは、同じ結合リレーションについて、内側あるいは外側のリレーションとの様々な組み合わせで繰り返し呼び出されます。 繰り返しの作業を最小化するのはフック側の責任です。
Note also that the set of join clauses to apply to the join,
which is passed as <literal>extra->restrictlist</literal>, varies
depending on the combination of inner and outer relations. A
<structname>CustomPath</structname> path generated for the
<literal>joinrel</literal> must contain the set of join clauses it uses,
which will be used by the planner to convert the
<structname>CustomPath</structname> path into a plan, if it is selected
by the planner as the best path for the <literal>joinrel</literal>.
extra->restrictlist
として渡される結合に適用される結合句のセットは、内部と外部のリレーションの組み合わせによって異なることにも注意してください。
joinrel
に対して生成されるCustomPath
パスには、使用する結合句の集合が含まれていなければなりません。このパスをプランナがjoinrel
に対する最適パスとして選択した場合、これらはCustomPath
パスをプランに変換するためにプランナによって使用されます。
Plan *(*PlanCustomPath) (PlannerInfo *root, RelOptInfo *rel, CustomPath *best_path, List *tlist, List *clauses, List *custom_plans);
Convert a custom path to a finished plan. The return value will generally
be a <literal>CustomScan</literal> object, which the callback must allocate and
initialize. See <xref linkend="custom-scan-plan"/> for more details.
カスタムパスを完成した計画に変換します。
戻り値は一般的にはCustomScan
オブジェクトで、その領域はコールバックが割り当てて初期化しなければなりません。
詳しくは59.2を参照してください。
List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root, List *custom_private, RelOptInfo *child_rel);
This callback is called while converting a path parameterized by the
top-most parent of the given child relation <literal>child_rel</literal>
to be parameterized by the child relation. The callback is used to
reparameterize any paths or translate any expression nodes saved in the
given <literal>custom_private</literal> member of a
<structname>CustomPath</structname>. The callback may use
<literal>reparameterize_path_by_child</literal>,
<literal>adjust_appendrel_attrs</literal> or
<literal>adjust_appendrel_attrs_multilevel</literal> as required.
このコールバックは、指定された子リレーションchild_rel
の最上位の親によりパラメータ化されたパスを子リレーションによりパラメータ化されるよう変換する時に呼び出されます。
コールバックはパスを再パラメータ化したり、CustomPath
の指定されたcustom_private
メンバに保存されている式ノードを変換したりするのに使われます。
コールバックは必要に応じてreparameterize_path_by_child
、adjust_appendrel_attrs
またはadjust_appendrel_attrs_multilevel
を使います。