which would affect the operation (row-level local triggers,
stored generated columns, or <literal>WITH CHECK OPTION</literal>
constraints from parent views), then it is possible to arrange things
so that the entire operation is performed on the remote server. The
interfaces described below make this possible.
</para>
<para>
<programlisting>
bool
PlanDirectModify(PlannerInfo *root,
ModifyTable *plan,
Index resultRelation,
int subplan_index);
</programlisting>
Decide whether it is safe to execute a direct modification
on the remote server. If so, return <literal>true</literal> after performing
planning actions needed for that. Otherwise, return <literal>false</literal>.
This optional function is called during query planning.
If this function succeeds, <function>BeginDirectModify</function>,
<function>IterateDirectModify</function> and <function>EndDirectModify</function> will
be called at the execution stage, instead. Otherwise, the table
modification will be executed using the table-updating functions
described above.
The parameters are the same as for <function>PlanForeignModify</function>.
</para>
<para>
To execute the direct modification on the remote server, this function
must rewrite the target subplan with a <structname>ForeignScan</structname> plan
node that executes the direct modification on the remote server. The
<structfield>operation</structfield> and <structfield>resultRelation</structfield> fields
of the <structname>ForeignScan</structname> must be set appropriately.
<structfield>operation</structfield> must be set to the <literal>CmdType</literal>
enumeration corresponding to the statement kind (that is,
<literal>CMD_UPDATE</literal> for <command>UPDATE</command>,
<literal>CMD_INSERT</literal> for <command>INSERT</command>, and
<literal>CMD_DELETE</literal> for <command>DELETE</command>), and the
<literal>resultRelation</literal> argument must be copied to the
<structfield>resultRelation</structfield> field.
</para>
<para>
See <xref linkend="fdw-planning"/> for additional information.
</para>
<para>
If the <function>PlanDirectModify</function> pointer is set to
<literal>NULL</literal>, no attempts to execute a direct modification on the
remote server are taken.
</para>
<para>
<programlisting>
void
BeginDirectModify(ForeignScanState *node,
int eflags);
</programlisting>
Prepare to execute a direct modification on the remote server.
This is called during executor startup. It should perform any
initialization needed prior to the direct modification (that should be
done upon the first call to <function>IterateDirectModify</function>).
The <structname>ForeignScanState</structname> node has already been created, but
its <structfield>fdw_state</structfield> field is still NULL. Information about
the table to modify is accessible through the
<structname>ForeignScanState</structname> node (in particular, from the underlying
<structname>ForeignScan</structname> plan node, which contains any FDW-private
information provided by <function>PlanDirectModify</function>).
<literal>eflags</literal> contains flag bits describing the executor's
operating mode for this plan node.
</para>
<para>
Note that when <literal>(eflags & EXEC_FLAG_EXPLAIN_ONLY)</literal> is
true, this function should not perform any externally-visible actions;
it should only do the minimum required to make the node state valid
for <function>ExplainDirectModify</function> and <function>EndDirectModify</function>.
</para>
<para>
If the <function>BeginDirectModify</function> pointer is set to
<literal>NULL</literal>, no attempts to execute a direct modification on the
remote server