--------+---------+-----------+----------+---------
id | integer | | not null |
a | text | | |
b | text | | |
c | text | | |
d | text | | |
e | text | | |
Indexes:
"t1_pkey" PRIMARY KEY, btree (id)
Publications:
"p1" (id, a, b, d)
</programlisting></para>
<para>
On the subscriber node, create a table <literal>t1</literal> which now
only needs a subset of the columns that were on the publisher table
<literal>t1</literal>, and also create the subscription
<literal>s1</literal> that subscribes to the publication
<literal>p1</literal>.
<programlisting>
/* sub # */ CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
/* sub # */ CREATE SUBSCRIPTION s1
/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1'
/* sub - */ PUBLICATION p1;
</programlisting></para>
<para>
On the publisher node, insert some rows to table <literal>t1</literal>.
<programlisting>
/* pub # */ INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
/* pub # */ INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
/* pub # */ INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
/* pub # */ SELECT * FROM t1 ORDER BY id;
id | a | b | c | d | e
----+-----+-----+-----+-----+-----
1 | a-1 | b-1 | c-1 | d-1 | e-1
2 | a-2 | b-2 | c-2 | d-2 | e-2
3 | a-3 | b-3 | c-3 | d-3 | e-3
(3 rows)
</programlisting></para>
<para>
Only data from the column list of publication <literal>p1</literal> is
replicated.
<programlisting>
/* sub # */ SELECT * FROM t1 ORDER BY id;
id | b | a | d
----+-----+-----+-----
1 | b-1 | a-1 | d-1
2 | b-2 | a-2 | d-2
3 | b-3 | a-3 | d-3
(3 rows)
</programlisting></para>
</sect2>
</sect1>
<sect1 id="logical-replication-gencols">
<title>Generated Column Replication</title>
<para>
Typically, a table at the subscriber will be defined the same as the
publisher table, so if the publisher table has a <link linkend="ddl-generated-columns">
<literal>GENERATED column</literal></link> then the subscriber table will
have a matching generated column. In this case, it is always the subscriber
table generated column value that is used.
</para>
<para>
For example, note below that subscriber table generated column value comes from the
subscriber column's calculation.
<programlisting>
/* pub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED);
/* pub # */ INSERT INTO tab_gen_to_gen VALUES (1),(2),(3);
/* pub # */ CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen;
/* pub # */ SELECT * FROM tab_gen_to_gen;
a | b
---+---
1 | 2
2 | 3
3 | 4
(3 rows)
/* sub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED);
/* sub # */ CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1;
/* sub # */ SELECT * from tab_gen_to_gen;
a | b
---+----
1 | 100
2 | 200
3 | 300
(3 rows)
</programlisting>
</para>
<para>
In fact, prior to version 18.0, logical replication does not publish
<literal>GENERATED</literal> columns at all.
</para>
<para>
But, replicating a generated column to a regular column can sometimes be
desirable.
<tip>
<para>
This feature may be useful when replicating data to a
non-PostgreSQL database via output plugin, especially if the target database
does not support generated columns.
</para>
</tip>
</para>
<para>
Generated columns are not published by default, but users can opt to
publish stored generated columns just like regular ones.
</para>
<para>
There are two ways to do this:
<itemizedlist>
<listitem>
<para>
Set the <command>PUBLICATION</command> parameter
<link linkend="sql-createpublication-params-with-publish-generated-columns">
<literal>publish_generated_columns</literal></link>