require all columns, but the
FDW could choose to optimize away returning some or all columns depending
on the contents of the <literal>RETURNING</literal> clause. Regardless, some
slot must be returned to indicate success, or the query's reported row
count will be wrong.
</para>
<para>
If the <function>ExecForeignDelete</function> pointer is set to
<literal>NULL</literal>, attempts to delete from the foreign table will fail
with an error message.
</para>
<para>
<programlisting>
void
EndForeignModify(EState *estate,
ResultRelInfo *rinfo);
</programlisting>
End the table update and release resources. It is normally not important
to release palloc'd memory, but for example open files and connections
to remote servers should be cleaned up.
</para>
<para>
If the <function>EndForeignModify</function> pointer is set to
<literal>NULL</literal>, no action is taken during executor shutdown.
</para>
<para>
Tuples inserted into a partitioned table by <command>INSERT</command> or
<command>COPY FROM</command> are routed to partitions. If an FDW
supports routable foreign-table partitions, it should also provide the
following callback functions. These functions are also called when
<command>COPY FROM</command> is executed on a foreign table.
</para>
<para>
<programlisting>
void
BeginForeignInsert(ModifyTableState *mtstate,
ResultRelInfo *rinfo);
</programlisting>
Begin executing an insert operation on a foreign table. This routine is
called right before the first tuple is inserted into the foreign table
in both cases when it is the partition chosen for tuple routing and the
target specified in a <command>COPY FROM</command> command. It should
perform any initialization needed prior to the actual insertion.
Subsequently, <function>ExecForeignInsert</function> or
<function>ExecForeignBatchInsert</function> will be called for
tuple(s) to be inserted into the foreign table.
</para>
<para>
<literal>mtstate</literal> is the overall state of the
<structname>ModifyTable</structname> plan node being executed; global data about
the plan and execution state is available via this structure.
<literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
the target foreign table. (The <structfield>ri_FdwState</structfield> field of
<structname>ResultRelInfo</structname> is available for the FDW to store any
private state it needs for this operation.)
</para>
<para>
When this is called by a <command>COPY FROM</command> command, the
plan-related global data in <literal>mtstate</literal> is not provided
and the <literal>planSlot</literal> parameter of
<function>ExecForeignInsert</function> subsequently called for each
inserted tuple is <literal>NULL</literal>, whether the foreign table is
the partition chosen for tuple routing or the target specified in the
command.
</para>
<para>
If the <function>BeginForeignInsert</function> pointer is set to
<literal>NULL</literal>, no action is taken for the initialization.
</para>
<para>
Note that if the FDW does not support routable foreign-table partitions
and/or executing <command>COPY FROM</command> on foreign tables, this
function or <function>ExecForeignInsert/ExecForeignBatchInsert</function>
subsequently called must throw error as needed.
</para>
<para>
<programlisting>
void
EndForeignInsert(EState *estate,
ResultRelInfo *rinfo);
</programlisting>
End the insert operation and release resources. It is normally not important
to release palloc'd memory, but for example open files and connections
to remote servers should be cleaned up.
</para>
<para>
If the <function>EndForeignInsert</function>