From ca24f775d1222cf877b5f084c49a940c04da6ce2 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Wed, 8 Jan 2025 19:50:54 +0530
Subject: [PATCH] pg_dumpall with directory/tar/custom format and restore it by
 pg_restore

new option to pg_dumpall:
-F, --format=d|t|c|p  output file format (directory, plain text (default))

Ex:1 ./pg_dumpall --format=directory --file=dumpDirName
Ex:2 ./pg_dumpall --format=tar --file=dumpDirName
Ex:3 ./pg_dumpall --format=custom --file=dumpDirName
Ex:4 ./pg_dumpall --format=plain --file=dumpDirName

dumps are as:
global.dat ::: global sql commands in simple plain format
map.dat.   ::: dboid dbname ---entries for all databases in simple text form
databases. :::
      subdir     dboid1  -> toc.dat and data files in archive format
      subdir     dboid2. -> toc.dat and data files in archive format
              etc
---------------------------------------------------------------------------
NOTE:
if needed, restore single db by particular subdir

Ex: ./pg_restore --format=directory -d postgres dumpDirName/databases/5
   -- here, 5 is the dboid of postgres db
   -- to get dboid, refer dbname in map.file

--------------------------------------------------------------------------
new options to pg_restore:
-g, --globals-only           restore only global objects, no databases
--exclude-database=PATTERN   exclude database whose name matches pattern

When we give -g/--globals-only option, then only restore globals, no db restoring.

Design:
When --format=d|t|c is specified and there is no toc.dat in main directory, then check
for global.dat and map.dat to restore all databases. If both files are exists in directory,
then first restore all globals from global.dat and then restore all databases one by one
from map.dat list.

TODO: We can dump and restore databases in parallel mode.
This needs more study.
---
 doc/src/sgml/ref/pg_dumpall.sgml |  36 +++++-
 src/bin/pg_dump/pg_dumpall.c     | 103 +++++++++------
 src/bin/pg_dump/pg_restore.c     | 213 +++++++++++++++++--------------
 3 files changed, 214 insertions(+), 138 deletions(-)

diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index 51deaae0d1..77a8d6a0c5 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -141,7 +141,12 @@ PostgreSQL documentation
          <term><literal>directory</literal></term>
          <listitem>
           <para>
-           The archive is a directory archive.
+           Output a directory-format archive suitable for input into pg_restore. This will create a directory
+           with one file for each table and large object being dumped, plus a so-called Table of Contents
+           file describing the dumped objects in a machine-readable format that pg_restore can read. A
+           directory format archive can be manipulated with standard Unix tools; for example, files in an
+           uncompressed archive can be compressed with the gzip, lz4, or zstd tools. This format is compressed
+           by default using gzip and also supports parallel dumps.
           </para>
          </listitem>
         </varlistentry>
@@ -151,10 +156,37 @@ PostgreSQL documentation
          <term><literal>plain</literal></term>
          <listitem>
           <para>
-           The archive is a plain archive.(by default also)
+           Output a plain-text SQL script file (the default).
           </para>
          </listitem>
         </varlistentry>
+
+        <varlistentry>
+         <term><literal>c</literal></term>
+         <term><literal>custom</literal></term>
+         <listitem>
+          <para>
+           Output a custom-format archive suitable for input into pg_restore. Together with the
+           directory output format, this is the most flexible output format in that it allows manual
+           selection and reordering of archived items during restore. This format is also
+           compressed by default.
+          </para>
+         </listitem>
+        </varlistentry>
+
+         <varlistentry>
+         <term><literal>t</literal></term>
+         <term><literal>tar</literal></term>
+         <listitem>
+          <para>
+           Output a tar-format archive suitable for input into pg_restore. The tar format is
+           compatible with the directory format: extracting a tar-format archive produces a valid
+           directory-format archive. However, the tar format does not support compression. Also,
+           when using tar format the relative order of table data items cannot be changed during restore.
+          </para>
+         </listitem>
+        </varlistentry>
+
         </variablelist>
         </para>
       </listitem>
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index ceb4c908d8..c26a14c617 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -66,10 +66,10 @@ static void dropTablespaces(PGconn *conn);
 static void dumpTablespaces(PGconn *conn);
 static void dropDBs(PGconn *conn);
 static void dumpUserConfig(PGconn *conn, const char *username);
