locking</firstterm> (as described
in <xref linkend="fdw-row-locking"/>), it must provide the following
callback functions:
</para>
<para>
<programlisting>
RowMarkType
GetForeignRowMarkType(RangeTblEntry *rte,
LockClauseStrength strength);
</programlisting>
Report which row-marking option to use for a foreign table.
<literal>rte</literal> is the <structname>RangeTblEntry</structname> node for the table
and <literal>strength</literal> describes the lock strength requested by the
relevant <literal>FOR UPDATE/SHARE</literal> clause, if any. The result must be
a member of the <literal>RowMarkType</literal> enum type.
</para>
<para>
This function is called during query planning for each foreign table that
appears in an <command>UPDATE</command>, <command>DELETE</command>, or <command>SELECT
FOR UPDATE/SHARE</command> query and is not the target of <command>UPDATE</command>
or <command>DELETE</command>.
</para>
<para>
If the <function>GetForeignRowMarkType</function> pointer is set to
<literal>NULL</literal>, the <literal>ROW_MARK_COPY</literal> option is always used.
(This implies that <function>RefetchForeignRow</function> will never be called,
so it need not be provided either.)
</para>
<para>
See <xref linkend="fdw-row-locking"/> for more information.
</para>
<para>
<programlisting>
void
RefetchForeignRow(EState *estate,
ExecRowMark *erm,
Datum rowid,
TupleTableSlot *slot,
bool *updated);
</programlisting>
Re-fetch one tuple slot from the foreign table, after locking it if required.
<literal>estate</literal> is global execution state for the query.
<literal>erm</literal> is the <structname>ExecRowMark</structname> struct describing
the target foreign table and the row lock type (if any) to acquire.
<literal>rowid</literal> identifies the tuple to be fetched.
<literal>slot</literal> contains nothing useful upon call, but can be used to
hold the returned tuple. <literal>updated</literal> is an output parameter.
</para>
<para>
This function should store the tuple into the provided slot, or clear it if
the row lock couldn't be obtained. The row lock type to acquire is
defined by <literal>erm->markType</literal>, which is the value
previously returned by <function>GetForeignRowMarkType</function>.
(<literal>ROW_MARK_REFERENCE</literal> means to just re-fetch the tuple
without acquiring any lock, and <literal>ROW_MARK_COPY</literal> will
never be seen by this routine.)
</para>
<para>
In addition, <literal>*updated</literal> should be set to <literal>true</literal>
if what was fetched was an updated version of the tuple rather than
the same version previously obtained. (If the FDW cannot be sure about
this, always returning <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.