Hi,

I observed that, in logical replication when a subscriber is missing
some columns, it currently emits an error message that says "some"
columns are missing(see logicalrep_rel_open()), but it doesn't specify
what the missing column names are. The comment there also says that
finding the missing column names is a todo item(/* TODO, detail
message with names of missing columns */).

I propose a patch to find the missing columns on the subscriber
relation using the publisher relation columns and show them in the
error message which can make the error more informative to the user.

Here's a snapshot how the error looks with the patch:
2020-09-04 01:00:36.721 PDT [843128] ERROR:  logical replication
target relation "public.test_1" is missing "b1, d1" replicated columns
2020-09-04 01:00:46.784 PDT [843132] ERROR:  logical replication
target relation "public.test_1" is missing "b1" replicated columns
2020-09-06 21:24:53.645 PDT [902945] ERROR:  logical replication
target relation "public.test_1" is missing "a1, c1, d1, b1" replicated
columns

Thoughts?

With Regards,
Bharath Rupireddy.
EnterpriseDB: http://www.enterprisedb.com
From e923dc6ddfa9b41c70f351ba6ad7dc8cfa8dbde3 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddy@enterprisedb.com>
Date: Fri, 4 Sep 2020 21:10:52 -0700
Subject: [PATCH v1] Detail message with names of missing columns in logical
 replication

In logical replication when a subscriber is missing some columns,
it currently emits an error message that says "some" columns are
missing(see logicalrep_rel_open()), but it doesn't specify what
the missing column names are. The comment there also says that
finding the missing column names is a todo item(/* TODO, detail
message with names of missing columns */).

This patch finds the missing columns on the subscriber relation
using the publisher relation columns and show them in the error
message which makes error to be more informative to the user.
---
 src/backend/replication/logical/relation.c | 50 ++++++++++++++++++++--
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
index a60c73d74d..d34ea3ce39 100644
--- a/src/backend/replication/logical/relation.c
+++ b/src/backend/replication/logical/relation.c
@@ -227,6 +227,44 @@ logicalrep_rel_att_by_name(LogicalRepRelation *remoterel, const char *attname)
 	return -1;
 }
 
+/*
+ * Finds the attributes that are missing in the local relation
+ * compared to remote relation.
+ */
+static void
+logicalrep_find_missing_atts(Relation localrel,
+							 LogicalRepRelation *remoterel,
+							 StringInfo missingatts)
+{
+	int			i;
+	int         j;
+	TupleDesc	desc;
+
+	desc = RelationGetDescr(localrel);
+
+	for (i = 0; i < remoterel->natts; i++)
+	{
+		bool found = false;
+		for (j = 0; j < desc->natts; j++)
+		{
+			Form_pg_attribute attr = TupleDescAttr(desc, j);
+			if (strcmp(remoterel->attnames[i], NameStr(attr->attname)) == 0)
+			{
+				found = true;
+				break;
+			}
+		}
+
+		if (found == false)
+		{
+			if (missingatts->len == 0)
+				appendStringInfoString(missingatts, remoterel->attnames[i]);
+			else if (missingatts->len > 0)
+				appendStringInfo(missingatts, ", %s", remoterel->attnames[i]);
+		}
+	}
+}
+
 /*
  * Open the local relation associated with the remote one.
  *
@@ -322,13 +360,19 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
 				found++;
 		}
 
-		/* TODO, detail message with names of missing columns */
 		if (found < remoterel->natts)
+		{
+			StringInfoData missingatts;
+
+			initStringInfo(&missingatts);
+			logicalrep_find_missing_atts(entry->localrel, remoterel, &missingatts);
 			ereport(ERROR,
 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 					 errmsg("logical replication target relation \"%s.%s\" is missing "
-							"some replicated columns",
-							remoterel->nspname, remoterel->relname)));
+							"\"%s\" replicated columns",
+							remoterel->nspname, remoterel->relname,
+							missingatts.data)));
+		}
 
 		/*
 		 * Check that replica identity matches. We allow for stricter replica
-- 
2.25.1

Reply via email to