From 6ff7c873d4842c47da22666d7efaba7551fb110b Mon Sep 17 00:00:00 2001 From: Mahendra Singh Thalor Date: Thu, 17 Jul 2025 15:24:25 +0530 Subject: [PATCH] use appendShellString to append file names --- doc/src/sgml/ref/pg_restore.sgml | 6 ++- src/bin/pg_dump/pg_dumpall.c | 67 ++++++++++++++++++-------------- src/bin/pg_dump/pg_restore.c | 28 +++++++------ 3 files changed, 60 insertions(+), 41 deletions(-) diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index b649bd3a5ae..f4eb31f2324 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -150,7 +150,9 @@ PostgreSQL documentation Access privileges for the database itself are also restored, unless is specified. is required when restoring multiple databases - from an archive created by pg_dumpall. + from an archive created by pg_dumpall and if + database is already created, then this will restore database without any + error. @@ -621,6 +623,8 @@ PostgreSQL documentation This option is only relevant when restoring from an archive made using pg_dumpall. + If there is no database connection exist, then pattern will be considered + as name only. diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 3cbcad65c5f..746c1f073c2 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -1622,8 +1622,8 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) { PGresult *res; int i; - char db_subdir[MAXPGPATH]; - char dbfilepath[MAXPGPATH]; + PQExpBufferData db_subdir; + PQExpBufferData dbfilepath; FILE *map_file = NULL; /* @@ -1653,20 +1653,28 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) */ if (archDumpFormat != archNull) { - char map_file_path[MAXPGPATH]; + PQExpBufferData map_file_path; - snprintf(db_subdir, MAXPGPATH, "%s/databases", filename); + initPQExpBuffer(&db_subdir); + initPQExpBuffer(&dbfilepath); + initPQExpBuffer(&map_file_path); + + appendShellString(&db_subdir, filename); + appendPQExpBufferChar(&db_subdir, '/'); + appendPQExpBufferStr(&db_subdir, "databases"); /* Create a subdirectory with 'databases' name under main directory. */ - if (mkdir(db_subdir, pg_dir_create_mode) != 0) - pg_fatal("could not create directory \"%s\": %m", db_subdir); + if (mkdir(db_subdir.data, pg_dir_create_mode) != 0) + pg_fatal("could not create directory \"%s\": %m", db_subdir.data); - snprintf(map_file_path, MAXPGPATH, "%s/map.dat", filename); + appendShellString(&map_file_path, filename); + appendPQExpBufferChar(&map_file_path, '/'); + appendPQExpBufferStr(&map_file_path, "map.dat"); /* Create a map file (to store dboid and dbname) */ - map_file = fopen(map_file_path, PG_BINARY_W); + map_file = fopen(map_file_path.data, PG_BINARY_W); if (!map_file) - pg_fatal("could not open file \"%s\": %m", map_file_path); + pg_fatal("could not open file \"%s\": %m", map_file_path.data); } for (i = 0; i < PQntuples(res); i++) @@ -1693,12 +1701,16 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) */ if (archDumpFormat != archNull) { + resetPQExpBuffer(&dbfilepath); + + appendShellString(&dbfilepath, db_subdir.data); + appendPQExpBufferChar(&dbfilepath, '/'); + appendShellString(&dbfilepath, oid); + if (archDumpFormat == archCustom) - snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\".dmp", db_subdir, oid); + appendPQExpBufferStr(&dbfilepath, ".dmp"); else if (archDumpFormat == archTar) - snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\".tar", db_subdir, oid); - else - snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\"", db_subdir, oid); + appendPQExpBufferStr(&dbfilepath, ".tar"); /* Put one line entry for dboid and dbname in map file. */ fprintf(map_file, "%s %s\n", oid, dbname); @@ -1731,23 +1743,20 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat) if (filename) fclose(OPF); - ret = runPgDump(dbname, create_opts, dbfilepath, archDumpFormat); + ret = runPgDump(dbname, create_opts, dbfilepath.data, archDumpFormat); if (ret != 0) pg_fatal("pg_dump failed on database \"%s\", exiting", dbname); - if (filename) + /* + * For non-plain mode, no need to re-open file as only once we write + * data into file. + */ + if (filename && archDumpFormat == archNull) { - char global_path[MAXPGPATH]; - - if (archDumpFormat != archNull) - snprintf(global_path, MAXPGPATH, "%s/global.dat", filename); - else - snprintf(global_path, MAXPGPATH, "%s", filename); - - OPF = fopen(global_path, PG_BINARY_A); + OPF = fopen(filename, PG_BINARY_A); if (!OPF) pg_fatal("could not re-open the output file \"%s\": %m", - global_path); + filename); } } @@ -1774,14 +1783,17 @@ runPgDump(const char *dbname, const char *create_opts, char *dbfile, initPQExpBuffer(&connstrbuf); initPQExpBuffer(&cmd); + printfPQExpBuffer(&cmd, "\"%s\" %s %s ", pg_dump_bin, + pgdumpopts->data, create_opts); + /* * If this is not a plain format dump, then append file name and dump * format to the pg_dump command to get archive dump. */ if (archDumpFormat != archNull) { - printfPQExpBuffer(&cmd, "\"%s\" -f %s %s", pg_dump_bin, - dbfile, create_opts); + + printfPQExpBuffer(&cmd, " -f %s ", dbfile); if (archDumpFormat == archDirectory) appendPQExpBufferStr(&cmd, " --format=directory "); @@ -1792,9 +1804,6 @@ runPgDump(const char *dbname, const char *create_opts, char *dbfile, } else { - printfPQExpBuffer(&cmd, "\"%s\" %s %s", pg_dump_bin, - pgdumpopts->data, create_opts); - /* * If we have a filename, use the undocumented plain-append pg_dump * format. diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 6ef789cb06d..4bb10971884 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -1038,7 +1038,7 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimplePtrList *dbname_oi { StringInfoData linebuf; FILE *pfile; - char map_file_path[MAXPGPATH]; + PQExpBufferData map_file_path; int count = 0; @@ -1052,13 +1052,16 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimplePtrList *dbname_oi return 0; } - snprintf(map_file_path, MAXPGPATH, "%s/map.dat", dumpdirpath); + initPQExpBuffer(&map_file_path); + appendShellString(&map_file_path, dumpdirpath); + appendPQExpBufferChar(&map_file_path, '/'); + appendPQExpBufferStr(&map_file_path, "map.dat"); /* Open map.dat file. */ - pfile = fopen(map_file_path, PG_BINARY_R); + pfile = fopen(map_file_path.data, PG_BINARY_R); if (pfile == NULL) - pg_fatal("could not open file \"%s\": %m", map_file_path); + pg_fatal("could not open file \"%s\": %m", map_file_path.data); initStringInfo(&linebuf); @@ -1086,11 +1089,11 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimplePtrList *dbname_oi /* Report error and exit if the file has any corrupted data. */ if (!OidIsValid(db_oid) || namelen <= 1) - pg_fatal("invalid entry in file \"%s\" on line %d", map_file_path, + pg_fatal("invalid entry in file \"%s\" on line %d", map_file_path.data, count + 1); pg_log_info("found database \"%s\" (OID: %u) in file \"%s\"", - dbname, db_oid, map_file_path); + dbname, db_oid, map_file_path.data); dbidname = pg_malloc(offsetof(DbOidName, str) + namelen + 1); dbidname->oid = db_oid; @@ -1306,20 +1309,23 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath, static int process_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *outfile) { - char global_file_path[MAXPGPATH]; + PQExpBufferData global_file_path; PGresult *result; StringInfoData sqlstatement, user_create; FILE *pfile; int n_errors = 0; - snprintf(global_file_path, MAXPGPATH, "%s/global.dat", dumpdirpath); + initPQExpBuffer(&global_file_path); + appendShellString(&global_file_path, dumpdirpath); + appendPQExpBufferChar(&global_file_path, '/'); + appendPQExpBufferStr(&global_file_path, "global.dat"); /* Open global.dat file. */ - pfile = fopen(global_file_path, PG_BINARY_R); + pfile = fopen(global_file_path.data, PG_BINARY_R); if (pfile == NULL) - pg_fatal("could not open file \"%s\": %m", global_file_path); + pg_fatal("could not open file \"%s\": %m", global_file_path.data); /* * If outfile is given, then just copy all global.dat file data into @@ -1369,7 +1375,7 @@ process_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *o if (n_errors) pg_log_warning(ngettext("ignored %d error in file \"%s\"", "ignored %d errors in file \"%s\"", n_errors), - n_errors, global_file_path); + n_errors, global_file_path.data); fclose(pfile); return n_errors; -- 2.39.3