ReorderBufferChange *change);
</programlisting>
</para>
</sect3>
<sect3 id="logicaldecoding-output-plugin-stream-message">
<title>Stream Message Callback</title>
<para>
The optional <function>stream_message_cb</function> callback is called when
sending a generic message in a block of streamed changes (demarcated by
<function>stream_start_cb</function> and <function>stream_stop_cb</function> calls).
The message contents for transactional messages are not displayed as the transaction
can abort at a later point in time and we don't decode changes for aborted
transactions.
<programlisting>
typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx,
ReorderBufferTXN *txn,
XLogRecPtr message_lsn,
bool transactional,
const char *prefix,
Size message_size,
const char *message);
</programlisting>
</para>
</sect3>
<sect3 id="logicaldecoding-output-plugin-stream-truncate">
<title>Stream Truncate Callback</title>
<para>
The optional <function>stream_truncate_cb</function> callback is called
for a <command>TRUNCATE</command> command in a block of streamed changes
(demarcated by <function>stream_start_cb</function> and
<function>stream_stop_cb</function> calls).
<programlisting>
typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx,
ReorderBufferTXN *txn,
int nrelations,
Relation relations[],
ReorderBufferChange *change);
</programlisting>
The parameters are analogous to the <function>stream_change_cb</function>
callback. However, because <command>TRUNCATE</command> actions on
tables connected by foreign keys need to be executed together, this
callback receives an array of relations instead of just a single one.
See the description of the <xref linkend="sql-truncate"/> statement for
details.
</para>
</sect3>
</sect2>
<sect2 id="logicaldecoding-output-plugin-output">
<title>Functions for Producing Output</title>
<para>
To actually produce output, output plugins can write data to
the <literal>StringInfo</literal> output buffer
in <literal>ctx->out</literal> when inside
the <function>begin_cb</function>, <function>commit_cb</function>,
or <function>change_cb</function> callbacks. Before writing to the output
buffer, <function>OutputPluginPrepareWrite(ctx, last_write)</function> has
to be called, and after finishing writing to the
buffer, <function>OutputPluginWrite(ctx, last_write)</function> has to be
called to perform the write. The <parameter>last_write</parameter>
indicates whether a particular write was the callback's last write.
</para>
<para>
The following example shows how to output data to the consumer of an
output plugin:
<programlisting>
OutputPluginPrepareWrite(ctx, true);
appendStringInfo(ctx->out, "BEGIN %u", txn->xid);
OutputPluginWrite(ctx, true);
</programlisting>
</para>
</sect2>
</sect1>
<sect1 id="logicaldecoding-writer">
<title>Logical Decoding Output Writers</title>
<para>
It is possible to add more output methods for logical decoding.
For details, see
<filename>src/backend/replication/logical/logicalfuncs.c</filename>.
Essentially, three functions need to be provided: one to read WAL, one to
prepare writing output, and one to write the output
(see <xref linkend="logicaldecoding-output-plugin-output"/>).
</para>
</sect1>
<sect1 id="logicaldecoding-synchronous">