v1-0003-Tap-tests-for-generated-columns.patch

text/x-patch

Filename: v1-0003-Tap-tests-for-generated-columns.patch
Type: text/x-patch
Part: 1
Message: Re: Pgoutput not capturing the generated columns

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v1-0003
Subject: Tap tests for generated columns
File+
src/test/subscription/t/011_generated.pl 289 0
From 3e20e7ec4b2731bb703cf94344e3c9c35ff4cbb0 Mon Sep 17 00:00:00 2001
From: Shubham Khanna <khannashubham1197@gmail.com>
Date: Thu, 10 Oct 2024 11:25:52 +1100
Subject: [PATCH v1 3/3] Tap tests for generated columns

Add tests for the combinations of generated column replication.
Also test effect of 'publish_generated_columns' option true/false.

Author: Shubham Khanna
Reviewed-by: Vignesh C
---
 src/test/subscription/t/011_generated.pl | 289 +++++++++++++++++++++++
 1 file changed, 289 insertions(+)

diff --git a/src/test/subscription/t/011_generated.pl b/src/test/subscription/t/011_generated.pl
index 8b2e5f4708..babe7e51c0 100644
--- a/src/test/subscription/t/011_generated.pl
+++ b/src/test/subscription/t/011_generated.pl
@@ -96,4 +96,293 @@ is( $result, qq(1|22|
 8|176|18
 9|198|19), 'generated columns replicated with trigger');
 
