Remove incorrect assertion for INSERT in logical replication's publisher
authorMichael Paquier
Sun, 12 Jan 2020 13:45:17 +0000 (22:45 +0900)
committerMichael Paquier
Sun, 12 Jan 2020 13:45:17 +0000 (22:45 +0900)
On the publisher, it was assumed that an INSERT change cannot happen for
a relation with no replica identity.  However this is true only for a
change that needs references to old rows, aka UPDATE or DELETE, so
trying to use logical replication with a relation that has no replica
identity led to an assertion failure in the publisher when issuing an
INSERT.  This commit removes the incorrect assertion, and adds more
regression tests to provide coverage for relations without replica
identity.

Reported-by: Neha Sharma
Author: Dilip Kumar, Michael Paquier
Reviewed-by: Andres Freund
Discussion: https://postgr.es/m/CANiYTQsL1Hb8_Km08qd32svrqNumXLJeoGo014O7VZymgOhZEA@mail.gmail.com
Backpatch-through: 10

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

index 94dfee0b24e61bf4085853f9deb965f12a3794f7..6204e420b5913ff1a4dbae292c172cee9826e9b5 100644 (file)
@@ -140,10 +140,6 @@ logicalrep_write_insert(StringInfo out, Relation rel, HeapTuple newtuple)
 {
    pq_sendbyte(out, 'I');      /* action INSERT */
 
-   Assert(rel->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT ||
-          rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL ||
-          rel->rd_rel->relreplident == REPLICA_IDENTITY_INDEX);
-
    /* use Oid as relation identifier */
    pq_sendint(out, RelationGetRelid(rel), 4);
 
index a6dab7a97f262c0397ae235563320dd952b85b54..b7c503f7795e06ca73a15e3c88bed23676c4a841 100644 (file)
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 21;
+use Test::More tests => 22;
 
 # Initialize publisher node
 my $node_publisher = get_new_node('publisher');
@@ -31,6 +31,10 @@ $node_publisher->safe_psql('postgres',
    "CREATE TABLE tab_mixed (a int primary key, b text, c numeric)");
 $node_publisher->safe_psql('postgres',
    "INSERT INTO tab_mixed (a, b, c) VALUES (1, 'foo', 1.1)");
+# Let this table with REPLICA IDENTITY NOTHING, allowing only INSERT changes.
+$node_publisher->safe_psql('postgres', "CREATE TABLE tab_nothing (a int)");
+$node_publisher->safe_psql('postgres',
+   "ALTER TABLE tab_nothing REPLICA IDENTITY NOTHING");
 
 # Setup structure on subscriber
 $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)");
@@ -39,6 +43,7 @@ $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_full (a int)");
 $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_full2 (x text)");
 $node_subscriber->safe_psql('postgres',
    "CREATE TABLE tab_rep (a int primary key)");
+$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_nothing (a int)");
 
 # different column count and order than on publisher
 $node_subscriber->safe_psql('postgres',
@@ -51,7 +56,7 @@ $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"
+"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_nothing"
 );
 $node_publisher->safe_psql('postgres',
    "ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins");
@@ -94,6 +99,9 @@ $node_publisher->safe_psql('postgres', "UPDATE tab_rep SET a = -a");
 $node_publisher->safe_psql('postgres',
    "INSERT INTO tab_mixed VALUES (2, 'bar', 2.2)");
 
+$node_publisher->safe_psql('postgres',
+   "INSERT INTO tab_nothing VALUES (generate_series(1,20))");
+
 $node_publisher->poll_query_until('postgres', $caughtup_query)
   or die "Timed out while waiting for subscriber to catch up";
 
@@ -109,6 +117,10 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT * FROM tab_mixed");
 is( $result, qq(local|1.1|foo|1
 local|2.2|bar|2), 'check replicated changes with different column order');
 
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab_nothing");
+is($result, qq(20), 'check replicated changes with REPLICA IDENTITY NOTHING');
+
 # insert some duplicate rows
 $node_publisher->safe_psql('postgres',
    "INSERT INTO tab_full SELECT generate_series(1,10)");