From b84f38deac1b02f057bfc05ff868fbf4a621b18b Mon Sep 17 00:00:00 2001
From: Onder Kalaci <onderkalaci@gmail.com>
Date: Thu, 16 Mar 2023 18:18:37 +0300
Subject: [PATCH v1 2/2] Ignore generated columns when REPLICA IDENTITY FULL

Generated columns are filled with NULL values on slot_store_data()
but not on table_scan_getnextslot(). With this commit, we skip
such columns while checking tuple equality.
---
 src/backend/executor/execReplication.c |  5 +++--
 src/test/subscription/t/100_bugs.pl    | 10 +++++++++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 7c8b0d2667..482806961a 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -290,10 +290,11 @@ tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2,
 		TypeCacheEntry *typentry;
 
 		/*
-		 * Ignore dropped columns as the publisher doesn't send those
+		 * Ignore dropped and generated columns as the publisher doesn't
+		 * send those
 		 */
 		att = TupleDescAttr(slot1->tts_tupleDescriptor, attrnum);
-		if (att->attisdropped)
+		if (att->attisdropped || att->attgenerated)
 			continue;
 
 		/*
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index 255746094c..96126428f3 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -387,14 +387,18 @@ $node_publisher_d_cols->safe_psql(
 	'postgres', qq(
 	CREATE TABLE dropped_cols (a int, b_drop int, c int);
 	ALTER TABLE dropped_cols REPLICA IDENTITY FULL;
-	CREATE PUBLICATION pub_dropped_cols FOR TABLE dropped_cols;
+	CREATE TABLE generated_cols (a int, b_gen int GENERATED ALWAYS AS (5 * a) STORED, c int);
+	ALTER TABLE generated_cols REPLICA IDENTITY FULL;
+	CREATE PUBLICATION pub_dropped_cols FOR TABLE dropped_cols, generated_cols;
 	-- some initial data
 	INSERT INTO dropped_cols VALUES (1, 1, 1);
+	INSERT INTO generated_cols (a,c) VALUES (1, 1);
 ));
 
 $node_subscriber_d_cols->safe_psql(
 	'postgres', qq(
 	 CREATE TABLE dropped_cols (a int, b_drop int, c int);
+	 CREATE TABLE generated_cols (a int, b_gen int GENERATED ALWAYS AS (5 * a) STORED, c int);
 ));
 
 my $publisher_connstr_d_cols = $node_publisher_d_cols->connstr . ' dbname=postgres';
@@ -415,12 +419,16 @@ $node_subscriber_d_cols->safe_psql(
 $node_publisher_d_cols->safe_psql(
 	'postgres', qq(
 		UPDATE dropped_cols SET a = 100;
+		UPDATE generated_cols SET a = 100;
 ));
 $node_publisher_d_cols->wait_for_catchup('sub_dropped_cols');
 
 is($node_subscriber_d_cols->safe_psql('postgres', "SELECT count(*) FROM dropped_cols WHERE a = 100"),
 	qq(1), 'replication with RI FULL and dropped columns');
 
+is($node_subscriber_d_cols->safe_psql('postgres', "SELECT count(*) FROM generated_cols WHERE a = 100"),
+	qq(1), 'replication with RI FULL and generated columns');
+
 $node_publisher_d_cols->stop('fast');
 $node_subscriber_d_cols->stop('fast');
 
-- 
2.34.1