+# cleanup
+$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION sub1");
+$node_publisher->safe_psql('postgres', "DROP PUBLICATION pub1");
+
+# =============================================================================
+# This test case exercises logical replication involving a generated column
+# on the publisher and a regular column on the subscriber.
+#
+# The following combinations are tested:
+# - Publication pub1 on the 'postgres' database with the option
+#   publish_generated_columns set to false.
+# - Publication pub2 on the 'postgres' database with the option
+#   publish_generated_columns set to true.
+# - Subscription sub1 on the 'postgres' database for publication pub1.
+# - Subscription sub2 on the 'test_pgc_true' database for publication pub2.
+# =============================================================================
+
+$node_subscriber->safe_psql('postgres', "CREATE DATABASE test_pgc_true");
+
+# --------------------------------------------------
+# Test Case: Generated to Regular Column Replication
+# Publisher table has generated column 'b'.
+# Subscriber table has regular column 'b'.
+# --------------------------------------------------
+
+# Create table and publications.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab_gen_to_nogen (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
+	INSERT INTO tab_gen_to_nogen (a) VALUES (1), (2), (3);
+	CREATE PUBLICATION regress_pub1_gen_to_nogen FOR TABLE tab_gen_to_nogen WITH (publish_generated_columns = false);
+	CREATE PUBLICATION regress_pub2_gen_to_nogen FOR TABLE tab_gen_to_nogen WITH (publish_generated_columns = true);
+));
+
+# Create the table and subscription in the 'postgres' database.
+$node_subscriber->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab_gen_to_nogen (a int, b int);
+	CREATE SUBSCRIPTION regress_sub1_gen_to_nogen CONNECTION '$publisher_connstr' PUBLICATION regress_pub1_gen_to_nogen WITH (copy_data = true);
+));
+
+# Create the table and subscription in the 'test_pgc_true' database.
+$node_subscriber->safe_psql(
+	'test_pgc_true', qq(
+	CREATE TABLE tab_gen_to_nogen (a int, b int);
+	CREATE SUBSCRIPTION regress_sub2_gen_to_nogen CONNECTION '$publisher_connstr' PUBLICATION regress_pub2_gen_to_nogen WITH (copy_data = true);
+));
+
+# Wait for the initial synchronization of the 'regress_sub1_gen_to_nogen'
+# subscription in the 'postgres' database.
+$node_subscriber->wait_for_subscription_sync($node_publisher,
+	'regress_sub1_gen_to_nogen', 'postgres');
+
+# Wait for the initial synchronization of the 'regress_sub2_gen_to_nogen'
+# subscription in the 'test_pgc_true' database.
+$node_subscriber->wait_for_subscription_sync($node_publisher,
+	'regress_sub2_gen_to_nogen', 'test_pgc_true');
+
+# Verify that generated column data is not copied during the initial
+# synchronization when publish_generated_columns is set to false.
+$result = $node_subscriber->safe_psql('postgres',
+	"SELECT a, b FROM tab_gen_to_nogen");
+is( $result, qq(1|
+2|
+3|), 'tab_gen_to_nogen initial sync, when publish_generated_columns=false');
+
+# Verify that generated column data is copied during the initial synchronization
+# when publish_generated_columns is set to true.
+$result = $node_subscriber->safe_psql('test_pgc_true',
+	"SELECT a, b FROM tab_gen_to_nogen");
+is( $result, qq(1|2
+2|4
+3|6),
+	'tab_gen_to_nogen initial sync, when publish_generated_columns=true');
+
+# Insert data to verify incremental replication.
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_gen_to_nogen VALUES (4), (5)");
+
+# Verify that the generated column data is not replicated during incremental
+# synchronization when publish_generated_columns is set to false.
+$node_publisher->wait_for_catchup('regress_sub1_gen_to_nogen');
+$result = $node_subscriber->safe_psql('postgres',
+	"SELECT a, b FROM tab_gen_to_nogen ORDER BY a");
+is( $result, qq(1|
+2|
+3|
+4|
+5|),
+	'tab_gen_to_nogen incremental replication, when publish_generated_columns=false'
+);
+
+# Verify that generated column data is replicated during incremental
+# synchronization when publish_generated_columns is set to true.
+$node_publisher->wait_for_catchup('regress_sub2_gen_to_nogen');
+$result = $node_subscriber->safe_psql('test_pgc_true',
+	"SELECT a, b FROM tab_gen_to_nogen ORDER BY a");
+is( $result, qq(1|2
+2|4
+3|6
+4|8
+5|10),
+	'tab_gen_to_nogen incremental replication, when publish_generated_columns=true'
+);
+
+# cleanup
+$node_subscriber->safe_psql('postgres',
+	"DROP SUBSCRIPTION regress_sub1_gen_to_nogen");
+$node_subscriber->safe_psql('test_pgc_true',
+	"DROP SUBSCRIPTION regress_sub2_gen_to_nogen");
+$node_publisher->safe_psql(
+	'postgres', qq(
+	DROP PUBLICATION regress_pub1_gen_to_nogen;
+	DROP PUBLICATION regress_pub2_gen_to_nogen;
+));
+$node_subscriber->safe_psql('test_pgc_true', "DROP table tab_gen_to_nogen");
+$node_subscriber->safe_psql('postgres', "DROP DATABASE test_pgc_true");
+
+# =============================================================================
+# The following test cases demonstrate the behavior of generated column
+# replication with publish_generated_columns set to false and true:
+# Test: Publication column list includes generated columns when
+# publish_generated_columns is set to false.
+# Test: Publication column list excludes generated columns when
+# publish_generated_columns is set to false.
+# Test: Publication column list includes generated columns when
+# publish_generated_columns is set to true.
+# Test: Publication column list excludes generated columns when
+# publish_generated_columns is set to true.
+# =============================================================================
+
+# --------------------------------------------------
+# Test Case: Publisher replicates the column list, including generated columns,
+# even when the publish_generated_columns option is set to false.
+# --------------------------------------------------
+
+# Create table and publications.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab2 (a int, gen1 int GENERATED ALWAYS AS (a * 2) STORED);
+	CREATE TABLE tab3 (a int, gen1 int GENERATED ALWAYS AS (a * 2) STORED);
+	CREATE PUBLICATION pub1 FOR table tab2, tab3(gen1) WITH (publish_generated_columns=false);
+));
+
+# Insert values into tables.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	INSERT INTO tab2 (a) VALUES (1), (2);
+	INSERT INTO tab3 (a) VALUES (1), (2);
+));
+
+# Create table and subscription.
+$node_subscriber->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab2 (a int, gen1 int);
+	CREATE TABLE tab3 (a int, gen1 int);
+	CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1 WITH (copy_data = true);
+));
+
+# Wait for initial sync.
+$node_subscriber->wait_for_subscription_sync;
+$node_publisher->wait_for_catchup('sub1');
+
+# Verify that the initial synchronization of generated columns is not replicated
+# when they are not included in the column list, regardless of the
+# publish_generated_columns option.
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab2 ORDER BY a");
+is( $result, qq(1|
+2|),
+	'tab2 initial sync, when publish_generated_columns=false');
+
+# Verify that the initial synchronization of generated columns is replicated
+# when they are included in the column list, regardless of the
+# publish_generated_columns option.
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab3 ORDER BY a");
+is( $result, qq(|2
+|4),
+	'tab3 initial sync, when publish_generated_columns=false');
+
+# Insert data to verify incremental replication.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	INSERT INTO tab2 VALUES (3), (4);
+	INSERT INTO tab3 VALUES (3), (4);
+));
+
+# Verify that incremental replication of generated columns does not occur
+# when they are not included in the column list, regardless of the
+# publish_generated_columns option.
+$node_publisher->wait_for_catchup('sub1');
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab2 ORDER BY a");
+is( $result, qq(1|
+2|
+3|
+4|),
+	'tab2 incremental replication, when publish_generated_columns=false');
+
+# Verify that incremental replication of generated columns occurs
+# when they are included in the column list, regardless of the
+# publish_generated_columns option.
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab3 ORDER BY a");
+is( $result, qq(|2
+|4
+|6
+|8),
+	'tab3 incremental replication, when publish_generated_columns=false');
+
+# cleanup
+$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION sub1");
+$node_publisher->safe_psql('postgres', "DROP PUBLICATION pub1");
+
+# --------------------------------------------------
+# Test Case: Even when publish_generated_columns is set to true, the publisher
+# only publishes the data of columns specified in the column list,
+# skipping other generated and non-generated columns.
+# --------------------------------------------------
+
+# Create table and publications.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab4 (a int, gen1 int GENERATED ALWAYS AS (a * 2) STORED);
+	CREATE TABLE tab5 (a int, gen1 int GENERATED ALWAYS AS (a * 2) STORED);
+	CREATE PUBLICATION pub1 FOR table tab4, tab5(gen1) WITH (publish_generated_columns=true);
+));
+
+# Insert values into tables.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	INSERT INTO tab4 (a) VALUES (1), (2);
+	INSERT INTO tab5 (a) VALUES (1), (2);
+));
+
+# Create table and subscription.
+$node_subscriber->safe_psql(
+	'postgres', qq(
+	CREATE TABLE tab4 (a int, gen1 int);
+	CREATE TABLE tab5 (a int, gen1 int);
+	CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1 WITH (copy_data = true);
+));
+
+# Wait for initial sync.
+$node_subscriber->wait_for_subscription_sync;
+$node_publisher->wait_for_catchup('sub1');
+
+# Initial sync test when publish_generated_columns=true.
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab4 ORDER BY a");
+is( $result, qq(1|2
+2|4),
+	'tab4 initial sync, when publish_generated_columns=true');
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab5 ORDER BY a");
+is( $result, qq(|2
+|4),
+	'tab5 initial sync, when publish_generated_columns=true');
+
+# Insert data to verify incremental replication.
+$node_publisher->safe_psql(
+	'postgres', qq(
+	INSERT INTO tab4 VALUES (3), (4);
+	INSERT INTO tab5 VALUES (3), (4);
+));
+
+# Incremental replication test when publish_generated_columns=true.
+# Verify that column 'gen1' is replicated.
+$node_publisher->wait_for_catchup('sub1');
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab4 ORDER BY a");
+is( $result, qq(1|2
+2|4
+3|6
+4|8),
+	'tab4 incremental replication, when publish_generated_columns=true');
+$result =
+  $node_subscriber->safe_psql('postgres', "SELECT * FROM tab5 ORDER BY a");
+is( $result, qq(|2
+|4
+|6
+|8),
+	'tab5 incremental replication, when publish_generated_columns=true');
+
+# cleanup
+$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION sub1");
+$node_publisher->safe_psql('postgres', "DROP PUBLICATION pub1");
+
 done_testing();
-- 
2.34.1