-static void dumpDatabases(PGconn *conn, bool directory_format);
+static void dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat);
 static void dumpTimestamp(const char *msg);
 static int runPgDump(const char *dbname, const char *create_opts,
-					 char *dbfile);
+					 char *dbfile, ArchiveFormat archDumpFormat);
 static void buildShSecLabels(PGconn *conn,
 							 const char *catalog_name, Oid objectId,
 							 const char *objtype, const char *objname,
@@ -84,6 +84,7 @@ static void executeCommand(PGconn *conn, const char *query);
 static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
 								   SimpleStringList *names);
 static void read_dumpall_filters(const char *filename, SimpleStringList *pattern);
+static ArchiveFormat parseDumpFormat(const char *format);
 
 static char pg_dump_bin[MAXPGPATH];
 static const char *progname;
@@ -192,13 +193,13 @@ main(int argc, char *argv[])
 	char	   *pgdb = NULL;
 	char	   *use_role = NULL;
 	const char *dumpencoding = NULL;
-	const char *formatName = NULL;
+	ArchiveFormat archDumpFormat = archNull;
+	const char *formatName = "p";
 	trivalue	prompt_password = TRI_DEFAULT;
 	bool		data_only = false;
 	bool		globals_only = false;
 	bool		roles_only = false;
 	bool		tablespaces_only = false;
-	bool		directory_format = false;
 	PGconn	   *conn;
 	int			encoding;
 	const char *std_strings;
@@ -272,7 +273,7 @@ main(int argc, char *argv[])
 				appendShellString(pgdumpopts, filename);
 				break;
 			case 'F':
-				formatName = optarg;
+				formatName = pg_strdup(optarg);
 				break;
 			case 'g':
 				globals_only = true;
@@ -422,25 +423,7 @@ main(int argc, char *argv[])
 		exit_nicely(1);
 	}
 
-	if (formatName)
-	{
-		switch (formatName[0])
-		{
-			case 'd':
-			case 'D':
-				directory_format = true;
-				break;
-
-			case 'p':
-			case 'P':
-				/* Default plain format. */
-				break;
-
-			default:
-				pg_fatal("unrecognized dump format \"%s\"; please specify \"d\", or \"p\" ",
-						formatName);
-		}
-	}
+	archDumpFormat = parseDumpFormat(formatName);
 
 	/*
 	 * If password values are not required in the dump, switch to using
@@ -527,7 +510,7 @@ main(int argc, char *argv[])
 	/*
 	 * Open the output file if required, otherwise use stdout.
 	 */
-	if (directory_format)
+	if (archDumpFormat != archNull)
 	{
 		char	toc_path[MAXPGPATH];
 
@@ -657,7 +640,7 @@ main(int argc, char *argv[])
 	}
 
 	if (!globals_only && !roles_only && !tablespaces_only)
-		dumpDatabases(conn, directory_format);
+		dumpDatabases(conn, archDumpFormat);
 
 	PQfinish(conn);
 
@@ -670,7 +653,7 @@ main(int argc, char *argv[])
 		fclose(OPF);
 
 		/* sync the resulting file, errors are not fatal */
-		if (dosync && !directory_format)
+		if (dosync && (archDumpFormat == archNull))
 			(void) fsync_fname(filename, false);
 	}
 
