@@ -1429,6 +1429,14 @@ test_sub=# SELECT * FROM child ORDER BY a;
14291429 of columns in the list is not preserved.
14301430 </para>
14311431
1432+ <para>
1433+ Generated columns can also be specified in a column list. This allows
1434+ generated columns to be published, regardless of the publication parameter
1435+ <link linkend="sql-createpublication-params-with-publish-generated-columns">
1436+ <literal>publish_generated_columns</literal></link>. See
1437+ <xref linkend="logical-replication-gencols"/> for details.
1438+ </para>
1439+
14321440 <para>
14331441 Specifying a column list when the publication also publishes
14341442 <link linkend="sql-createpublication-params-for-tables-in-schema"><literal>FOR TABLES IN SCHEMA</literal></link>
@@ -1594,6 +1602,190 @@ test_sub=# SELECT * FROM t1 ORDER BY id;
15941602
15951603 </sect1>
15961604
1605+ <sect1 id="logical-replication-gencols">
1606+ <title>Generated Column Replication</title>
1607+
1608+ <para>
1609+ Typically, a table at the subscriber will be defined the same as the
1610+ publisher table, so if the publisher table has a <link linkend="ddl-generated-columns">
1611+ <literal>GENERATED column</literal></link> then the subscriber table will
1612+ have a matching generated column. In this case, it is always the subscriber
1613+ table generated column value that is used.
1614+ </para>
1615+
1616+ <para>
1617+ For example, note below that subscriber table generated column value comes from the
1618+ subscriber column's calculation.
1619+ <programlisting>
1620+ test_pub=# CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED);
1621+ CREATE TABLE
1622+ test_pub=# INSERT INTO tab_gen_to_gen VALUES (1),(2),(3);
1623+ INSERT 0 3
1624+ test_pub=# CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen;
1625+ CREATE PUBLICATION
1626+ test_pub=# SELECT * FROM tab_gen_to_gen;
1627+ a | b
1628+ ---+---
1629+ 1 | 2
1630+ 2 | 3
1631+ 3 | 4
1632+ (3 rows)
1633+
1634+ test_sub=# CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED);
1635+ CREATE TABLE
1636+ test_sub=# CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1;
1637+ CREATE SUBSCRIPTION
1638+ test_sub=# SELECT * from tab_gen_to_gen;
1639+ a | b
1640+ ---+----
1641+ 1 | 100
1642+ 2 | 200
1643+ 3 | 300
1644+ (3 rows)
1645+ </programlisting>
1646+ </para>
1647+
1648+ <para>
1649+ In fact, prior to version 18.0, logical replication does not publish
1650+ <literal>GENERATED</literal> columns at all.
1651+ </para>
1652+
1653+ <para>
1654+ But, replicating a generated column to a regular column can sometimes be
1655+ desirable.
1656+ <tip>
1657+ <para>
1658+ This feature may be useful when replicating data to a
1659+ non-PostgreSQL database via output plugin, especially if the target database
1660+ does not support generated columns.
1661+ </para>
1662+ </tip>
1663+ </para>
1664+
1665+ <para>
1666+ Generated columns are not published by default, but users can opt to
1667+ publish stored generated columns just like regular ones.
1668+ </para>
1669+
1670+ <para>
1671+ There are two ways to do this:
1672+ <itemizedlist>
1673+ <listitem>
1674+ <para>
1675+ Set the <command>PUBLICATION</command> parameter
1676+ <link linkend="sql-createpublication-params-with-publish-generated-columns">
1677+ <literal>publish_generated_columns</literal></link> to <literal>stored</literal>.
1678+ This instructs PostgreSQL logical replication to publish current and
1679+ future stored generated columns of the publication's tables.
1680+ </para>
1681+ </listitem>
1682+
1683+ <listitem>
1684+ <para>
1685+ Specify a table <link linkend="logical-replication-col-lists">column list</link>
1686+ to explicitly nominate which stored generated columns will be published.
1687+ </para>
1688+
1689+ <note>
1690+ <para>
1691+ When determining which table columns will be published, a column list
1692+ takes precedence, overriding the effect of the
1693+ <literal>publish_generated_columns</literal> parameter.
1694+ </para>
1695+ </note>
1696+ </listitem>
1697+ </itemizedlist>
1698+ </para>
1699+
1700+ <para>
1701+ The following table summarizes behavior when there are generated columns
1702+ involved in the logical replication. Results are shown for when
1703+ publishing generated columns is not enabled, and for when it is
1704+ enabled.
1705+ </para>
1706+
1707+ <table id="logical-replication-gencols-table-summary">
1708+ <title>Replication Result Summary</title>
1709+ <tgroup cols="4">
1710+
1711+ <thead>
1712+ <row>
1713+ <entry>Publish generated columns?</entry>
1714+ <entry>Publisher table column</entry>
1715+ <entry>Subscriber table column</entry>
1716+ <entry>Result</entry>
1717+ </row>
1718+ </thead>
1719+
1720+ <tbody>
1721+ <row>
1722+ <entry>No</entry>
1723+ <entry>GENERATED</entry>
1724+ <entry>GENERATED</entry>
1725+ <entry>Publisher table column is not replicated. Use the subscriber table generated column value.</entry>
1726+ </row>
1727+
1728+ <row>
1729+ <entry>No</entry>
1730+ <entry>GENERATED</entry>
1731+ <entry>regular</entry>
1732+ <entry>Publisher table column is not replicated. Use the subscriber table regular column default value.</entry>
1733+ </row>
1734+
1735+ <row>
1736+ <entry>No</entry>
1737+ <entry>GENERATED</entry>
1738+ <entry>--missing--</entry>
1739+ <entry>Publisher table column is not replicated. Nothing happens.</entry>
1740+ </row>
1741+
1742+ <row>
1743+ <entry>Yes</entry>
1744+ <entry>GENERATED</entry>
1745+ <entry>GENERATED</entry>
1746+ <entry>ERROR. Not supported.</entry>
1747+ </row>
1748+
1749+ <row>
1750+ <entry>Yes</entry>
1751+ <entry>GENERATED</entry>
1752+ <entry>regular</entry>
1753+ <entry>Publisher table column value is replicated to the subscriber table column.</entry>
1754+ </row>
1755+
1756+ <row>
1757+ <entry>Yes</entry>
1758+ <entry>GENERATED</entry>
1759+ <entry>--missing--</entry>
1760+ <entry>ERROR. The column is reported as missing from the subscriber table.</entry>
1761+ </row>
1762+ </tbody>
1763+ </tgroup>
1764+ </table>
1765+
1766+ <warning>
1767+ <para>
1768+ There's currently no support for subscriptions comprising several
1769+ publications where the same table has been published with different column
1770+ lists. See <xref linkend="logical-replication-col-lists"/>.
1771+ </para>
1772+
1773+ <para>
1774+ This same situation can occur if one publication is publishing generated
1775+ columns, while another publication in the same subscription is not
1776+ publishing generated columns for the same table.
1777+ </para>
1778+ </warning>
1779+
1780+ <note>
1781+ <para>
1782+ If the subscriber is from a release prior to 18, then initial table
1783+ synchronization won't copy generated columns even if they are defined in
1784+ the publisher.
1785+ </para>
1786+ </note>
1787+ </sect1>
1788+
15971789 <sect1 id="logical-replication-conflicts">
15981790 <title>Conflicts</title>
15991791
0 commit comments