From 57f112c5a76b2acecf19c9c9c14e0791670b2a22 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Thu, 22 Feb 2024 10:13:09 +0000
Subject: [PATCH v24 15/18] Call disconnect_database() even when the process
 would exit soon

---
 src/bin/pg_basebackup/pg_createsubscriber.c | 73 +++++++++++++++++++--
 1 file changed, 69 insertions(+), 4 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index a51943106a..86e277b339 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -419,6 +419,8 @@ connect_database(const char *conninfo)
 	{
 		pg_log_error("could not clear search_path: %s",
 					 PQresultErrorMessage(res));
+
+		disconnect_database(conn);
 		return NULL;
 	}
 	PQclear(res);
@@ -581,6 +583,8 @@ setup_publisher(LogicalRepInfo *dbinfo)
 		{
 			pg_log_error("could not obtain database OID: %s",
 						 PQresultErrorMessage(res));
+
+			disconnect_database(conn);
 			return false;
 		}
 
@@ -588,6 +592,8 @@ setup_publisher(LogicalRepInfo *dbinfo)
 		{
 			pg_log_error("could not obtain database OID: got %d rows, expected %d rows",
 						 PQntuples(res), 1);
+
+			disconnect_database(conn);
 			return false;
 		}
 
@@ -654,7 +660,10 @@ server_is_in_recovery(PGconn *conn)
 	res = PQexec(conn, "SELECT pg_catalog.pg_is_in_recovery()");
 
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		disconnect_database(conn);
 		pg_fatal("could not obtain recovery progress");
+	}
 
 	ret = strcmp("t", PQgetvalue(res, 0, 0));
 
@@ -690,7 +699,10 @@ check_publisher(LogicalRepInfo *dbinfo)
 	 * objects (publication) cannot be created because it is read only.
 	 */
 	if (server_is_in_recovery(conn))
+	{
+		disconnect_database(conn);
 		pg_fatal("primary server cannot be in recovery");
+	}
 
 	/*------------------------------------------------------------------------
 	 * Logical replication requires a few parameters to be set on publisher.
@@ -726,6 +738,8 @@ check_publisher(LogicalRepInfo *dbinfo)
 	{
 		pg_log_error("could not obtain publisher settings: %s",
 					 PQresultErrorMessage(res));
+
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -763,6 +777,8 @@ check_publisher(LogicalRepInfo *dbinfo)
 		{
 			pg_log_error("could not obtain replication slot information: %s",
 						 PQresultErrorMessage(res));
+
+			disconnect_database(conn);
 			return false;
 		}
 
@@ -770,6 +786,8 @@ check_publisher(LogicalRepInfo *dbinfo)
 		{
 			pg_log_error("could not obtain replication slot information: got %d rows, expected %d row",
 						 PQntuples(res), 1);
+
+			disconnect_database(conn);
 			return false;
 		}
 		else
@@ -832,6 +850,8 @@ check_subscriber(LogicalRepInfo *dbinfo)
 	if (!server_is_in_recovery(conn))
 	{
 		pg_log_error("The target server is not a standby");
+
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -845,14 +865,18 @@ check_subscriber(LogicalRepInfo *dbinfo)
 
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
 	{
-			pg_log_error("could not obtain walsender information");
-			return false;
+		pg_log_error("could not obtain walsender information");
+
+		disconnect_database(conn);
+		return false;
 	}
 
 	if (atoi(PQgetvalue(res, 0, 0)) != 0)
 	{
-			pg_log_error("the target server is primary to other server");
-			return false;
+		pg_log_error("the target server is primary to other server");
+
+		disconnect_database(conn);
+		return false;
 	}
 
 	/*
@@ -874,6 +898,8 @@ check_subscriber(LogicalRepInfo *dbinfo)
 	{
 		pg_log_error("could not obtain access privilege information: %s",
 					 PQresultErrorMessage(res));
+
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -882,6 +908,8 @@ check_subscriber(LogicalRepInfo *dbinfo)
 		pg_log_error("permission denied to create subscription");
 		pg_log_error_hint("Only roles with privileges of the \"%s\" role may create subscriptions.",
 						  "pg_create_subscription");
+
+		disconnect_database(conn);
 		return false;
 	}
 	if (strcmp(PQgetvalue(res, 0, 1), "t") != 0)
@@ -893,6 +921,8 @@ check_subscriber(LogicalRepInfo *dbinfo)
 	{
 		pg_log_error("permission denied for function \"%s\"",
 					 "pg_catalog.pg_replication_origin_advance(text, pg_lsn)");
+
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -947,6 +977,9 @@ check_subscriber(LogicalRepInfo *dbinfo)
 					 num_dbs, max_repslots);
 		pg_log_error_hint("Consider increasing max_replication_slots to at least %d.",
 						  num_dbs);
+
+		PQclear(res);
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -956,6 +989,9 @@ check_subscriber(LogicalRepInfo *dbinfo)
 					 num_dbs, max_lrworkers);
 		pg_log_error_hint("Consider increasing max_logical_replication_workers to at least %d.",
 						  num_dbs);
+
+		PQclear(res);
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -965,6 +1001,9 @@ check_subscriber(LogicalRepInfo *dbinfo)
 					 num_dbs + 1, max_wprocs);
 		pg_log_error_hint("Consider increasing max_worker_processes to at least %d.",
 						  num_dbs + 1);
+
+		PQclear(res);
+		disconnect_database(conn);
 		return false;
 	}
 
@@ -1052,6 +1091,8 @@ create_logical_replication_slot(PGconn *conn, LogicalRepInfo *dbinfo,
 			pg_log_error("could not create replication slot \"%s\" on database \"%s\": %s",
 						 slot_name, dbinfo->dbname,
 						 PQresultErrorMessage(res));
+
+			disconnect_database(conn);
 			return lsn;
 		}
 	}
@@ -1253,6 +1294,7 @@ wait_for_end_recovery(const char *conninfo, const char *pg_ctl_path,
 		if (atoi(PQgetvalue(res, 0, 0)) == 0 &&
 			count++ > NUM_ACCEPTABLE_DISCONNECTION)
 		{
+			disconnect_database(conn);
 			stop_standby_server(pg_ctl_path, opt->subscriber_dir);
 			pg_fatal("standby disconnected from the primary");
 		}
@@ -1260,6 +1302,7 @@ wait_for_end_recovery(const char *conninfo, const char *pg_ctl_path,
 		/* Bail out after recovery_timeout seconds if this option is set */
 		if (opt->recovery_timeout > 0 && timer >= opt->recovery_timeout)
 		{
+			disconnect_database(conn);
 			stop_standby_server(pg_ctl_path, opt->subscriber_dir);
 			pg_fatal("recovery timed out");
 		}
