@@ -1429,6 +1429,14 @@ test_sub=# SELECT * FROM child ORDER BY a;
1429
1429
of columns in the list is not preserved.
1430
1430
</para>
1431
1431
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
+
1432
1440
<para>
1433
1441
Specifying a column list when the publication also publishes
1434
1442
<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;
1594
1602
1595
1603
</sect1>
1596
1604
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
+
1597
1789
<sect1 id="logical-replication-conflicts">
1598
1790
<title>Conflicts</title>
1599
1791
0 commit comments