<literal>true</literal> is recommended.)
</para>
<para>
Note that by default, failure to acquire a row lock should result in
raising an error; returning with an empty slot is only appropriate if
the <literal>SKIP LOCKED</literal> option is specified
by <literal>erm->waitPolicy</literal>.
</para>
<para>
The <literal>rowid</literal> is the <structfield>ctid</structfield> value previously read
for the row to be re-fetched. Although the <literal>rowid</literal> value is
passed as a <type>Datum</type>, it can currently only be a <type>tid</type>. The
function API is chosen in hopes that it may be possible to allow other
data types for row IDs in future.
</para>
<para>
If the <function>RefetchForeignRow</function> pointer is set to
<literal>NULL</literal>, attempts to re-fetch rows will fail
with an error message.
</para>
<para>
See <xref linkend="fdw-row-locking"/> for more information.
</para>
<para>
<programlisting>
bool
RecheckForeignScan(ForeignScanState *node,
TupleTableSlot *slot);
</programlisting>
Recheck that a previously-returned tuple still matches the relevant
scan and join qualifiers, and possibly provide a modified version of
the tuple. For foreign data wrappers which do not perform join pushdown,
it will typically be more convenient to set this to <literal>NULL</literal> and
instead set <structfield>fdw_recheck_quals</structfield> appropriately.
When outer joins are pushed down, however, it isn't sufficient to
reapply the checks relevant to all the base tables to the result tuple,
even if all needed attributes are present, because failure to match some
qualifier might result in some attributes going to NULL, rather than in
no tuple being returned. <literal>RecheckForeignScan</literal> can recheck
qualifiers and return true if they are still satisfied and false
otherwise, but it can also store a replacement tuple into the supplied
slot.
</para>
<para>
To implement join pushdown, a foreign data wrapper will typically
construct an alternative local join plan which is used only for
rechecks; this will become the outer subplan of the
<literal>ForeignScan</literal>. When a recheck is required, this subplan
can be executed and the resulting tuple can be stored in the slot.
This plan need not be efficient since no base table will return more
than one row; for example, it may implement all joins as nested loops.
The function <literal>GetExistingLocalJoinPath</literal> may be used to search
existing paths for a suitable local join path, which can be used as the
alternative local join plan. <literal>GetExistingLocalJoinPath</literal>
searches for an unparameterized path in the path list of the specified
join relation. (If it does not find such a path, it returns NULL, in
which case a foreign data wrapper may build the local path by itself or
may choose not to create access paths for that join.)
</para>
</sect2>
<sect2 id="fdw-callbacks-explain">
<title>FDW Routines for <command>EXPLAIN</command></title>
<para>
<programlisting>
void
ExplainForeignScan(ForeignScanState *node,
ExplainState *es);
</programlisting>
Print additional <command>EXPLAIN</command> output for a foreign table scan.
This function can call <function>ExplainPropertyText</function> and
related functions to add fields to the <command>EXPLAIN</command> output.
The flag fields in <literal>es</literal> can be used to determine what to
print, and the state of the <structname>ForeignScanState</structname> node
can be inspected to provide run-time statistics in the <command>EXPLAIN
ANALYZE</command> case.
</para>
<para>
If the <function>ExplainForeignScan</function> pointer is set to
<literal>NULL</literal>,