Fix the initial sync tables with no columns.
authorAmit Kapila <akapila@postgresql.org>
Wed, 22 Nov 2023 05:57:38 +0000 (11:27 +0530)
committerAmit Kapila <akapila@postgresql.org>
Wed, 22 Nov 2023 05:57:38 +0000 (11:27 +0530)
The copy command formed for initial sync was using parenthesis for tables
with no columns leading to syntax error. This patch avoids adding
parenthesis for such tables.

Reported-by: Justin G
Author: Vignesh C
Reviewed-by: Peter Smith, Amit Kapila
Backpatch-through: 15
Discussion: http://postgr.es/m/18203-df37fe354b626670@postgresql.org

src/backend/replication/logical/tablesync.c
src/test/subscription/t/001_rep_changes.pl

index 6d461654ab46d7b306fb5509175ba3dfed0ebddf..fcc6e1f311c1f1ec9dd299f997e5a8e00e513f69 100644 (file)
@@ -1111,22 +1111,30 @@ copy_table(Relation rel)
    /* Regular table with no row filter */
    if (lrel.relkind == RELKIND_RELATION && qual == NIL)
    {
-       appendStringInfo(&cmd, "COPY %s (",
+       appendStringInfo(&cmd, "COPY %s",
                         quote_qualified_identifier(lrel.nspname, lrel.relname));
 
-       /*
-        * XXX Do we need to list the columns in all cases? Maybe we're
-        * replicating all columns?
-        */
-       for (int i = 0; i < lrel.natts; i++)
+       /* If the table has columns, then specify the columns */
+       if (lrel.natts)
        {
-           if (i > 0)
-               appendStringInfoString(&cmd, ", ");
+           appendStringInfoString(&cmd, " (");
 
-           appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i]));
+           /*
+            * XXX Do we need to list the columns in all cases? Maybe we're
+            * replicating all columns?
+            */
+           for (int i = 0; i < lrel.natts; i++)
+           {
+               if (i > 0)
+                   appendStringInfoString(&cmd, ", ");
+
+               appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i]));
+           }
+
+           appendStringInfoString(&cmd, ")");
        }
 
-       appendStringInfoString(&cmd, ") TO STDOUT");
+       appendStringInfoString(&cmd, " TO STDOUT");
    }
    else
    {
index 0a399cdb82b92b22ea26bde9c932874d02708929..857bcfb5cc2d4afad601be483bffed7be80b5e4d 100644 (file)
@@ -57,6 +57,11 @@ $node_publisher->safe_psql('postgres',
    "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)"
 );
 
+# Replicate the changes without columns
+$node_publisher->safe_psql('postgres', "CREATE TABLE tab_no_col()");
+$node_publisher->safe_psql('postgres',
+   "INSERT INTO tab_no_col default VALUES");
+
 # Setup structure on subscriber
 $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)");
 $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_ins (a int)");
@@ -87,13 +92,16 @@ $node_subscriber->safe_psql('postgres',
    "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)"
 );
 
+# replication of the table without columns
+$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_no_col()");
+
 # Setup logical replication
 my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
 $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub");
 $node_publisher->safe_psql('postgres',
    "CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)");
 $node_publisher->safe_psql('postgres',
-   "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk, tab_no_replidentity_index"
+   "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk, tab_no_replidentity_index, tab_no_col"
 );
 $node_publisher->safe_psql('postgres',
    "ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins");
@@ -141,6 +149,9 @@ $node_publisher->safe_psql('postgres', "UPDATE tab_include SET a = -a");
 $node_publisher->safe_psql('postgres',
    "INSERT INTO tab_no_replidentity_index VALUES(1)");
 
+$node_publisher->safe_psql('postgres',
+   "INSERT INTO tab_no_col default VALUES");
+
 $node_publisher->wait_for_catchup('tap_sub');
 
 $result = $node_subscriber->safe_psql('postgres',
@@ -169,6 +180,10 @@ is( $node_subscriber->safe_psql(
    1,
    "value replicated to subscriber without replica identity index");
 
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab_no_col");
+is($result, qq(2), 'check replicated changes for table having no columns');
+
 # insert some duplicate rows
 $node_publisher->safe_psql('postgres',
    "INSERT INTO tab_full SELECT generate_series(1,10)");