@@ -1538,7 +1521,7 @@ expand_dbname_patterns(PGconn *conn,
  * Dump contents of databases.
  */
 static void
-dumpDatabases(PGconn *conn, bool directory_format)
+dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat)
 {
 	PGresult   *res;
 	int			i;
@@ -1571,7 +1554,7 @@ dumpDatabases(PGconn *conn, bool directory_format)
 	 * main directory and each database dump file will be created under the
 	 * subdirectory in archive mode as per single db pg_dump.
 	 */
-	if (directory_format)
+	if (archDumpFormat != archNull)
 	{
 		char    map_file_path[MAXPGPATH];
 
@@ -1597,7 +1580,7 @@ dumpDatabases(PGconn *conn, bool directory_format)
 		if (strcmp(dbname, "template0") == 0)
 			continue;
 
-		if (directory_format)
+		if (archDumpFormat != archNull)
 		{
 			snprintf(dbfilepath, MAXPGPATH, "-f %s/%s", db_subdir, oid);
 
@@ -1614,7 +1597,7 @@ dumpDatabases(PGconn *conn, bool directory_format)
 
 		pg_log_info("dumping database \"%s\"", dbname);
 
-		if (!directory_format)
+		if (archDumpFormat == archNull)
 			fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname);
 
 		/*
@@ -1633,21 +1616,21 @@ dumpDatabases(PGconn *conn, bool directory_format)
 			{
 				create_opts = "";
 				/* Since pg_dump won't emit a \connect command, we must */
-				if (!directory_format)
+				if (archDumpFormat == archNull)
 					fprintf(OPF, "\\connect %s\n\n", dbname);
 			}
 		}
 		else
 			create_opts = "--create";
 
-		if (!directory_format && filename)
+		if ((archDumpFormat == archNull) && filename)
 			fclose(OPF);
 
-		ret = runPgDump(dbname, create_opts, directory_format ? dbfilepath : NULL);
+		ret = runPgDump(dbname, create_opts, dbfilepath, archDumpFormat);
 		if (ret != 0)
 			pg_fatal("pg_dump failed on database \"%s\", exiting", dbname);
 
-		if (!directory_format && filename)
+		if ((archDumpFormat == archNull) && filename)
 		{
 			OPF = fopen(filename, PG_BINARY_A);
 			if (!OPF)
@@ -1656,8 +1639,8 @@ dumpDatabases(PGconn *conn, bool directory_format)
 		}
 	}
 
-	/* close map file */
-	if (directory_format)
+	/* Close map file */
+	if (archDumpFormat != archNull)
 		fclose(map_file);
 
 	PQclear(res);
@@ -1669,7 +1652,8 @@ dumpDatabases(PGconn *conn, bool directory_format)
  * Run pg_dump on dbname, with specified options.
  */
 static int
-runPgDump(const char *dbname, const char *create_opts, char *dbfile)
+runPgDump(const char *dbname, const char *create_opts, char *dbfile,
+		ArchiveFormat archDumpFormat)
 {
 	PQExpBufferData connstrbuf;
 	PQExpBufferData cmd;
@@ -1678,11 +1662,23 @@ runPgDump(const char *dbname, const char *create_opts, char *dbfile)
 	initPQExpBuffer(&connstrbuf);
 	initPQExpBuffer(&cmd);
 
-	if (dbfile)
+	/*
+	 * If this is not a plain dump, then append file name and dump format to
+	 * the pg_dump command.
+	 */
+	if (archDumpFormat != archNull)
 	{
 		printfPQExpBuffer(&cmd, "\"%s\" %s %s", pg_dump_bin,
 						  dbfile, create_opts);
-		appendPQExpBufferStr(&cmd, " -F d ");
+
+		if (archDumpFormat == archDirectory)
+			appendPQExpBufferStr(&cmd, " -F d ");
+		else if (archDumpFormat == archCustom)
+			appendPQExpBufferStr(&cmd, " -F c ");
+		else if (archDumpFormat == archTar)
+			appendPQExpBufferStr(&cmd, " -F t ");
+		else
+			pg_fatal("invalid dump format %d, specified, please use d/c/p only", archDumpFormat);
 	}
 	else
 	{
@@ -2092,3 +2088,30 @@ read_dumpall_filters(const char *filename, SimpleStringList *pattern)
 
 	filter_free(&fstate);
 }
+
+static ArchiveFormat
+parseDumpFormat(const char *format)
+{
+	ArchiveFormat	archDumpFormat;
+
+	if (pg_strcasecmp(format, "c") == 0)
+		archDumpFormat = archCustom;
+	else if (pg_strcasecmp(format, "custom") == 0)
+		archDumpFormat = archCustom;
+	else if (pg_strcasecmp(format, "d") == 0)
+		archDumpFormat = archDirectory;
+	else if (pg_strcasecmp(format, "directory") == 0)
+		archDumpFormat = archDirectory;
+	else if (pg_strcasecmp(format, "p") == 0)
+		archDumpFormat = archNull;
+	else if (pg_strcasecmp(format, "plain") == 0)
+		archDumpFormat = archNull;
+	else if (pg_strcasecmp(format, "t") == 0)
+		archDumpFormat = archTar;
+	else if (pg_strcasecmp(format, "tar") == 0)
+		archDumpFormat = archTar;
+	else
+		pg_fatal("invalid dump format \"%s\" specified", format);
+
+	return archDumpFormat;
+}
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 273f2002f1..e6a70adea9 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -59,9 +59,9 @@
 
 typedef struct SimpleDatabaseOidListCell
 {
-	struct SimpleDatabaseOidListCell *next;
-	Oid         dboid;
-	const char  *dbname;
+	struct SimpleDatabaseOidListCell	*next;
+	Oid									db_oid;
+	const char							*db_name;
 } SimpleDatabaseOidListCell;
 
 typedef struct SimpleDatabaseOidList
@@ -71,11 +71,11 @@ typedef struct SimpleDatabaseOidList
 } SimpleDatabaseOidList;
 
 static void
