summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/html/logicaldecoding-output-plugin.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/html/logicaldecoding-output-plugin.html')
-rw-r--r--doc/src/sgml/html/logicaldecoding-output-plugin.html471
1 files changed, 471 insertions, 0 deletions
diff --git a/doc/src/sgml/html/logicaldecoding-output-plugin.html b/doc/src/sgml/html/logicaldecoding-output-plugin.html
new file mode 100644
index 0000000..c800931
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-output-plugin.html
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.6. Logical Decoding Output Plugins</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding" /><link rel="next" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.6. Logical Decoding Output Plugins</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-OUTPUT-PLUGIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.6. Logical Decoding Output Plugins</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-INIT">49.6.1. Initialization Function</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES">49.6.2. Capabilities</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE">49.6.3. Output Modes</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS">49.6.4. Output Plugin Callbacks</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT">49.6.5. Functions for Producing Output</a></span></dt></dl></div><p>
+ An example output plugin can be found in the
+ <a class="link" href="test-decoding.html" title="F.45. test_decoding">
+ <code class="filename">contrib/test_decoding</code>
+ </a>
+ subdirectory of the PostgreSQL source tree.
+ </p><div class="sect2" id="LOGICALDECODING-OUTPUT-INIT"><div class="titlepage"><div><div><h3 class="title">49.6.1. Initialization Function</h3></div></div></div><a id="id-1.8.14.12.3.2" class="indexterm"></a><p>
+ An output plugin is loaded by dynamically loading a shared library with
+ the output plugin's name as the library base name. The normal library
+ search path is used to locate the library. To provide the required output
+ plugin callbacks and to indicate that the library is actually an output
+ plugin it needs to provide a function named
+ <code class="function">_PG_output_plugin_init</code>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions.
+</p><pre class="programlisting">
+typedef struct OutputPluginCallbacks
+{
+ LogicalDecodeStartupCB startup_cb;
+ LogicalDecodeBeginCB begin_cb;
+ LogicalDecodeChangeCB change_cb;
+ LogicalDecodeTruncateCB truncate_cb;
+ LogicalDecodeCommitCB commit_cb;
+ LogicalDecodeMessageCB message_cb;
+ LogicalDecodeFilterByOriginCB filter_by_origin_cb;
+ LogicalDecodeShutdownCB shutdown_cb;
+ LogicalDecodeFilterPrepareCB filter_prepare_cb;
+ LogicalDecodeBeginPrepareCB begin_prepare_cb;
+ LogicalDecodePrepareCB prepare_cb;
+ LogicalDecodeCommitPreparedCB commit_prepared_cb;
+ LogicalDecodeRollbackPreparedCB rollback_prepared_cb;
+ LogicalDecodeStreamStartCB stream_start_cb;
+ LogicalDecodeStreamStopCB stream_stop_cb;
+ LogicalDecodeStreamAbortCB stream_abort_cb;
+ LogicalDecodeStreamPrepareCB stream_prepare_cb;
+ LogicalDecodeStreamCommitCB stream_commit_cb;
+ LogicalDecodeStreamChangeCB stream_change_cb;
+ LogicalDecodeStreamMessageCB stream_message_cb;
+ LogicalDecodeStreamTruncateCB stream_truncate_cb;
+} OutputPluginCallbacks;
+
+typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb);
+</pre><p>
+ The <code class="function">begin_cb</code>, <code class="function">change_cb</code>
+ and <code class="function">commit_cb</code> callbacks are required,
+ while <code class="function">startup_cb</code>,
+ <code class="function">filter_by_origin_cb</code>, <code class="function">truncate_cb</code>,
+ and <code class="function">shutdown_cb</code> are optional.
+ If <code class="function">truncate_cb</code> is not set but a
+ <code class="command">TRUNCATE</code> is to be decoded, the action will be ignored.
+ </p><p>
+ An output plugin may also define functions to support streaming of large,
+ in-progress transactions. The <code class="function">stream_start_cb</code>,
+ <code class="function">stream_stop_cb</code>, <code class="function">stream_abort_cb</code>,
+ <code class="function">stream_commit_cb</code>, <code class="function">stream_change_cb</code>,
+ and <code class="function">stream_prepare_cb</code>
+ are required, while <code class="function">stream_message_cb</code> and
+ <code class="function">stream_truncate_cb</code> are optional.
+ </p><p>
+ An output plugin may also define functions to support two-phase commits,
+ which allows actions to be decoded on the <code class="command">PREPARE TRANSACTION</code>.
+ The <code class="function">begin_prepare_cb</code>, <code class="function">prepare_cb</code>,
+ <code class="function">stream_prepare_cb</code>,
+ <code class="function">commit_prepared_cb</code> and <code class="function">rollback_prepared_cb</code>
+ callbacks are required, while <code class="function">filter_prepare_cb</code> is optional.
+ </p></div><div class="sect2" id="LOGICALDECODING-CAPABILITIES"><div class="titlepage"><div><div><h3 class="title">49.6.2. Capabilities</h3></div></div></div><p>
+ To decode, format and output changes, output plugins can use most of the
+ backend's normal infrastructure, including calling output functions. Read
+ only access to relations is permitted as long as only relations are
+ accessed that either have been created by <code class="command">initdb</code> in
+ the <code class="literal">pg_catalog</code> schema, or have been marked as user
+ provided catalog tables using
+</p><pre class="programlisting">
+ALTER TABLE user_catalog_table SET (user_catalog_table = true);
+CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
+</pre><p>
+ Note that access to user catalog tables or regular system catalog tables
+ in the output plugins has to be done via the <code class="literal">systable_*</code>
+ scan APIs only. Access via the <code class="literal">heap_*</code> scan APIs will
+ error out. Additionally, any actions leading to transaction ID assignment
+ are prohibited. That, among others, includes writing to tables, performing
+ DDL changes, and calling <code class="literal">pg_current_xact_id()</code>.
+ </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-MODE"><div class="titlepage"><div><div><h3 class="title">49.6.3. Output Modes</h3></div></div></div><p>
+ Output plugin callbacks can pass data to the consumer in nearly arbitrary
+ formats. For some use cases, like viewing the changes via SQL, returning
+ data in a data type that can contain arbitrary data (e.g., <code class="type">bytea</code>) is
+ cumbersome. If the output plugin only outputs textual data in the
+ server's encoding, it can declare that by
+ setting <code class="literal">OutputPluginOptions.output_type</code>
+ to <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code> instead
+ of <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code> in
+ the <a class="link" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-STARTUP" title="49.6.4.1. Startup Callback">startup
+ callback</a>. In that case, all the data has to be in the server's encoding
+ so that a <code class="type">text</code> datum can contain it. This is checked in assertion-enabled
+ builds.
+ </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">49.6.4. Output Plugin Callbacks</h3></div></div></div><p>
+ An output plugin gets notified about changes that are happening via
+ various callbacks it needs to provide.
+ </p><p>
+ Concurrent transactions are decoded in commit order, and only changes
+ belonging to a specific transaction are decoded between
+ the <code class="literal">begin</code> and <code class="literal">commit</code>
+ 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 <code class="command">PREPARE TRANSACTION</code> 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
+ <code class="command">ROLLBACK PREPARED</code> 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
+ <code class="function">prepare_cb</code> 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 <code class="command">ROLLBACK PREPARED</code> once
+ that is decoded.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Only transactions that have already safely been flushed to disk will be
+ decoded. That can lead to a <code class="command">COMMIT</code> not immediately being decoded in a
+ directly following <code class="literal">pg_logical_slot_get_changes()</code>
+ when <code class="varname">synchronous_commit</code> is set
+ to <code class="literal">off</code>.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STARTUP"><div class="titlepage"><div><div><h4 class="title">49.6.4.1. Startup Callback</h4></div></div></div><p>
+ The optional <code class="function">startup_cb</code> 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.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx,
+ OutputPluginOptions *options,
+ bool is_init);
+</pre><p>
+ The <code class="literal">is_init</code> parameter will be true when the
+ replication slot is being created and false
+ otherwise. <em class="parameter"><code>options</code></em> points to a struct of options
+ that output plugins can set:
+</p><pre class="programlisting">
+typedef struct OutputPluginOptions
+{
+ OutputPluginOutputType output_type;
+ bool receive_rewrites;
+} OutputPluginOptions;
+</pre><p>
+ <code class="literal">output_type</code> has to either be set to
+ <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code>
+ or <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code>. See also
+ <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE" title="49.6.3. Output Modes">Section 49.6.3</a>.
+ If <code class="literal">receive_rewrites</code> 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.
+ </p><p>
+ The startup callback should validate the options present in
+ <code class="literal">ctx-&gt;output_plugin_options</code>. If the output plugin
+ needs to have a state, it can
+ use <code class="literal">ctx-&gt;output_plugin_private</code> to store it.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-SHUTDOWN"><div class="titlepage"><div><div><h4 class="title">49.6.4.2. Shutdown Callback</h4></div></div></div><p>
+ The optional <code class="function">shutdown_cb</code> callback is called
+ whenever a formerly active replication slot is not used anymore and can
+ be used to deallocate resources private to the output plugin. The slot
+ isn't necessarily being dropped, streaming is just being stopped.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.3. Transaction Begin Callback</h4></div></div></div><p>
+ The required <code class="function">begin_cb</code> callback is called whenever a
+ start of a committed transaction has been decoded. Aborted transactions
+ and their contents never get decoded.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ The <em class="parameter"><code>txn</code></em> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.4. Transaction End Callback</h4></div></div></div><p>
+ The required <code class="function">commit_cb</code> callback is called whenever
+ a transaction commit has been
+ decoded. The <code class="function">change_cb</code> callbacks for all modified
+ rows will have been called before this, if there have been any modified
+ rows.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.5. Change Callback</h4></div></div></div><p>
+ The required <code class="function">change_cb</code> callback is called for every
+ individual row modification inside a transaction, may it be
+ an <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ or <code class="command">DELETE</code>. Even if the original command modified
+ several rows at once the callback will be called individually for each
+ row. The <code class="function">change_cb</code> callback may access system or
+ user catalog tables to aid in the process of outputting the row
+ modification details. In case of decoding a prepared (but yet
+ uncommitted) transaction or decoding of an uncommitted transaction, this
+ change callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> and <em class="parameter"><code>txn</code></em> parameters
+ have the same contents as for the <code class="function">begin_cb</code>
+ and <code class="function">commit_cb</code> callbacks, but additionally the
+ relation descriptor <em class="parameter"><code>relation</code></em> points to the
+ relation the row belongs to and a struct
+ <em class="parameter"><code>change</code></em> describing the row modification are passed
+ in.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Only changes in user defined tables that are not unlogged
+ (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-UNLOGGED"><code class="literal">UNLOGGED</code></a>) and not temporary
+ (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-TEMPORARY"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></a>) can be extracted using
+ logical decoding.
+ </p></div></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.6. Truncate Callback</h4></div></div></div><p>
+ The <code class="function">truncate_cb</code> callback is called for a
+ <code class="command">TRUNCATE</code> command.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</pre><p>
+ The parameters are analogous to the <code class="function">change_cb</code>
+ callback. However, because <code class="command">TRUNCATE</code> 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 <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for
+ details.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-ORIGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.7. Origin Filter Callback</h4></div></div></div><p>
+ The optional <code class="function">filter_by_origin_cb</code> callback
+ is called to determine whether data that has been replayed
+ from <em class="parameter"><code>origin_id</code></em> is of interest to the
+ output plugin.
+</p><pre class="programlisting">
+typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx,
+ RepOriginId origin_id);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> parameter has the same contents
+ as for the other callbacks. No information but the origin is
+ available. To signal that changes originating on the passed in
+ node are irrelevant, return true, causing them to be filtered
+ away; false otherwise. The other callbacks will not be called
+ for transactions and changes that have been filtered away.
+ </p><p>
+ This is useful when implementing cascading or multidirectional
+ replication solutions. Filtering by the origin allows to
+ prevent replicating the same changes back and forth in such
+ setups. While transactions and changes also carry information
+ about the origin, filtering via this callback is noticeably
+ more efficient.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.8. Generic Message Callback</h4></div></div></div><p>
+ The optional <code class="function">message_cb</code> callback is called whenever
+ a logical decoding message has been decoded.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</pre><p>
+ The <em class="parameter"><code>txn</code></em> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID. Note however that it can be NULL when the message is
+ non-transactional and the XID was not assigned yet in the transaction
+ which logged the message. The <em class="parameter"><code>lsn</code></em> has WAL
+ location of the message. The <em class="parameter"><code>transactional</code></em> says
+ if the message was sent as transactional or not. Similar to the change
+ callback, in case of decoding a prepared (but yet uncommitted)
+ transaction or decoding of an uncommitted transaction, this message
+ callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+
+ The <em class="parameter"><code>prefix</code></em> is arbitrary null-terminated prefix
+ which can be used for identifying interesting messages for the current
+ plugin. And finally the <em class="parameter"><code>message</code></em> parameter holds
+ the actual message of <em class="parameter"><code>message_size</code></em> size.
+ </p><p>
+ Extra care should be taken to ensure that the prefix the output plugin
+ considers interesting is unique. Using name of the extension or the
+ output plugin itself is often a good choice.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.9. Prepare Filter Callback</h4></div></div></div><p>
+ The optional <code class="function">filter_prepare_cb</code> callback
+ is called to determine whether data that is part of the current
+ two-phase commit transaction should be considered for decoding
+ at this prepare stage or later as a regular one-phase transaction at
+ <code class="command">COMMIT PREPARED</code> time. To signal that
+ decoding should be skipped, return <code class="literal">true</code>;
+ <code class="literal">false</code> otherwise. When the callback is not
+ defined, <code class="literal">false</code> is assumed (i.e. no filtering, all
+ transactions using two-phase commit are decoded in two phases as well).
+</p><pre class="programlisting">
+typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx,
+ TransactionId xid,
+ const char *gid);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> parameter has the same contents as for
+ the other callbacks. The parameters <em class="parameter"><code>xid</code></em>
+ and <em class="parameter"><code>gid</code></em> provide two different ways to identify
+ the transaction. The later <code class="command">COMMIT PREPARED</code> or
+ <code class="command">ROLLBACK PREPARED</code> carries both identifiers,
+ providing an output plugin the choice of what to use.
+ </p><p>
+ The callback may be invoked multiple times per transaction to decode
+ and must provide the same static answer for a given pair of
+ <em class="parameter"><code>xid</code></em> and <em class="parameter"><code>gid</code></em> every time
+ it is called.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.10. Transaction Begin Prepare Callback</h4></div></div></div><p>
+ The required <code class="function">begin_prepare_cb</code> callback is called
+ whenever the start of a prepared transaction has been decoded. The
+ <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback to
+ check if the plugin has already received this <code class="command">PREPARE</code>
+ in which case it can either error out or skip the remaining changes of
+ the transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.11. Transaction Prepare Callback</h4></div></div></div><p>
+ The required <code class="function">prepare_cb</code> callback is called whenever
+ a transaction which is prepared for two-phase commit has been
+ decoded. The <code class="function">change_cb</code> callback for all modified
+ rows will have been called before this, if there have been any modified
+ rows. The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.12. Transaction Commit Prepared Callback</h4></div></div></div><p>
+ The required <code class="function">commit_prepared_cb</code> callback is called
+ whenever a transaction <code class="command">COMMIT PREPARED</code> has been decoded.
+ The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-ROLLBACK-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.13. Transaction Rollback Prepared Callback</h4></div></div></div><p>
+ The required <code class="function">rollback_prepared_cb</code> callback is called
+ whenever a transaction <code class="command">ROLLBACK PREPARED</code> has been
+ decoded. The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback. The
+ parameters <em class="parameter"><code>prepare_end_lsn</code></em> and
+ <em class="parameter"><code>prepare_time</code></em> can be used to check if the plugin
+ has received this <code class="command">PREPARE TRANSACTION</code> in which case
+ it can apply the rollback, otherwise, it can skip the rollback operation. The
+ <em class="parameter"><code>gid</code></em> alone is not sufficient because the downstream
+ node can have a prepared transaction with same identifier.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_end_lsn,
+ TimestampTz prepare_time);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-START"><div class="titlepage"><div><div><h4 class="title">49.6.4.14. Stream Start Callback</h4></div></div></div><p>
+ The <code class="function">stream_start_cb</code> callback is called when opening
+ a block of streamed changes from an in-progress transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-STOP"><div class="titlepage"><div><div><h4 class="title">49.6.4.15. Stream Stop Callback</h4></div></div></div><p>
+ The <code class="function">stream_stop_cb</code> callback is called when closing
+ a block of streamed changes from an in-progress transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-ABORT"><div class="titlepage"><div><div><h4 class="title">49.6.4.16. Stream Abort Callback</h4></div></div></div><p>
+ The <code class="function">stream_abort_cb</code> callback is called to abort
+ a previously streamed transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr abort_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.17. Stream Prepare Callback</h4></div></div></div><p>
+ The <code class="function">stream_prepare_cb</code> callback is called to prepare
+ a previously streamed transaction as part of a two-phase commit.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.18. Stream Commit Callback</h4></div></div></div><p>
+ The <code class="function">stream_commit_cb</code> callback is called to commit
+ a previously streamed transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.19. Stream Change Callback</h4></div></div></div><p>
+ The <code class="function">stream_change_cb</code> callback is called when sending
+ a change in a block of streamed changes (demarcated by
+ <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> calls).
+ The actual changes are not displayed as the transaction can abort at a later
+ point in time and we don't decode changes for aborted transactions.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.20. Stream Message Callback</h4></div></div></div><p>
+ The <code class="function">stream_message_cb</code> callback is called when sending
+ a generic message in a block of streamed changes (demarcated by
+ <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> 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.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.21. Stream Truncate Callback</h4></div></div></div><p>
+ The <code class="function">stream_truncate_cb</code> callback is called for a
+ <code class="command">TRUNCATE</code> command in a block of streamed changes
+ (demarcated by <code class="function">stream_start_cb</code> and
+ <code class="function">stream_stop_cb</code> calls).
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</pre><p>
+ The parameters are analogous to the <code class="function">stream_change_cb</code>
+ callback. However, because <code class="command">TRUNCATE</code> 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 <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for
+ details.
+ </p></div></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT"><div class="titlepage"><div><div><h3 class="title">49.6.5. Functions for Producing Output</h3></div></div></div><p>
+ To actually produce output, output plugins can write data to
+ the <code class="literal">StringInfo</code> output buffer
+ in <code class="literal">ctx-&gt;out</code> when inside
+ the <code class="function">begin_cb</code>, <code class="function">commit_cb</code>,
+ or <code class="function">change_cb</code> callbacks. Before writing to the output
+ buffer, <code class="function">OutputPluginPrepareWrite(ctx, last_write)</code> has
+ to be called, and after finishing writing to the
+ buffer, <code class="function">OutputPluginWrite(ctx, last_write)</code> has to be
+ called to perform the write. The <em class="parameter"><code>last_write</code></em>
+ indicates whether a particular write was the callback's last write.
+ </p><p>
+ The following example shows how to output data to the consumer of an
+ output plugin:
+</p><pre class="programlisting">
+OutputPluginPrepareWrite(ctx, true);
+appendStringInfo(ctx-&gt;out, "BEGIN %u", txn-&gt;xid);
+OutputPluginWrite(ctx, true);
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.5. System Catalogs Related to Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.7. Logical Decoding Output Writers</td></tr></table></div></body></html> \ No newline at end of file