Fix the initial sync tables with no columns.
authorAmit Kapila <[email protected]>
Wed, 22 Nov 2023 06:14:14 +0000 (11:44 +0530)
committerAmit Kapila <[email protected]>
Wed, 22 Nov 2023 06:14:14 +0000 (11:44 +0530)
The copy command formed for initial sync was using parenthesis for tables
with no columns leading to syntax error. This  avoids adding
parenthesis for such tables.

Reported-by: Justin G
Author: Vignesh C
Reviewed-by: Peter Smith, Amit Kapila
Back-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 37a0abe2f4dde70997a0c731a0e29101a0527d1b..df3c42eb5de0a304f64a997c0a176ba97d043008 100644 (file)
@@ -1124,22 +1124,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 87d44f634f5c5157e58761e4eab5c3d58c673298..e49da00b29af5d2abf117c0b0c8ff44b42a6474e 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)");