used by the query more cheaply than can be done locally, it could add
those expressions to <structfield>fdw_scan_tlist</structfield>. Note that join
plans (created from paths made by <function>GetForeignJoinPaths</function>) must
always supply <structfield>fdw_scan_tlist</structfield> to describe the set of
columns they will return.
</para>
<para>
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 example
<replaceable>foreign_variable</replaceable> <literal>=</literal>
<replaceable>local_variable</replaceable>. Such clauses will not be found in
<literal>baserel->baserestrictinfo</literal> but must be sought in the
relation's join lists. A path using such a clause is called a
<quote>parameterized path</quote>. It must identify the other relations
used in the selected join clause(s) with a suitable value of
<literal>param_info</literal>; use <function>get_baserel_parampathinfo</function>
to compute that value. In <function>GetForeignPlan</function>, the
<replaceable>local_variable</replaceable> portion of the join clause would be added
to <structfield>fdw_exprs</structfield>, and then at run time the case works the
same as for an ordinary restriction clause.
</para>
<para>
If an FDW supports remote joins, <function>GetForeignJoinPaths</function> should
produce <structname>ForeignPath</structname>s for potential remote joins in much
the same way as <function>GetForeignPaths</function> works for base tables.
Information about the intended join can be passed forward
to <function>GetForeignPlan</function> in the same ways described above.
However, <structfield>baserestrictinfo</structfield> is not relevant for join
relations; instead, the relevant join clauses for a particular join are
passed to <function>GetForeignJoinPaths</function> as a separate parameter
(<literal>extra->restrictlist</literal>).
</para>
<para>
An FDW might additionally support direct execution of some plan actions
that are above the level of scans and joins, such as grouping or
aggregation. To offer such options, the FDW should generate paths and
insert them into the appropriate <firstterm>upper relation</firstterm>. For
example, a path representing remote aggregation should be inserted into
the <literal>UPPERREL_GROUP_AGG</literal> relation, using <function>add_path</function>.
This path will be compared on a cost basis with local aggregation
performed by reading a simple scan path for the foreign relation (note
that such a path must also be supplied, else there will be an error at
plan time). If the remote-aggregation path wins, which it usually would,
it will be converted into a plan in the usual way, by
calling <function>GetForeignPlan</function>. The recommended place to generate
such paths is in the <function>GetForeignUpperPaths</function>
callback function, which is called for each upper relation (i.e., each
post-scan/join processing step), if all the base relations of the query
come from the same FDW.
</para>
<para>
<function>PlanForeignModify</function> and the other callbacks described in
<xref linkend="fdw-callbacks-update"/> are designed around the assumption
that the foreign relation will be scanned in the usual way and then
individual row updates will be driven by a local <literal>ModifyTable</literal>
plan node. This approach is necessary for the general case where an
update requires reading local tables as well as foreign tables.
However, if the operation could be executed entirely by the foreign
server, the FDW could generate a path representing that and insert it
into the <literal>UPPERREL_FINAL</literal>