From 102b4a7f0c165238688d9f5487592e648dfb6ef8 Mon Sep 17 00:00:00 2001
From: Khanna <Shubham.Khanna@fujitsu.com>
Date: Wed, 26 Mar 2025 13:22:23 +0530
Subject: [PATCH v22 2/2] Fetch databases from publisher

This patch allows current functionality of --all to fetch databases from the
publisher and display them to the user.
---
 doc/src/sgml/ref/pg_createsubscriber.sgml   |  8 +++--
 src/bin/pg_basebackup/pg_createsubscriber.c | 34 ++++++++++++++++-----
 2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml
index 7d105079127..676dd933496 100644
--- a/doc/src/sgml/ref/pg_createsubscriber.sgml
+++ b/doc/src/sgml/ref/pg_createsubscriber.sgml
@@ -95,9 +95,11 @@ PostgreSQL documentation
        Create one subscription on the target server for each non-template
        database on the source server that allows connections, excluding
        template databases or databases with connection restrictions.
-       Automatically generated names for subscriptions, publications, and
-       replication slots are used when this option is specified. This option
-       cannot be used along with <option>--database</option>,
+       If database name is not specified in publisher-server, it will try to
+       connect with postgres/template1 database to fetch the databases from
+       primary. Automatically generated names for subscriptions, publications,
+       and replication slots are used when this option is specified.
+       This option cannot be used along with <option>--database</option>,
        <option>--publication</option>, <option>--replication-slot</option>, or
        <option>--subscription</option>.
       </para>
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index edf1b0ae119..1a545d56007 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -125,7 +125,8 @@ static void check_and_drop_existing_subscriptions(PGconn *conn,
 												  const struct LogicalRepInfo *dbinfo);
 static void drop_existing_subscriptions(PGconn *conn, const char *subname,
 										const char *dbname);
-static void get_publisher_databases(struct CreateSubscriberOptions *opt);
+static void get_publisher_databases(struct CreateSubscriberOptions *opt,
+									bool dbnamespecified);
 
 #define	USEC_PER_SEC	1000000
 #define	WAIT_INTERVAL	1		/* 1 second */
@@ -540,8 +541,9 @@ connect_database(const char *conninfo, bool exit_on_error)
 	conn = PQconnectdb(conninfo);
 	if (PQstatus(conn) != CONNECTION_OK)
 	{
-		pg_log_error("connection to database failed: %s",
-					 PQerrorMessage(conn));
+		if (exit_on_error)
+			pg_log_error("connection to database failed: %s",
+						 PQerrorMessage(conn));
 		PQfinish(conn);
 
 		if (exit_on_error)
@@ -1969,13 +1971,27 @@ enable_subscription(PGconn *conn, const struct LogicalRepInfo *dbinfo)
  * options, one for each source database.
  */
 static void
-get_publisher_databases(struct CreateSubscriberOptions *opt)
+get_publisher_databases(struct CreateSubscriberOptions *opt,
+						bool dbnamespecified)
 {
 	PGconn	   *conn;
 	PGresult   *res;
+	char	   *conninfo;
 
-	/* Establish a connection to the source server */
-	conn = connectMaintenanceDatabase(opt->pub_conninfo_str, true);
+	/* If a database name was specified, just connect to it. */
+	if (dbnamespecified)
+		conn = connect_database(opt->pub_conninfo_str, true);
+	else
+	{
+		/* Otherwise, try postgres first and then template1. */
+		conninfo = concat_conninfo_dbname(opt->pub_conninfo_str, "postgres");
+		conn = connect_database(conninfo, false);
+		if (!conn)
+		{
+			conninfo = concat_conninfo_dbname(opt->pub_conninfo_str, "template1");
+			conn = connect_database(conninfo, true);
+		}
+	}
 
 	res = PQexec(conn, "SELECT datname FROM pg_database WHERE datistemplate = false AND datallowconn AND datconnlimit <> -2 ORDER BY 1");
 
@@ -2277,7 +2293,11 @@ main(int argc, char **argv)
 	 * one for each source database.
 	 */
 	if (opt.all_dbs)
-		get_publisher_databases(&opt);
+	{
+		bool		dbnamespecified = (dbname_conninfo != NULL);
+
+		get_publisher_databases(&opt, dbnamespecified);
+	}
 	if (opt.database_names.head == NULL)
 	{
 		pg_log_info("no database was specified");
-- 
2.41.0.windows.3

