From ebe124eacd7c3faa36ed358e7cc1d7c5b419e5f6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:18:09 +0200 Subject: Merging upstream version 15.6. Signed-off-by: Daniel Baumann --- src/test/subscription/t/001_rep_changes.pl | 17 +++++++++- src/test/subscription/t/100_bugs.pl | 53 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'src/test/subscription') diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl index 6ed9265..6e6ebd8 100644 --- a/src/test/subscription/t/001_rep_changes.pl +++ b/src/test/subscription/t/001_rep_changes.pl @@ -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)"); diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl index 61c9f53..28ca4af 100644 --- a/src/test/subscription/t/100_bugs.pl +++ b/src/test/subscription/t/100_bugs.pl @@ -365,4 +365,57 @@ is( $node_subscriber_d_cols->safe_psql( $node_publisher_d_cols->stop('fast'); $node_subscriber_d_cols->stop('fast'); +# The bug was that pgoutput was incorrectly replacing missing attributes in +# tuples with NULL. This could result in incorrect replication with +# `REPLICA IDENTITY FULL`. + +$node_publisher->rotate_logfile(); +$node_publisher->start(); + +$node_subscriber->rotate_logfile(); +$node_subscriber->start(); + +# Set up a table with schema `(a int, b bool)` where the `b` attribute is +# missing for one row due to the `ALTER TABLE ... ADD COLUMN ... DEFAULT` +# fast path. +$node_publisher->safe_psql( + 'postgres', qq( + CREATE TABLE tab_default (a int); + ALTER TABLE tab_default REPLICA IDENTITY FULL; + INSERT INTO tab_default VALUES (1); + ALTER TABLE tab_default ADD COLUMN b bool DEFAULT false NOT NULL; + INSERT INTO tab_default VALUES (2, true); + CREATE PUBLICATION pub1 FOR TABLE tab_default; +)); + +# Replicate to the subscriber. +$node_subscriber->safe_psql( + 'postgres', qq( + CREATE TABLE tab_default (a int, b bool); + CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1; +)); + +$node_subscriber->wait_for_subscription_sync($node_publisher, 'sub1'); +my $result = $node_subscriber->safe_psql('postgres', + "SELECT a, b FROM tab_default"); +is($result, qq(1|f +2|t), 'check snapshot on subscriber'); + +# Update all rows in the table and ensure the rows with the missing `b` +# attribute replicate correctly. +$node_publisher->safe_psql('postgres', + "UPDATE tab_default SET a = a + 1"); +$node_publisher->wait_for_catchup('sub1'); + +# When the bug is present, the `1|f` row will not be updated to `2|f` because +# the publisher incorrectly fills in `NULL` for `b` and publishes an update +# for `1|NULL`, which doesn't exist in the subscriber. +$result = $node_subscriber->safe_psql('postgres', + "SELECT a, b FROM tab_default"); +is($result, qq(2|f +3|t), 'check replicated update on subscriber'); + +$node_publisher->stop('fast'); +$node_subscriber->stop('fast'); + done_testing(); -- cgit v1.2.3