diff options
-rw-r--r-- | src/backend/replication/logical/relation.c | 3 | ||||
-rw-r--r-- | src/test/subscription/t/008_diff_schema.pl | 37 |
2 files changed, 37 insertions, 3 deletions
diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 54bcd16ec12..aa59c455d4c 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -339,7 +339,8 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) attnum = AttrNumberGetAttrOffset(attnum); - if (!bms_is_member(entry->attrmap[attnum], remoterel->attkeys)) + if (entry->attrmap[attnum] < 0 || + !bms_is_member(entry->attrmap[attnum], remoterel->attkeys)) { entry->updatable = false; break; diff --git a/src/test/subscription/t/008_diff_schema.pl b/src/test/subscription/t/008_diff_schema.pl index cca4480f52e..2c94d4dfe43 100644 --- a/src/test/subscription/t/008_diff_schema.pl +++ b/src/test/subscription/t/008_diff_schema.pl @@ -3,7 +3,7 @@ use strict; use warnings; use PostgresNode; use TestLib; -use Test::More tests => 4; +use Test::More tests => 5; sub wait_for_caught_up { @@ -35,7 +35,7 @@ $node_subscriber->safe_psql('postgres', "CREATE TABLE test_tab (a int primary ke # Setup logical replication my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -$node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR TABLE test_tab"); +$node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR ALL TABLES"); my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', @@ -86,5 +86,38 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), count(c), count(d = 999), count(e) FROM test_tab"); is($result, qq(3|3|3|3), 'check extra columns contain local defaults after apply'); + +# Check a bug about adding a replica identity column on the subscriber +# that was not yet mapped to a column on the publisher. This would +# result in errors on the subscriber and replication thus not +# progressing. +# (https://www.postgresql.org/message-id/flat/a9139c29-7ddd-973b-aa7f-71fed9c38d75%40minerva.info) + +$node_publisher->safe_psql('postgres', + "CREATE TABLE test_tab2 (a int)"); + +$node_subscriber->safe_psql('postgres', + "CREATE TABLE test_tab2 (a int)"); + +$node_subscriber->safe_psql('postgres', + "ALTER SUBSCRIPTION tap_sub REFRESH PUBLICATION"); + +# Add replica identity column. (The serial is not necessary, but it's +# a convenient way to get a default on the new column so that rows +# from the publisher that don't have the column yet can be inserted.) +$node_subscriber->safe_psql('postgres', + "ALTER TABLE test_tab2 ADD COLUMN b serial PRIMARY KEY"); + +$node_publisher->safe_psql('postgres', + "INSERT INTO test_tab2 VALUES (1)"); + +wait_for_caught_up($node_publisher, $appname); + +is($node_subscriber->safe_psql('postgres', + "SELECT count(*), min(a), max(a) FROM test_tab2"), + qq(1|1|1), + 'check replicated inserts on subscriber'); + + $node_subscriber->stop; $node_publisher->stop; |