外部データラッパのコールバックルーチン

PostgreSQL 9.1.0文書
前のページ | 巻戻し | 第 50章外部データラッパの作成 | 早送り | 次のページ

# 50.1. 外部データラッパのコールバックルーチン

FDWハンドラ関数は、以下のコールバック関数へのポインタを含む、pallocされた`FdwRoutine`構造体を返します。

    FdwPlan *
    PlanForeignScan (Oid foreigntableid,
                     PlannerInfo *root,
                     RelOptInfo *baserel);

外部テーブルへのスキャンの実行計画を作成します。 この関数はクエリの実行計画を作成するときに呼び出されます。 `foreigntableid`はその外部テーブルの`pg_class`のOIDです。 `root`はそのクエリに関するプランナのグローバル情報で、`baserel`はこのテーブルに関するプランナの情報です。 この関数は、コストの見積もりに加えて、後で外部テーブルスキャンを実行するのに必要なFDWのプライベート情報を含む、pallocされた構造体を返さなければなりません。 (プライベート情報は`copyObject`がコピー方法を知っている形式で表現されていなければならないことに注意してください。)

`root`と`baserel`に含まれる情報は、外部テーブルから取り出す情報を減らすために(結果としてコスト見積もりを減らすことに)使うことができます。 `baserel->baserestrictinfo`は、取り出す行を選別するのに使用できる制約条件(`WHERE`句)を含んでおり、特に興味深いものです。 (最終的な実行計画では制約条件を再度チェックするので、FDWでこれらの条件を適用しなければならないわけではありません。) `baserel->reltargetlist`は取り出す必要があるカラムを決定するのに使用できます。

この関数は、コスト見積もりを返すのに加えて、制約条件によるフィルタリングも考慮した、そのスキャンで返される想定行数に`baserel->rows`を更新すべきです。 `baserel->rows`の初期値は単なるデフォルトの見積もりであり、可能であれば置き換えられるべきものです。 平均行長のより良い見積もりを算出できるのであれば、この関数で`baserel->width`を更新することを選択することもできます。

    void
    ExplainForeignScan (ForeignScanState *node,
                        ExplainState *es);

外部テーブルスキャンの追加の`EXPLAIN`出力を表示します。 何も表示する必要がないのであれば、単にリターンすることもできます。 もしくは、`EXPLAIN`出力にフィールドを追加するために`ExplainPropertyText`や関連する関数を呼び出すべきです。 `es`の中のフラグフィールドは何を表示するかを決めるのに使用できます。また、`EXPLAIN ANALYZE`の場合には、実行時統計情報を提供するために`ForeignScanState`ノードの状態を調べることができます。

    void
    BeginForeignScan (ForeignScanState *node,
                      int eflags);

外部テーブルスキャンの実行を開始します。 この関数はエグゼキュータのスタートアップ中に呼び出されます。 スキャンを開始できるようになる前に、あらゆる必要な初期化を実行するべきです。 `ForeignScanState`ノードは作成されていますが、その`fdw_state`フィールドはNULLのままです。 スキャンするテーブルの情報は、`ForeignScanState`ノード(実際にはその先にある、`PlanForeignScan`から返された`FdwPlan`構造体へのポインタを含む、`ForeignScan`プランノード)を通じてアクセス可能です。

`(eflags & EXEC_FLAG_EXPLAIN_ONLY)`が真の場合、この関数は外部に見えるアクションを起こすべきではないことに注意してください。 `ExplainForeignScan`や`EndForeignScan`用にノード状態を有効にするのに必要とされる最小限のことだけをすべきです。

    TupleTableSlot *
    IterateForeignScan (ForeignScanState *node);

外部ソースから一行を取り出して、それをタプルテーブルスロットに入れて返します(この用途にはノードの`ScanTupleSlot`を使うべきです)。 利用可能な行がない場合は、NULLを返します。 タプルテーブルスロット機構を使うと、物理タプルと仮想タプルのどちらでも返せます。 ほとんどの場合、パフォーマンスの観点から後者を選ぶのが良いでしょう。 この関数は、呼出しごとにリセットされる短命なメモリコンテキスト内で呼び出されることに注意してください。 より長命なストレージが必要な場合は、`BeginForeignScan`でメモリコンテキストを作成するか、ノードの`EState`に含まれる`es_query_cxt`を使用してください。

返される行はスキャンされている外部テーブルのカラムシグネチャと一致しなければなりません。 不要なカラムを取り出さないように最適化することを選ぶなら、それらのカラム位置にNULLを入れるべきです。

    void
    ReScanForeignScan (ForeignScanState *node);

先頭からスキャンを再開します。 スキャンが依存するいずれかのパラメータが値を変更しているかもしれないので、新しいスキャンが必ずしも厳密に同じ行を返すとは限らないことに注意してください。

    void
    EndForeignScan (ForeignScanState *node);

スキャンを終了しリソースを解放します。 通常、pallocされたメモリを解放することは重要ではありませんが、開いたファイルやリモートサーバへの接続などはクリーンアップするべきです。

`FdwRoutine`と`FdwPlan`の構造体型は`src/include/foreign/fdwapi.h`で宣言されているので、さらなる詳細はそちらを見て下さい。

前のページ | ホーム | 次のページ
外部データラッパの作成 | 上に戻る | 遺伝的問い合わせ最適化