Movatterモバイル変換


[0]ホーム

URL:



Facebook
Postgres Pro
Facebook
Downloads
54.4. Foreign Data Wrapper Query Planning
Prev UpChapter 54. Writing A Foreign Data WrapperHome Next

54.4. Foreign Data Wrapper Query Planning

The FDW callback functionsGetForeignRelSize,GetForeignPaths,GetForeignPlan,PlanForeignModify, andGetForeignJoinPaths must fit into the workings of thePostgres Pro planner. Here are some notes about what they must do.

The information inroot andbaserel can be used to reduce the amount of information that has to be fetched from the foreign table (and therefore reduce the cost).baserel->baserestrictinfo is particularly interesting, as it contains restriction quals (WHERE clauses) that should be used to filter the rows to be fetched. (The FDW itself is not required to enforce these quals, as the core executor can check them instead.)baserel->reltargetlist can be used to determine which columns need to be fetched; but note that it only lists columns that have to be emitted by theForeignScan plan node, not columns that are used in qual evaluation but not output by the query.

Various private fields are available for the FDW planning functions to keep information in. Generally, whatever you store in FDW private fields should be palloc'd, so that it will be reclaimed at the end of planning.

baserel->fdw_private is avoid pointer that is available for FDW planning functions to store information relevant to the particular foreign table. The core planner does not touch it except to initialize it to NULL when theRelOptInfo node is created. It is useful for passing information forward fromGetForeignRelSize toGetForeignPaths and/orGetForeignPaths toGetForeignPlan, thereby avoiding recalculation.

GetForeignPaths can identify the meaning of different access paths by storing private information in thefdw_private field ofForeignPath nodes.fdw_private is declared as aList pointer, but could actually contain anything since the core planner does not touch it. However, best practice is to use a representation that's dumpable bynodeToString, for use with debugging support available in the backend.

GetForeignPlan can examine thefdw_private field of the selectedForeignPath node, and can generatefdw_exprs andfdw_private lists to be placed in theForeignScan plan node, where they will be available at execution time. Both of these lists must be represented in a form thatcopyObject knows how to copy. Thefdw_private list has no other restrictions and is not interpreted by the core backend in any way. Thefdw_exprs list, if not NIL, is expected to contain expression trees that are intended to be executed at run time. These trees will undergo post-processing by the planner to make them fully executable.

InGetForeignPlan, generally the passed-in target list can be copied into the plan node as-is. The passedscan_clauses list contains the same clauses asbaserel->baserestrictinfo, but may be re-ordered for better execution efficiency. In simple cases the FDW can just stripRestrictInfo nodes from thescan_clauses list (usingextract_actual_clauses) and put all the clauses into the plan node's qual list, which means that all the clauses will be checked by the executor at run time. More complex FDWs may be able to check some of the clauses internally, in which case those clauses can be removed from the plan node's qual list so that the executor doesn't waste time rechecking them.

As an example, the FDW might identify some restriction clauses of the formforeign_variable=sub_expression, which it determines can be executed on the remote server given the locally-evaluated value of thesub_expression. The actual identification of such a clause should happen duringGetForeignPaths, since it would affect the cost estimate for the path. The path'sfdw_private field would probably include a pointer to the identified clause'sRestrictInfo node. ThenGetForeignPlan would remove that clause fromscan_clauses, but add thesub_expression tofdw_exprs to ensure that it gets massaged into executable form. It would probably also put control information into the plan node'sfdw_private field to tell the execution functions what to do at run time. The query transmitted to the remote server would involve something likeWHEREforeign_variable = $1, with the parameter value obtained at run time from evaluation of thefdw_exprs expression tree.

Any clauses removed from the plan node's qual list must instead be added tofdw_recheck_quals or rechecked byRecheckForeignScan in order to ensure correct behavior at theREAD COMMITTED isolation level. When a concurrent update occurs for some other table involved in the query, the executor may need to verify that all of the original quals are still satisfied for the tuple, possibly against a different set of parameter values. Usingfdw_recheck_quals is typically easier than implementing checks insideRecheckForeignScan, but this method will be insufficient when outer joins have been pushed down, since the join tuples in that case might have some fields go to NULL without rejecting the tuple entirely.

AnotherForeignScan field that can be filled by FDWs isfdw_scan_tlist, which describes the tuples returned by the FDW for this plan node. For simple foreign table scans this can be set toNIL, implying that the returned tuples have the row type declared for the foreign table. A non-NIL value must be a target list (list ofTargetEntrys) containing Vars and/or expressions representing the returned columns. This might be used, for example, to show that the FDW has omitted some columns that it noticed won't be needed for the query. Also, if the FDW can compute expressions used by the query more cheaply than can be done locally, it could add those expressions tofdw_scan_tlist. Note that join plans (created from paths made byGetForeignJoinPaths) must always supplyfdw_scan_tlist to describe the set of columns they will return.

The FDW should always construct at least one path that depends only on the table's restriction clauses. In join queries, it might also choose to construct path(s) that depend on join clauses, for exampleforeign_variable=local_variable. Such clauses will not be found inbaserel->baserestrictinfo but must be sought in the relation's join lists. A path using such a clause is called aparameterized path. It must identify the other relations used in the selected join clause(s) with a suitable value ofparam_info; useget_baserel_parampathinfo to compute that value. InGetForeignPlan, thelocal_variable portion of the join clause would be added tofdw_exprs, and then at run time the case works the same as for an ordinary restriction clause.

If an FDW supports remote joins,GetForeignJoinPaths should produceForeignPaths for potential remote joins in much the same way asGetForeignPaths works for base tables. Information about the intended join can be passed forward toGetForeignPlan in the same ways described above. However,baserestrictinfo is not relevant for join relations; instead, the relevant join clauses for a particular join are passed toGetForeignJoinPaths as a separate parameter (extra->restrictlist).

When planning anUPDATE orDELETE,PlanForeignModify can look up theRelOptInfo struct for the foreign table and make use of thebaserel->fdw_private data previously created by the scan-planning functions. However, inINSERT the target table is not scanned so there is noRelOptInfo for it. TheList returned byPlanForeignModify has the same restrictions as thefdw_private list of aForeignScan plan node, that is it must contain only structures thatcopyObject knows how to copy.

INSERT with anON CONFLICT clause does not support specifying the conflict target, as unique constraints or exclusion constraints on remote tables are not locally known. This in turn implies thatON CONFLICT DO UPDATE is not supported, since the specification is mandatory there.


Prev Up Next
54.3. Foreign Data Wrapper Helper Functions Home 54.5. Row Locking in Foreign Data Wrappers
pdfepub
Go to Postgres Pro Standard 9.5
By continuing to browse this website, you agree to the use of cookies. Go toPrivacy Policy.

[8]ページ先頭

©2009-2025 Movatter.jp