-simple_dboid_list_append(SimpleDatabaseOidList *list, Oid dboid, const char *dbname);
+simple_db_oid_list_append(SimpleDatabaseOidList *list, Oid db_oid, const char *dbname);
 
 static void usage(const char *progname);
 static void read_restore_filters(const char *filename, RestoreOptions *opts);
-static bool _fileExistsInDirectory(const char *dir, const char *filename);
+static bool IsFileExistsInDirectory(const char *dir, const char *filename);
 static bool restoreOneDatabase(const char *inputFileSpec,
 		RestoreOptions *opts, int numWorkers);
 static PGconn *connectDatabase(const char *dbname, const char *conn_string,
@@ -90,12 +90,12 @@ static int filter_dbnames_for_restore(PGconn *conn,
 		SimpleDatabaseOidList *dbname_oid_list, SimpleStringList db_exclude_patterns);
 static int get_dbname_oid_list_from_mfile(const char *dumpdirpath,
 		SimpleDatabaseOidList *dbname_oid_list);
-static void simple_dboid_list_append(SimpleDatabaseOidList *list, Oid dboid,
+static void simple_db_oid_list_append(SimpleDatabaseOidList *list, Oid db_oid,
 		const char *dbname);
 static bool is_full_pattern(PGconn *conn, const char *str, const char *ptrn);
 static void simple_string_list_delete(SimpleStringList *list,
 		SimpleStringListCell *cell, SimpleStringListCell *prev);
-static void simple_dboid_list_delete(SimpleDatabaseOidList *list,
+static void simple_db_oid_list_delete(SimpleDatabaseOidList *list,
 		SimpleDatabaseOidListCell *cell, SimpleDatabaseOidListCell *prev);
 
 int
@@ -352,12 +352,8 @@ main(int argc, char **argv)
 				opts->exit_on_error = true;
 				break;
 			case 6:
-				/* list of databases those needs to skip while restoring */
+				/* list of databases patterns those needs to skip while restoring */
 				simple_string_list_append(&db_exclude_patterns, optarg);
-				/*
-				 * XXX: TODO as of now, considering only db names but we can
-				 * implement for patterns also.
-				 */
 				break;
 
 			default:
@@ -474,49 +470,53 @@ main(int argc, char **argv)
 	}
 
 	/*
-	 * If directory format, then first check that toc.dat file exist or not?
-	 *
-	 * if toc.dat exist, then no need to check for map.dat and global.dat
-	 *
+	 * If toc.dat file does not present in current path, then check for
+	 * global.dat and map.dat files.  If both files are present, then
+	 * restore all the databases from map.dat file list and skip restoring for
+	 * --exclude-database patterns.
 	 */
-	if (opts->format == archDirectory &&
-			inputFileSpec != NULL &&
-			!_fileExistsInDirectory(inputFileSpec, "toc.dat"))
+	if (inputFileSpec != NULL &&
+			!IsFileExistsInDirectory(inputFileSpec, "toc.dat"))
 	{
-		/* if global.dat and map.dat are exist, then open them */
-		if (_fileExistsInDirectory(pg_strdup(inputFileSpec), "global.dat")
-				&& _fileExistsInDirectory(pg_strdup(inputFileSpec), "map.dat"))
+		/* If global.dat and map.dat are exist, then proces them. */
+		if (IsFileExistsInDirectory(pg_strdup(inputFileSpec), "global.dat")
+				&& IsFileExistsInDirectory(pg_strdup(inputFileSpec), "map.dat"))
 		{
-			/* Found the global.dat and map.dat file so process. */
-			PGconn				*conn = NULL;
+			PGconn	*conn = NULL; /* Connection to restore global sql commands. */
 
+			/*
+			 * If we are restoring dump of multiple databases, then connection
+			 * should be given.
+			 */
 			if (opts->cparams.dbname == NULL)
-				pg_fatal(" -d/--dbanme should be given if using dump of dumpall and global.dat");
+				pg_fatal(" -d/--dbanme should be given when using archive dump of pg_dumpall");
 
+			/*
+			 * To restore multiple databases, create database option should be
+			 * specified.
+			 */
 			if (opts->createDB != 1)
-				pg_fatal("option -C/--create should be specified if using dump of dumpall with global.dat");
+				pg_fatal("option -C/--create should be specified when using dump of pg_dumpall");
 
-			/* Connect to database so that we can execute global.dat */
-			conn = connectDatabase(opts->cparams.dbname, NULL,
-					opts->cparams.pghost, opts->cparams.pgport, opts->cparams.username,
-					TRI_DEFAULT, false);
+			/* Connect to database to execute global sql commands from global.dat file. */
+			conn = connectDatabase(opts->cparams.dbname, NULL, opts->cparams.pghost,
+					opts->cparams.pgport, opts->cparams.username, TRI_DEFAULT, false);
 
 			if (!conn)
 				pg_fatal("could not connect to database \"%s\"", opts->cparams.dbname);
 
-			/* Open global.dat file and execute all the sql commands */
+			/* Open global.dat file and execute all the sql commands. */
 			execute_global_sql_commands(conn, inputFileSpec);
 
-			/* if globals-only, then return from here */
+			/* If globals-only, then return from here. */
 			if (globals_only)
 			{
 				PQfinish(conn);
 				return 0;
 			}
 
-			/* Now restore all the databases from map.dat file */
-			return restoreAllDatabases(conn, inputFileSpec,
-					db_exclude_patterns,
+			/* Now restore all the databases from map.dat file. */
+			return restoreAllDatabases(conn, inputFileSpec, db_exclude_patterns,
 					opts, numWorkers);
 		}/* end if */
 	}/* end if */
@@ -754,11 +754,16 @@ read_restore_filters(const char *filename, RestoreOptions *opts)
 	filter_free(&fstate);
 }
 
+/*
+ * IsFileExistsInDirectory
+ *
+ * Returns true if file exist in current directory.
+ */
 static bool
-_fileExistsInDirectory(const char *dir, const char *filename)
+IsFileExistsInDirectory(const char *dir, const char *filename)
 {
-	struct stat		st;
-	char			 buf[MAXPGPATH];
+	struct stat			st;
+	char				buf[MAXPGPATH];
 
 	if (snprintf(buf, MAXPGPATH, "%s/%s", dir, filename) >= MAXPGPATH)
 		pg_fatal("directory name too long: \"%s\"", dir);
@@ -767,27 +772,28 @@ _fileExistsInDirectory(const char *dir, const char *filename)
 }
 
 /*
+ * connectDatabase
+ *
  * Make a database connection with the given parameters.  An
  * interactive password prompt is automatically issued if required.
  *
  * If fail_on_error is false, we return NULL without printing any message
  * on failure, but preserve any prompted password for the next try.
- *
  */
 static PGconn *
 connectDatabase(const char *dbname, const char *connection_string,
 				const char *pghost, const char *pgport, const char *pguser,
 				trivalue prompt_password, bool fail_on_error)
 {
-	PGconn	   *conn;
-	bool		new_pass;
-	const char *remoteversion_str;
-	int			my_version;
-	const char **keywords = NULL;
-	const char **values = NULL;
-	PQconninfoOption *conn_opts = NULL;
-	static char *password = NULL;
-	static int  server_version;
+	PGconn				*conn;
+	bool				new_pass;
+	const char			*remoteversion_str;
+	int					my_version;
+	const char			**keywords = NULL;
+	const char			**values = NULL;
+	PQconninfoOption 	*conn_opts = NULL;
+	static char			*password = NULL;
+	static int			server_version;
 
 	if (prompt_password == TRI_YES && !password)
 		password = simple_prompt("Password: ", false);
@@ -798,10 +804,10 @@ connectDatabase(const char *dbname, const char *connection_string,
 	 */
 	do
 	{
-		int			argcount = 6;
-		PQconninfoOption *conn_opt;
-		char	   *err_msg = NULL;
-		int			i = 0;
+		int					argcount = 6;
+		PQconninfoOption	*conn_opt;
+		char				*err_msg = NULL;
+		int					i = 0;
 
 		free(keywords);
 		free(values);
@@ -949,12 +955,14 @@ connectDatabase(const char *dbname, const char *connection_string,
 }
 
 /*
+ * executeQuery
+ *
  * Run a query, return the results, exit program on failure.
  */
 static PGresult *
 executeQuery(PGconn *conn, const char *query)
 {
-	PGresult   *res;
+	PGresult	*res;
 
 	pg_log_info("executing %s", query);
 
@@ -970,20 +978,19 @@ executeQuery(PGconn *conn, const char *query)
 	return res;
 }
 
-/* ----------------
- *	ReadOneStatement()
+/*
+ *	ReadOneStatement
  *
  * This will start reading from passed file pointer using fgetc and read till
  * semicolon(sql statement terminator for global.sql file)
  *
  *	EOF is returned if end-of-file input is seen; time to shut down.
- * ----------------
  */
 
 static int
 ReadOneStatement(StringInfo inBuf, FILE *f_glo)
 {
-	int			c;				/* character read from getc() */
+	int			c; /* character read from getc() */
 
 	resetStringInfo(inBuf);
 
@@ -1015,6 +1022,8 @@ ReadOneStatement(StringInfo inBuf, FILE *f_glo)
 }
 
 /*
+ * filter_dbnames_for_restore
+ *
  * This will remove names from all dblist that are given with exclude-database
  * option.
  *
@@ -1024,24 +1033,25 @@ static int
 filter_dbnames_for_restore(PGconn *conn, SimpleDatabaseOidList *dbname_oid_list,
 		SimpleStringList db_exclude_patterns)
 {
-	int					countdb = 0;
-	SimpleDatabaseOidListCell	*cell = dbname_oid_list->head;
-	SimpleDatabaseOidListCell	*precell = NULL;
+	SimpleDatabaseOidListCell	*dboid_cell = dbname_oid_list->head;
+	SimpleDatabaseOidListCell	*dboidprecell = NULL;
+	int							count_db = 0;
 
 	/* Return 0 if there is no db to restore. */
-	if (cell == NULL)
+	if (dboid_cell == NULL)
 		return 0;
 
-	while (cell != NULL)
+	/* Process one by one all dbnames and if needs to skip restoring. */
+	while (dboid_cell != NULL)
 	{
-		bool					skip_db_restore = false;
-		SimpleStringListCell	*prev = NULL;
-		SimpleDatabaseOidListCell		*next = cell->next;
+		bool						skip_db_restore = false;
+		SimpleStringListCell		*prev = NULL;
+		SimpleDatabaseOidListCell	*next = dboid_cell->next;
 
 		/* Now match this dbname with exclude-database list. */
 		for (SimpleStringListCell *celldb = db_exclude_patterns.head; celldb; celldb = celldb->next)
 		{
-			if (is_full_pattern(conn, cell->dbname, celldb->val))
+			if (is_full_pattern(conn, dboid_cell->db_name, celldb->val))
 			{
 				/*
 				 * As we need to skip this dbname so set flag to remove it from
@@ -1062,22 +1072,25 @@ filter_dbnames_for_restore(PGconn *conn, SimpleDatabaseOidList *dbname_oid_list,
 
 		/* Increment count if db needs to be restored. */
 		if (skip_db_restore)
-			simple_dboid_list_delete(dbname_oid_list, cell, precell);
+			simple_db_oid_list_delete(dbname_oid_list, dboid_cell, dboidprecell);
 		else
 		{
-			countdb++; /* Increment db couter. */
-			precell = cell;
+			count_db++; /* Increment db couter. */
+			dboidprecell = dboid_cell;
 		}
 
-		cell = next; /* Process next dbname from dbname list. */
+		/* Process next dbname from dbname list. */
+		dboid_cell = next;
 	}
 
-	return countdb;
+	return count_db;
 }
 
 /*
+ * get_dbname_oid_list_from_mfile
+ *
  * Open map.dat file and read line by line and then prepare a list of database
- * names and correspoding dboid.
+ * names and correspoding db_oid.
  *
  * Returns, total number of database names in map.dat file.
  */
@@ -1097,19 +1110,19 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleDatabaseOidList *d
 	if (pfile == NULL)
 		pg_fatal("could not open map.dat file: %s", strerror(errno));
 
-	/* Append all the dbname and dboid to the list. */
+	/* Append all the dbname and db_oid to the list. */
 	while((fgets(line, MAXPGPATH, pfile)) != NULL)
 	{
-		Oid         dboid;
+		Oid         db_oid;
 		char        dbname[MAXPGPATH + 1];
 
-		/* Extract dbname and dboid from line */
-		sscanf(line, "%u %s" , &dboid, dbname);
+		/* Extract dbname and db_oid from line */
+		sscanf(line, "%u %s" , &db_oid, dbname);
 
-		pg_log_info("found dbname as :%s and dboid:%d in map.dat file while restoring", dbname, dboid);
+		pg_log_info("found dbname as :%s and db_oid:%d in map.dat file while restoring", dbname, db_oid);
 
 		/* Report error if file has any corrupted data. */
-		if (!OidIsValid(dboid) || strlen(dbname) == 0)
+		if (!OidIsValid(db_oid) || strlen(dbname) == 0)
 			pg_fatal("invalid entry in map.dat file at line : %d", count + 1);
 
 		/*
@@ -1117,7 +1130,7 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleDatabaseOidList *d
 		 * needs to skipped for restore or not but as of now, we are making
 		 * a list of all the databases.
 		 */
-		simple_dboid_list_append(dbname_oid_list, dboid, dbname);
+		simple_db_oid_list_append(dbname_oid_list, db_oid, dbname);
 		count++;
 	}
 
@@ -1128,6 +1141,8 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleDatabaseOidList *d
 }
 
 /*
+ * restoreAllDatabases
+ *
  * This will restore databases those dumps are present in
  * directory based on map.dat file mapping.
  *
@@ -1140,7 +1155,7 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 		int numWorkers)
 {
 	SimpleDatabaseOidList			dbname_oid_list = {NULL, NULL};
-	SimpleDatabaseOidListCell		*cell;
+	SimpleDatabaseOidListCell		*dboid_cell;
 	int								exit_code = 0;
 	int								num_db_restore;
 	int								num_total_db;
@@ -1171,9 +1186,9 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 	 * after skipping names of exclude-database.  Now we can launch parallel
 	 * workers to restore these databases.
 	 */
-	cell = dbname_oid_list.head;
+	dboid_cell = dbname_oid_list.head;
 
-	while(cell != NULL)
+	while(dboid_cell != NULL)
 	{
 		char		subdirpath[MAXPGPATH];
 		int			dbexit_code;
@@ -1188,16 +1203,16 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 			opts->cparams.override_dbname = NULL;
 		}
 
-		snprintf(subdirpath, MAXPGPATH, "%s/databases/%u", dumpdirpath, cell->dboid);
+		snprintf(subdirpath, MAXPGPATH, "%s/databases/%u", dumpdirpath, dboid_cell->db_oid);
 
 		/*
 		 * Database -d/--dbname is already created so reset createDB to ignore
 		 * database creation error.
 		 */
-		if (strcmp(cell->dbname, opts->cparams.dbname) == 0)
+		if (pg_strcasecmp(dboid_cell->db_name, opts->cparams.dbname) == 0)
 			opts->createDB = 0;
 
-		pg_log_info("restoring database \"%s\"", cell->dbname);
+		pg_log_info("restoring database \"%s\"", dboid_cell->db_name);
 
 		dbexit_code = restoreOneDatabase(subdirpath, opts, numWorkers);
 
@@ -1206,10 +1221,10 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 			exit_code = dbexit_code;
 
 		/* Set createDB option to create new database. */
-		if (strcmp(cell->dbname, opts->cparams.dbname) == 0)
+		if (pg_strcasecmp(dboid_cell->db_name, opts->cparams.dbname) == 0)
 			opts->createDB = 1;
 
-		cell = cell->next;
+		dboid_cell = dboid_cell->next;
 	} /* end while */
 
 	/* Log number of processed databases.*/
@@ -1219,10 +1234,11 @@ restoreAllDatabases(PGconn *conn, const char *dumpdirpath,
 }
 
 /*
+ * execute_global_sql_commands
+ *
  * This will open global.dat file and will execute all global sql commands one
  * by one statement.
- *
- * semicolon is considered as statement terminator.
+ * Semicolon is considered as statement terminator.
  */
 static void
 execute_global_sql_commands(PGconn *conn, const char *dumpdirpath)
@@ -1253,7 +1269,6 @@ execute_global_sql_commands(PGconn *conn, const char *dumpdirpath)
 			case PGRES_COMMAND_OK:
 			case PGRES_TUPLES_OK:
 			case PGRES_EMPTY_QUERY:
-			case PGRES_COPY_IN:
 				break;
 			default:
 				pg_log_error("could not execute query: %s \nCommand was: %s", PQerrorMessage(conn), sqlstatement.data);
@@ -1265,18 +1280,20 @@ execute_global_sql_commands(PGconn *conn, const char *dumpdirpath)
 }
 
 /*
+ * simple_db_oid_list_append
+ *
  * appends a node to the list in the end.
  */
 static void
-simple_dboid_list_append(SimpleDatabaseOidList *list, Oid dboid, const char *dbname)
+simple_db_oid_list_append(SimpleDatabaseOidList *list, Oid db_oid, const char *dbname)
 {
 	SimpleDatabaseOidListCell *cell;
 
 	cell = pg_malloc_object(SimpleDatabaseOidListCell);
 
 	cell->next = NULL;
-	cell->dboid = dboid;
-	cell->dbname = pg_strdup(dbname);
+	cell->db_oid = db_oid;
+	cell->db_name = pg_strdup(dbname);
 
 	if (list->tail)
 		list->tail->next = cell;
@@ -1286,6 +1303,8 @@ simple_dboid_list_append(SimpleDatabaseOidList *list, Oid dboid, const char *dbn
 }
 
 /*
+ * simple_string_list_delete
+ *
  * delete cell from string list.
  */
 static void
@@ -1305,10 +1324,12 @@ simple_string_list_delete(SimpleStringList *list, SimpleStringListCell *cell,
 }
 
 /*
+ * simple_db_oid_list_delete
+ *
  * delete cell from database and oid list.
  */
 static void
-simple_dboid_list_delete(SimpleDatabaseOidList *list, SimpleDatabaseOidListCell *cell,
+simple_db_oid_list_delete(SimpleDatabaseOidList *list, SimpleDatabaseOidListCell *cell,
 		SimpleDatabaseOidListCell *prev)
 {
 	if (prev == NULL)
@@ -1348,7 +1369,7 @@ is_full_pattern(PGconn *conn, const char *str, const char *ptrn)
 	{
 		if (PQntuples(result) == 1)
 		{
-			const char		*outstr;
+			const char	*outstr;
 
 			outstr = PQgetvalue(result, 0, 0);
 
@@ -1359,7 +1380,7 @@ is_full_pattern(PGconn *conn, const char *str, const char *ptrn)
 			 * If output string of substring function is matches with str, then
 			 * we can construct str from pattern.
 			 */
-			if (strcmp(outstr, str) == 0)
+			if (pg_strcasecmp(outstr, str) == 0)
 				return true;
 			else
 				return false;
-- 
2.39.3