@@ -1297,8 +1340,11 @@ create_publication(PGconn *conn, LogicalRepInfo *dbinfo)
 					  dbinfo->pubname);
 	res = PQexec(conn, str->data);
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		disconnect_database(conn);
 		pg_fatal("could not obtain publication information: %s",
 				 PQresultErrorMessage(res));
+	}
 
 	if (atoi(PQgetvalue(res, 0, 0)) == 1)
 	{
@@ -1311,6 +1357,7 @@ create_publication(PGconn *conn, LogicalRepInfo *dbinfo)
 		 */
 		pg_log_error("publication \"%s\" already exists", dbinfo->pubname);
 		pg_log_error_hint("Consider renaming this publication.");
+		disconnect_database(conn);
 		exit(1);
 	}
 
@@ -1330,8 +1377,11 @@ create_publication(PGconn *conn, LogicalRepInfo *dbinfo)
 		res = PQexec(conn, str->data);
 
 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
+		{
+			disconnect_database(conn);
 			pg_fatal("could not create publication \"%s\" on database \"%s\": %s",
 					 dbinfo->pubname, dbinfo->dbname, PQresultErrorMessage(res));
+		}
 	}
 
 	/* for cleanup purposes */
@@ -1409,8 +1459,11 @@ create_subscription(PGconn *conn, LogicalRepInfo *dbinfo)
 		res = PQexec(conn, str->data);
 
 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
+		{
+			disconnect_database(conn);
 			pg_fatal("could not create subscription \"%s\" on database \"%s\": %s",
 					 dbinfo->subname, dbinfo->dbname, PQresultErrorMessage(res));
+		}
 	}
 
 	if (!dry_run)
@@ -1447,12 +1500,18 @@ set_replication_progress(PGconn *conn, LogicalRepInfo *dbinfo, const char *lsn)
 
 	res = PQexec(conn, str->data);
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		disconnect_database(conn);
 		pg_fatal("could not obtain subscription OID: %s",
 				 PQresultErrorMessage(res));
+	}
 
 	if (PQntuples(res) != 1 && !dry_run)
+	{
+		disconnect_database(conn);
 		pg_fatal("could not obtain subscription OID: got %d rows, expected %d rows",
 				 PQntuples(res), 1);
+	}
 
 	if (dry_run)
 	{
@@ -1489,8 +1548,11 @@ set_replication_progress(PGconn *conn, LogicalRepInfo *dbinfo, const char *lsn)
 		res = PQexec(conn, str->data);
 
 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
+		{
+			disconnect_database(conn);
 			pg_fatal("could not set replication progress for the subscription \"%s\": %s",
 					 dbinfo->subname, PQresultErrorMessage(res));
+		}
 
 		PQclear(res);
 	}
@@ -1525,8 +1587,11 @@ enable_subscription(PGconn *conn, LogicalRepInfo *dbinfo)
 		res = PQexec(conn, str->data);
 
 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
+		{
+			disconnect_database(conn);
 			pg_fatal("could not enable subscription \"%s\": %s",
 					 dbinfo->subname, PQresultErrorMessage(res));
+		}
 
 		PQclear(res);
 	}
-- 
2.43.0

