From f795accf5fede15476300a43ea27135708b5d1e1 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Mon, 31 Mar 2025 14:59:13 +0530
Subject: [PATCH] pg_restore: skip error for CRETE ROLE username

---
 src/bin/pg_dump/pg_restore.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 3d8be43241d..8ce5b790e51 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -64,7 +64,7 @@ static int	read_one_statement(StringInfo inBuf, FILE *pfile);
 static int	restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 								SimpleStringList db_exclude_patterns, RestoreOptions *opts, int numWorkers);
 static int	process_global_sql_commands(PGconn *conn, const char *dumpdirpath,
-										const char *outfile);
+										const char *outfile, const char *username);
 static void copy_or_print_global_file(const char *outfile, FILE *pfile);
 static int	get_dbnames_list_to_restore(PGconn *conn,
 										SimpleOidStringList * dbname_oid_list,
@@ -543,7 +543,7 @@ main(int argc, char **argv)
 			 * commands.
 			 */
 			n_errors = process_global_sql_commands(conn, inputFileSpec,
-												   opts->filename);
+												   opts->filename, opts->cparams.username);
 
 			if (conn)
 				PQfinish(conn);
@@ -1123,7 +1123,7 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 	 * file.
 	 */
 	if (dbname_oid_list.head == NULL)
-		return process_global_sql_commands(conn, dumpdirpath, opts->filename);
+		return process_global_sql_commands(conn, dumpdirpath, opts->filename, opts->cparams.username);
 
 	pg_log_info("found total %d database names in map.dat file", num_total_db);
 
@@ -1153,7 +1153,7 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 												 db_exclude_patterns);
 
 	/* Open global.dat file and execute/append all the global sql commands. */
-	n_errors_total = process_global_sql_commands(conn, dumpdirpath, opts->filename);
+	n_errors_total = process_global_sql_commands(conn, dumpdirpath, opts->filename, opts->cparams.username);
 
 	/* Close the db connection as we are done with globals and patterns. */
 	if (conn)
@@ -1280,11 +1280,13 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
  * returns the number of errors while processing global.dat
  */
 static int
-process_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *outfile)
+process_global_sql_commands(PGconn *conn, const char *dumpdirpath,
+		const char *outfile, const char *username)
 {
 	char		global_file_path[MAXPGPATH];
 	PGresult   *result;
 	StringInfoData sqlstatement;
+	StringInfoData rolesqlstatement;
 	FILE	   *pfile;
 	int			n_errors = 0;
 
@@ -1308,10 +1310,30 @@ process_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *o
 
 	/* Init sqlstatement to append commands. */
 	initStringInfo(&sqlstatement);
+	initStringInfo(&rolesqlstatement);
 
 	/* Process file till EOF and execute sql statements. */
 	while (read_one_statement(&sqlstatement, pfile) != EOF)
 	{
+		if (username)
+		{
+			appendStringInfoString(&rolesqlstatement, "\n\n--\n-- Roles\n--\n\nCREATE ROLE ");
+			appendStringInfoString(&rolesqlstatement, username);
+			appendStringInfoString(&rolesqlstatement, ";");
+		}
+
+		/*
+		 * If this command is for "CREATE ROLE username", then skip this as
+		 * current user is already created.
+		 */
+		if (username && strcmp(sqlstatement.data, rolesqlstatement.data) == 0)
+		{
+			resetStringInfo(&rolesqlstatement);
+			continue;
+		}
+
+		resetStringInfo(&rolesqlstatement);
+
 		pg_log_info("executing query: %s", sqlstatement.data);
 		result = PQexec(conn, sqlstatement.data);
 
-- 
2.39.3

