Home Explore Blog CI



postgresql

34th chunk of `doc/src/sgml/fdwhandler.sgml`
ac8238c1887d609c2c98130c9314208b9c2c9979e650dc2e0000000100000bfa
 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-&gt;parse-&gt;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"/>.
     In <function>GetForeignRowMarkType</function>, select rowmark option
     <literal>ROW_MARK_EXCLUSIVE</literal>, <literal>ROW_MARK_NOKEYEXCLUSIVE</literal>,
     <literal>ROW_MARK_SHARE</literal>, or <literal>ROW_MARK_KEYSHARE</literal> depending
     on the requested lock strength.  (The core code will act the same
     regardless of which of these four options you choose.)
     Elsewhere, you can detect whether a foreign table was specified to be
     locked by this type of command by using <function>get_plan_rowmark</function> at
     plan time, or <function>ExecFindRowMark</function> at execution time; you must
     check not only whether a non-null rowmark struct is returned, but that
     its <structfield>strength</structfield> field is not <literal>LCS_NONE</literal>.
    </para>

    <para>
     Lastly, for foreign tables that are used in an <command>UPDATE</command>,
     <command>DELETE</command> or <command>SELECT FOR UPDATE/SHARE</command> command but
     are not specified to be row-locked, you can override the default choice
     to copy entire rows by having <function>GetForeignRowMarkType</function> select
     option <literal>ROW_MARK_REFERENCE</literal> when it sees lock strength
     <literal>LCS_NONE</literal>.  This will cause <function>RefetchForeignRow</function> to
     be called with that value for <structfield>markType</structfield>; it should then
     re-fetch the row without acquiring any new lock.  (If you have
     a <function>GetForeignRowMarkType</function> function but don't wish to re-fetch
     unlocked rows, select option <literal>ROW_MARK_COPY</literal>
     for <literal>LCS_NONE</literal>.)
    </para>

    <para>
     See <filename>src/include/nodes/lockoptions.h</filename>, the comments
     for <type>RowMarkType</type> and <type>PlanRowMark</type>
     in <filename>src/include/nodes/plannodes.h</filename>, and the comments for
     <type>ExecRowMark</type> in <filename>src/include/nodes/execnodes.h</filename> for
     additional information.
    </para>

  </sect1>

 </chapter>

Title: Locking Mechanisms for Foreign Tables in UPDATE, DELETE, and SELECT FOR UPDATE/SHARE Commands
Summary
This section delves into locking strategies for foreign tables used in UPDATE, DELETE, and SELECT FOR UPDATE/SHARE commands. It explains how to implement early or late locking, and how to detect if a table is a target for these commands. It also covers how to handle row locking for SELECT FOR UPDATE/SHARE, including the selection of rowmark options. Additionally, it discusses overriding the default behavior of copying entire rows for unlocked tables by using ROW_MARK_REFERENCE and RefetchForeignRow. References to relevant header files are provided for further details.