-- fails, binary plugin, textual consumer
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '1');
-ERROR: output plugin cannot produce binary output
+ERROR: logical decoding output plugin "test_decoding" produces binary output, but "pg_logical_slot_get_changes(name,pg_lsn,integer,text[])" expects textual data
-- succeeds, textual plugin, binary consumer
SELECT data FROM pg_logical_slot_get_binary_changes('regression_slot', NULL, NULL, 'force-binary', '0');
data
</para>
</sect2>
+ <sect2 id="logicaldecoding-output-mode">
+ <title>Output Modes</title>
+ <para>
+ 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 datatype that can contain arbitrary data (i.e. bytea) is
+ cumbersome. If the output plugin only outputs textual data in the
+ server's encoding it can declare that by
+ setting <literal>OutputPluginOptions.output_mode</>
+ to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</> instead
+ of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</> in
+ the <link linkend="logicaldecoding-output-plugin-startup">startup
+ callback</>. In that case all the data has to be in the server's encoding
+ so a <type>text</> can contain it. This is checked in assertion enabled
+ builds.
+ </para>
+ </sect2>
+
<sect2 id="logicaldecoding-output-plugin-callbacks">
<title>Output Plugin Callbacks</title>
<para>
</programlisting>
<literal>output_type</literal> has to either be set to
<literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal>
- or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>.
+ or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>. See also
+ <xref linkend="logicaldecoding-output-mode"/>.
</para>
<para>
The startup callback should validate the options present in
ctx->options.output_type != OUTPUT_PLUGIN_TEXTUAL_OUTPUT)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("output plugin cannot produce binary output")));
+ errmsg("logical decoding output plugin \"%s\" produces binary output, but \"%s\" expects textual data",
+ NameStr(MyReplicationSlot->data.plugin),
+ format_procedure(fcinfo->flinfo->fn_oid))));
ctx->output_writer_private = p;