assertion-enabled
builds.
</para>
</sect2>
<sect2 id="logicaldecoding-output-plugin-callbacks">
<title>Output Plugin Callbacks</title>
<para>
An output plugin gets notified about changes that are happening via
various callbacks it needs to provide.
</para>
<para>
Concurrent transactions are decoded in commit order, and only changes
belonging to a specific transaction are decoded between
the <literal>begin</literal> and <literal>commit</literal>
callbacks. Transactions that were rolled back explicitly or implicitly
never get
decoded. Successful savepoints are
folded into the transaction containing them in the order they were
executed within that transaction. A transaction that is prepared for
a two-phase commit using <command>PREPARE TRANSACTION</command> will
also be decoded if the output plugin callbacks needed for decoding
them are provided. It is possible that the current prepared transaction
which is being decoded is aborted concurrently via a
<command>ROLLBACK PREPARED</command> command. In that case, the logical
decoding of this transaction will be aborted too. All the changes of such
a transaction are skipped once the abort is detected and the
<function>prepare_cb</function> callback is invoked. Thus even in case of
a concurrent abort, enough information is provided to the output plugin
for it to properly deal with <command>ROLLBACK PREPARED</command> once
that is decoded.
</para>
<note>
<para>
Only transactions that have already safely been flushed to disk will be
decoded. That can lead to a <command>COMMIT</command> not immediately being decoded in a
directly following <literal>pg_logical_slot_get_changes()</literal>
when <varname>synchronous_commit</varname> is set
to <literal>off</literal>.
</para>
</note>
<sect3 id="logicaldecoding-output-plugin-startup">
<title>Startup Callback</title>
<para>
The optional <function>startup_cb</function> callback is called whenever
a replication slot is created or asked to stream changes, independent
of the number of changes that are ready to be put out.
<programlisting>
typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx,
OutputPluginOptions *options,
bool is_init);
</programlisting>
The <literal>is_init</literal> parameter will be true when the
replication slot is being created and false
otherwise. <parameter>options</parameter> points to a struct of options
that output plugins can set:
<programlisting>
typedef struct OutputPluginOptions
{
OutputPluginOutputType output_type;
bool receive_rewrites;
} OutputPluginOptions;
</programlisting>
<literal>output_type</literal> has to either be set to
<literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal>
or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>. See also
<xref linkend="logicaldecoding-output-mode"/>.
If <literal>receive_rewrites</literal> is true, the output plugin will
also be called for changes made by heap rewrites during certain DDL
operations. These are of interest to plugins that handle DDL
replication, but they require special handling.
</para>
<para>
The startup callback should validate the options present in
<literal>ctx->output_plugin_options</literal>. If the output plugin
needs to have a state, it can
use <literal>ctx->output_plugin_private</literal> to store it.
</para>
</sect3>
<sect3 id="logicaldecoding-output-plugin-shutdown">
<title>Shutdown Callback</title>
<para>
The optional <function>shutdown_cb</function> callback is called
whenever a formerly active replication slot is not used anymore and can
be used to deallocate resources