If a <structname>ForeignPath</structname> path is chosen for the join, it will
represent the entire join process; paths generated for the component
tables and subsidiary joins will not be used. Subsequent processing of
the join path proceeds much as it does for a path scanning a single
foreign table. One difference is that the <structfield>scanrelid</structfield> of
the resulting <structname>ForeignScan</structname> plan node should be set to zero,
since there is no single relation that it represents; instead,
the <structfield>fs_relids</structfield> field of the <structname>ForeignScan</structname>
node represents the set of relations that were joined. (The latter field
is set up automatically by the core planner code, and need not be filled
by the FDW.) Another difference is that, because the column list for a
remote join cannot be found from the system catalogs, the FDW must
fill <structfield>fdw_scan_tlist</structfield> with an appropriate list
of <structfield>TargetEntry</structfield> nodes, representing the set of columns
it will supply at run time in the tuples it returns.
</para>
<note>
<para>
Beginning with <productname>PostgreSQL</productname> 16,
<structfield>fs_relids</structfield> includes the rangetable indexes
of outer joins, if any were involved in this join. The new field
<structfield>fs_base_relids</structfield> includes only base
relation indexes, and thus
mimics <structfield>fs_relids</structfield>'s old semantics.
</para>
</note>
<para>
See <xref linkend="fdw-planning"/> for additional information.
</para>
</sect2>
<sect2 id="fdw-callbacks-upper-planning">
<title>FDW Routines for Planning Post-Scan/Join Processing</title>
<para>
If an FDW supports performing remote post-scan/join processing, such as
remote aggregation, it should provide this callback function:
</para>
<para>
<programlisting>
void
GetForeignUpperPaths(PlannerInfo *root,
UpperRelationKind stage,
RelOptInfo *input_rel,
RelOptInfo *output_rel,
void *extra);
</programlisting>
Create possible access paths for <firstterm>upper relation</firstterm> processing,
which is the planner's term for all post-scan/join query processing, such
as aggregation, window functions, sorting, and table updates. This
optional function is called during query planning. Currently, it is
called only if all base relation(s) involved in the query belong to the
same FDW. This function should generate <structname>ForeignPath</structname>
path(s) for any post-scan/join processing that the FDW knows how to
perform remotely
(use <function>create_foreign_upper_path</function> to build them),
and call <function>add_path</function> to add these paths to
the indicated upper relation. As with <function>GetForeignJoinPaths</function>,
it is not necessary that this function succeed in creating any paths,
since paths involving local processing are always possible.
</para>
<para>
The <literal>stage</literal> parameter identifies which post-scan/join step is
currently being considered. <literal>output_rel</literal> is the upper relation
that should receive paths representing computation of this step,
and <literal>input_rel</literal> is the relation representing the input to this
step. The <literal>extra</literal> parameter provides additional details,
currently, it is set only for <literal>UPPERREL_PARTIAL_GROUP_AGG</literal>
or <literal>UPPERREL_GROUP_AGG</literal>, in which case it points to a
<literal>GroupPathExtraData</literal> structure;
or for <literal>UPPERREL_FINAL</literal>, in which case it points to a
<literal>FinalPathExtraData</literal> structure.
(Note that <structname>ForeignPath</structname>