this is
done by including the TIDs of the non-target tables in the column list
projected through the join, and then re-fetching non-target rows when
required. This approach keeps the join data set compact, but it
requires inexpensive re-fetch capability, as well as a TID that can
uniquely identify the row version to be re-fetched. By default,
therefore, the approach used with foreign tables is to include a copy of
the entire row fetched from a foreign table in the column list projected
through the join. This puts no special demands on the FDW but can
result in reduced performance of merge and hash joins. An FDW that is
capable of meeting the re-fetch requirements can choose to do it the
first way.
</para>
<para>
For an <command>UPDATE</command> or <command>DELETE</command> on a foreign table, it
is recommended that the <literal>ForeignScan</literal> operation on the target
table perform early locking on the rows that it fetches, perhaps via the
equivalent of <command>SELECT FOR UPDATE</command>. An FDW can detect whether
a table is an <command>UPDATE</command>/<command>DELETE</command> target at plan time
by comparing its relid to <literal>root->parse->resultRelation</literal>,
or at execution time by using <function>ExecRelationIsTargetRelation()</function>.
An alternative possibility is to perform late locking within the
<function>ExecForeignUpdate</function> or <function>ExecForeignDelete</function>
callback, but no special support is provided for this.
</para>
<para>
For foreign tables that are specified to be locked by a <command>SELECT
FOR UPDATE/SHARE</command> command, the <literal>ForeignScan</literal> operation can
again perform early locking by fetching tuples with the equivalent
of <command>SELECT FOR UPDATE/SHARE</command>. To perform late locking
instead, provide the callback functions defined
in <xref linkend="fdw-callbacks-row-locking"/>.