Clean up inconsistent use of fflush().
[pgsql.git] / src / bin / pg_dump / pg_dumpall.c
blobd665b257c93589c61ac6a3cb410928a0a0b2f4b5
1 /*-------------------------------------------------------------------------
3 * pg_dumpall.c
5 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * pg_dumpall forces all pg_dump output to be text, since it also outputs
9 * text into the same output stream.
11 * src/bin/pg_dump/pg_dumpall.c
13 *-------------------------------------------------------------------------
16 #include "postgres_fe.h"
18 #include <time.h>
19 #include <unistd.h>
21 #include "catalog/pg_authid_d.h"
22 #include "common/connect.h"
23 #include "common/file_utils.h"
24 #include "common/hashfn.h"
25 #include "common/logging.h"
26 #include "common/string.h"
27 #include "dumputils.h"
28 #include "fe_utils/string_utils.h"
29 #include "getopt_long.h"
30 #include "pg_backup.h"
32 /* version string we expect back from pg_dump */
33 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
35 static uint32 hash_string_pointer(char *s);
37 typedef struct
39 uint32 status;
40 uint32 hashval;
41 char *rolename;
42 } RoleNameEntry;
44 #define SH_PREFIX rolename
45 #define SH_ELEMENT_TYPE RoleNameEntry
46 #define SH_KEY_TYPE char *
47 #define SH_KEY rolename
48 #define SH_HASH_KEY(tb, key) hash_string_pointer(key)
49 #define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
50 #define SH_STORE_HASH
51 #define SH_GET_HASH(tb, a) (a)->hashval
52 #define SH_SCOPE static inline
53 #define SH_RAW_ALLOCATOR pg_malloc0
54 #define SH_DECLARE
55 #define SH_DEFINE
56 #include "lib/simplehash.h"
58 static void help(void);
60 static void dropRoles(PGconn *conn);
61 static void dumpRoles(PGconn *conn);
62 static void dumpRoleMembership(PGconn *conn);
63 static void dumpRoleGUCPrivs(PGconn *conn);
64 static void dropTablespaces(PGconn *conn);
65 static void dumpTablespaces(PGconn *conn);
66 static void dropDBs(PGconn *conn);
67 static void dumpUserConfig(PGconn *conn, const char *username);
68 static void dumpDatabases(PGconn *conn);
69 static void dumpTimestamp(const char *msg);
70 static int runPgDump(const char *dbname, const char *create_opts);
71 static void buildShSecLabels(PGconn *conn,
72 const char *catalog_name, Oid objectId,
73 const char *objtype, const char *objname,
74 PQExpBuffer buffer);
75 static PGconn *connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport,
76 const char *pguser, trivalue prompt_password, bool fail_on_error);
77 static char *constructConnStr(const char **keywords, const char **values);
78 static PGresult *executeQuery(PGconn *conn, const char *query);
79 static void executeCommand(PGconn *conn, const char *query);
80 static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
81 SimpleStringList *names);
83 static char pg_dump_bin[MAXPGPATH];
84 static const char *progname;
85 static PQExpBuffer pgdumpopts;
86 static char *connstr = "";
87 static bool output_clean = false;
88 static bool skip_acls = false;
89 static bool verbose = false;
90 static bool dosync = true;
92 static int binary_upgrade = 0;
93 static int column_inserts = 0;
94 static int disable_dollar_quoting = 0;
95 static int disable_triggers = 0;
96 static int if_exists = 0;
97 static int inserts = 0;
98 static int no_table_access_method = 0;
99 static int no_tablespaces = 0;
100 static int use_setsessauth = 0;
101 static int no_comments = 0;
102 static int no_publications = 0;
103 static int no_security_labels = 0;
104 static int no_subscriptions = 0;
105 static int no_toast_compression = 0;
106 static int no_unlogged_table_data = 0;
107 static int no_role_passwords = 0;
108 static int server_version;
109 static int load_via_partition_root = 0;
110 static int on_conflict_do_nothing = 0;
112 static char role_catalog[10];
113 #define PG_AUTHID "pg_authid"
114 #define PG_ROLES "pg_roles "
116 static FILE *OPF;
117 static char *filename = NULL;
119 static SimpleStringList database_exclude_patterns = {NULL, NULL};
120 static SimpleStringList database_exclude_names = {NULL, NULL};
122 #define exit_nicely(code) exit(code)
125 main(int argc, char *argv[])
127 static struct option long_options[] = {
128 {"data-only", no_argument, NULL, 'a'},
129 {"clean", no_argument, NULL, 'c'},
130 {"encoding", required_argument, NULL, 'E'},
131 {"file", required_argument, NULL, 'f'},
132 {"globals-only", no_argument, NULL, 'g'},
133 {"host", required_argument, NULL, 'h'},
134 {"dbname", required_argument, NULL, 'd'},
135 {"database", required_argument, NULL, 'l'},
136 {"no-owner", no_argument, NULL, 'O'},
137 {"port", required_argument, NULL, 'p'},
138 {"roles-only", no_argument, NULL, 'r'},
139 {"schema-only", no_argument, NULL, 's'},
140 {"superuser", required_argument, NULL, 'S'},
141 {"tablespaces-only", no_argument, NULL, 't'},
142 {"username", required_argument, NULL, 'U'},
143 {"verbose", no_argument, NULL, 'v'},
144 {"no-password", no_argument, NULL, 'w'},
145 {"password", no_argument, NULL, 'W'},
146 {"no-privileges", no_argument, NULL, 'x'},
147 {"no-acl", no_argument, NULL, 'x'},
150 * the following options don't have an equivalent short option letter
152 {"attribute-inserts", no_argument, &column_inserts, 1},
153 {"binary-upgrade", no_argument, &binary_upgrade, 1},
154 {"column-inserts", no_argument, &column_inserts, 1},
155 {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
156 {"disable-triggers", no_argument, &disable_triggers, 1},
157 {"exclude-database", required_argument, NULL, 6},
158 {"extra-float-digits", required_argument, NULL, 5},
159 {"if-exists", no_argument, &if_exists, 1},
160 {"inserts", no_argument, &inserts, 1},
161 {"lock-wait-timeout", required_argument, NULL, 2},
162 {"no-table-access-method", no_argument, &no_table_access_method, 1},
163 {"no-tablespaces", no_argument, &no_tablespaces, 1},
164 {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
165 {"load-via-partition-root", no_argument, &load_via_partition_root, 1},
166 {"role", required_argument, NULL, 3},
167 {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
168 {"no-comments", no_argument, &no_comments, 1},
169 {"no-publications", no_argument, &no_publications, 1},
170 {"no-role-passwords", no_argument, &no_role_passwords, 1},
171 {"no-security-labels", no_argument, &no_security_labels, 1},
172 {"no-subscriptions", no_argument, &no_subscriptions, 1},
173 {"no-sync", no_argument, NULL, 4},
174 {"no-toast-compression", no_argument, &no_toast_compression, 1},
175 {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
176 {"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1},
177 {"rows-per-insert", required_argument, NULL, 7},
179 {NULL, 0, NULL, 0}
182 char *pghost = NULL;
183 char *pgport = NULL;
184 char *pguser = NULL;
185 char *pgdb = NULL;
186 char *use_role = NULL;
187 const char *dumpencoding = NULL;
188 trivalue prompt_password = TRI_DEFAULT;
189 bool data_only = false;
190 bool globals_only = false;
191 bool roles_only = false;
192 bool tablespaces_only = false;
193 PGconn *conn;
194 int encoding;
195 const char *std_strings;
196 int c,
197 ret;
198 int optindex;
200 pg_logging_init(argv[0]);
201 pg_logging_set_level(PG_LOG_WARNING);
202 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
203 progname = get_progname(argv[0]);
205 if (argc > 1)
207 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
209 help();
210 exit_nicely(0);
212 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
214 puts("pg_dumpall (PostgreSQL) " PG_VERSION);
215 exit_nicely(0);
219 if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
220 pg_dump_bin)) < 0)
222 char full_path[MAXPGPATH];
224 if (find_my_exec(argv[0], full_path) < 0)
225 strlcpy(full_path, progname, sizeof(full_path));
227 if (ret == -1)
228 pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
229 "pg_dump", progname, full_path);
230 else
231 pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s",
232 "pg_dump", full_path, progname);
235 pgdumpopts = createPQExpBuffer();
237 while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:Op:rsS:tU:vwWx", long_options, &optindex)) != -1)
239 switch (c)
241 case 'a':
242 data_only = true;
243 appendPQExpBufferStr(pgdumpopts, " -a");
244 break;
246 case 'c':
247 output_clean = true;
248 break;
250 case 'd':
251 connstr = pg_strdup(optarg);
252 break;
254 case 'E':
255 dumpencoding = pg_strdup(optarg);
256 appendPQExpBufferStr(pgdumpopts, " -E ");
257 appendShellString(pgdumpopts, optarg);
258 break;
260 case 'f':
261 filename = pg_strdup(optarg);
262 appendPQExpBufferStr(pgdumpopts, " -f ");
263 appendShellString(pgdumpopts, filename);
264 break;
266 case 'g':
267 globals_only = true;
268 break;
270 case 'h':
271 pghost = pg_strdup(optarg);
272 break;
274 case 'l':
275 pgdb = pg_strdup(optarg);
276 break;
278 case 'O':
279 appendPQExpBufferStr(pgdumpopts, " -O");
280 break;
282 case 'p':
283 pgport = pg_strdup(optarg);
284 break;
286 case 'r':
287 roles_only = true;
288 break;
290 case 's':
291 appendPQExpBufferStr(pgdumpopts, " -s");
292 break;
294 case 'S':
295 appendPQExpBufferStr(pgdumpopts, " -S ");
296 appendShellString(pgdumpopts, optarg);
297 break;
299 case 't':
300 tablespaces_only = true;
301 break;
303 case 'U':
304 pguser = pg_strdup(optarg);
305 break;
307 case 'v':
308 verbose = true;
309 pg_logging_increase_verbosity();
310 appendPQExpBufferStr(pgdumpopts, " -v");
311 break;
313 case 'w':
314 prompt_password = TRI_NO;
315 appendPQExpBufferStr(pgdumpopts, " -w");
316 break;
318 case 'W':
319 prompt_password = TRI_YES;
320 appendPQExpBufferStr(pgdumpopts, " -W");
321 break;
323 case 'x':
324 skip_acls = true;
325 appendPQExpBufferStr(pgdumpopts, " -x");
326 break;
328 case 0:
329 break;
331 case 2:
332 appendPQExpBufferStr(pgdumpopts, " --lock-wait-timeout ");
333 appendShellString(pgdumpopts, optarg);
334 break;
336 case 3:
337 use_role = pg_strdup(optarg);
338 appendPQExpBufferStr(pgdumpopts, " --role ");
339 appendShellString(pgdumpopts, use_role);
340 break;
342 case 4:
343 dosync = false;
344 appendPQExpBufferStr(pgdumpopts, " --no-sync");
345 break;
347 case 5:
348 appendPQExpBufferStr(pgdumpopts, " --extra-float-digits ");
349 appendShellString(pgdumpopts, optarg);
350 break;
352 case 6:
353 simple_string_list_append(&database_exclude_patterns, optarg);
354 break;
356 case 7:
357 appendPQExpBufferStr(pgdumpopts, " --rows-per-insert ");
358 appendShellString(pgdumpopts, optarg);
359 break;
361 default:
362 /* getopt_long already emitted a complaint */
363 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
364 exit_nicely(1);
368 /* Complain if any arguments remain */
369 if (optind < argc)
371 pg_log_error("too many command-line arguments (first is \"%s\")",
372 argv[optind]);
373 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
374 exit_nicely(1);
377 if (database_exclude_patterns.head != NULL &&
378 (globals_only || roles_only || tablespaces_only))
380 pg_log_error("option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only");
381 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
382 exit_nicely(1);
385 /* Make sure the user hasn't specified a mix of globals-only options */
386 if (globals_only && roles_only)
388 pg_log_error("options -g/--globals-only and -r/--roles-only cannot be used together");
389 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
390 exit_nicely(1);
393 if (globals_only && tablespaces_only)
395 pg_log_error("options -g/--globals-only and -t/--tablespaces-only cannot be used together");
396 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
397 exit_nicely(1);
400 if (if_exists && !output_clean)
401 pg_fatal("option --if-exists requires option -c/--clean");
403 if (roles_only && tablespaces_only)
405 pg_log_error("options -r/--roles-only and -t/--tablespaces-only cannot be used together");
406 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
407 exit_nicely(1);
411 * If password values are not required in the dump, switch to using
412 * pg_roles which is equally useful, just more likely to have unrestricted
413 * access than pg_authid.
415 if (no_role_passwords)
416 sprintf(role_catalog, "%s", PG_ROLES);
417 else
418 sprintf(role_catalog, "%s", PG_AUTHID);
420 /* Add long options to the pg_dump argument list */
421 if (binary_upgrade)
422 appendPQExpBufferStr(pgdumpopts, " --binary-upgrade");
423 if (column_inserts)
424 appendPQExpBufferStr(pgdumpopts, " --column-inserts");
425 if (disable_dollar_quoting)
426 appendPQExpBufferStr(pgdumpopts, " --disable-dollar-quoting");
427 if (disable_triggers)
428 appendPQExpBufferStr(pgdumpopts, " --disable-triggers");
429 if (inserts)
430 appendPQExpBufferStr(pgdumpopts, " --inserts");
431 if (no_table_access_method)
432 appendPQExpBufferStr(pgdumpopts, " --no-table-access-method");
433 if (no_tablespaces)
434 appendPQExpBufferStr(pgdumpopts, " --no-tablespaces");
435 if (quote_all_identifiers)
436 appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers");
437 if (load_via_partition_root)
438 appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root");
439 if (use_setsessauth)
440 appendPQExpBufferStr(pgdumpopts, " --use-set-session-authorization");
441 if (no_comments)
442 appendPQExpBufferStr(pgdumpopts, " --no-comments");
443 if (no_publications)
444 appendPQExpBufferStr(pgdumpopts, " --no-publications");
445 if (no_security_labels)
446 appendPQExpBufferStr(pgdumpopts, " --no-security-labels");
447 if (no_subscriptions)
448 appendPQExpBufferStr(pgdumpopts, " --no-subscriptions");
449 if (no_toast_compression)
450 appendPQExpBufferStr(pgdumpopts, " --no-toast-compression");
451 if (no_unlogged_table_data)
452 appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data");
453 if (on_conflict_do_nothing)
454 appendPQExpBufferStr(pgdumpopts, " --on-conflict-do-nothing");
457 * If there was a database specified on the command line, use that,
458 * otherwise try to connect to database "postgres", and failing that
459 * "template1".
461 if (pgdb)
463 conn = connectDatabase(pgdb, connstr, pghost, pgport, pguser,
464 prompt_password, false);
466 if (!conn)
467 pg_fatal("could not connect to database \"%s\"", pgdb);
469 else
471 conn = connectDatabase("postgres", connstr, pghost, pgport, pguser,
472 prompt_password, false);
473 if (!conn)
474 conn = connectDatabase("template1", connstr, pghost, pgport, pguser,
475 prompt_password, true);
477 if (!conn)
479 pg_log_error("could not connect to databases \"postgres\" or \"template1\"\n"
480 "Please specify an alternative database.");
481 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
482 exit_nicely(1);
487 * Get a list of database names that match the exclude patterns
489 expand_dbname_patterns(conn, &database_exclude_patterns,
490 &database_exclude_names);
493 * Open the output file if required, otherwise use stdout
495 if (filename)
497 OPF = fopen(filename, PG_BINARY_W);
498 if (!OPF)
499 pg_fatal("could not open output file \"%s\": %m",
500 filename);
502 else
503 OPF = stdout;
506 * Set the client encoding if requested.
508 if (dumpencoding)
510 if (PQsetClientEncoding(conn, dumpencoding) < 0)
511 pg_fatal("invalid client encoding \"%s\" specified",
512 dumpencoding);
516 * Get the active encoding and the standard_conforming_strings setting, so
517 * we know how to escape strings.
519 encoding = PQclientEncoding(conn);
520 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
521 if (!std_strings)
522 std_strings = "off";
524 /* Set the role if requested */
525 if (use_role)
527 PQExpBuffer query = createPQExpBuffer();
529 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
530 executeCommand(conn, query->data);
531 destroyPQExpBuffer(query);
534 /* Force quoting of all identifiers if requested. */
535 if (quote_all_identifiers)
536 executeCommand(conn, "SET quote_all_identifiers = true");
538 fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
539 if (verbose)
540 dumpTimestamp("Started on");
543 * We used to emit \connect postgres here, but that served no purpose
544 * other than to break things for installations without a postgres
545 * database. Everything we're restoring here is a global, so whichever
546 * database we're connected to at the moment is fine.
549 /* Restore will need to write to the target cluster */
550 fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
552 /* Replicate encoding and std_strings in output */
553 fprintf(OPF, "SET client_encoding = '%s';\n",
554 pg_encoding_to_char(encoding));
555 fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
556 if (strcmp(std_strings, "off") == 0)
557 fprintf(OPF, "SET escape_string_warning = off;\n");
558 fprintf(OPF, "\n");
560 if (!data_only)
563 * If asked to --clean, do that first. We can avoid detailed
564 * dependency analysis because databases never depend on each other,
565 * and tablespaces never depend on each other. Roles could have
566 * grants to each other, but DROP ROLE will clean those up silently.
568 if (output_clean)
570 if (!globals_only && !roles_only && !tablespaces_only)
571 dropDBs(conn);
573 if (!roles_only && !no_tablespaces)
574 dropTablespaces(conn);
576 if (!tablespaces_only)
577 dropRoles(conn);
581 * Now create objects as requested. Be careful that option logic here
582 * is the same as for drops above.
584 if (!tablespaces_only)
586 /* Dump roles (users) */
587 dumpRoles(conn);
589 /* Dump role memberships */
590 dumpRoleMembership(conn);
592 /* Dump role GUC privileges */
593 if (server_version >= 150000 && !skip_acls)
594 dumpRoleGUCPrivs(conn);
597 /* Dump tablespaces */
598 if (!roles_only && !no_tablespaces)
599 dumpTablespaces(conn);
602 if (!globals_only && !roles_only && !tablespaces_only)
603 dumpDatabases(conn);
605 PQfinish(conn);
607 if (verbose)
608 dumpTimestamp("Completed on");
609 fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
611 if (filename)
613 fclose(OPF);
615 /* sync the resulting file, errors are not fatal */
616 if (dosync)
617 (void) fsync_fname(filename, false);
620 exit_nicely(0);
624 static void
625 help(void)
627 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
628 printf(_("Usage:\n"));
629 printf(_(" %s [OPTION]...\n"), progname);
631 printf(_("\nGeneral options:\n"));
632 printf(_(" -f, --file=FILENAME output file name\n"));
633 printf(_(" -v, --verbose verbose mode\n"));
634 printf(_(" -V, --version output version information, then exit\n"));
635 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
636 printf(_(" -?, --help show this help, then exit\n"));
637 printf(_("\nOptions controlling the output content:\n"));
638 printf(_(" -a, --data-only dump only the data, not the schema\n"));
639 printf(_(" -c, --clean clean (drop) databases before recreating\n"));
640 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
641 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
642 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
643 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
644 printf(_(" -s, --schema-only dump only the schema, no data\n"));
645 printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
646 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
647 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
648 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
649 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
650 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
651 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
652 printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n"));
653 printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
654 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
655 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
656 printf(_(" --load-via-partition-root load partitions via the root table\n"));
657 printf(_(" --no-comments do not dump comments\n"));
658 printf(_(" --no-publications do not dump publications\n"));
659 printf(_(" --no-role-passwords do not dump passwords for roles\n"));
660 printf(_(" --no-security-labels do not dump security label assignments\n"));
661 printf(_(" --no-subscriptions do not dump subscriptions\n"));
662 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
663 printf(_(" --no-table-access-method do not dump table access methods\n"));
664 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
665 printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
666 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
667 printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
668 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
669 printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
670 printf(_(" --use-set-session-authorization\n"
671 " use SET SESSION AUTHORIZATION commands instead of\n"
672 " ALTER OWNER commands to set ownership\n"));
674 printf(_("\nConnection options:\n"));
675 printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
676 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
677 printf(_(" -l, --database=DBNAME alternative default database\n"));
678 printf(_(" -p, --port=PORT database server port number\n"));
679 printf(_(" -U, --username=NAME connect as specified database user\n"));
680 printf(_(" -w, --no-password never prompt for password\n"));
681 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
682 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
684 printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
685 "output.\n\n"));
686 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
687 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
692 * Drop roles
694 static void
695 dropRoles(PGconn *conn)
697 PQExpBuffer buf = createPQExpBuffer();
698 PGresult *res;
699 int i_rolname;
700 int i;
702 if (server_version >= 90600)
703 printfPQExpBuffer(buf,
704 "SELECT rolname "
705 "FROM %s "
706 "WHERE rolname !~ '^pg_' "
707 "ORDER BY 1", role_catalog);
708 else
709 printfPQExpBuffer(buf,
710 "SELECT rolname "
711 "FROM %s "
712 "ORDER BY 1", role_catalog);
714 res = executeQuery(conn, buf->data);
716 i_rolname = PQfnumber(res, "rolname");
718 if (PQntuples(res) > 0)
719 fprintf(OPF, "--\n-- Drop roles\n--\n\n");
721 for (i = 0; i < PQntuples(res); i++)
723 const char *rolename;
725 rolename = PQgetvalue(res, i, i_rolname);
727 fprintf(OPF, "DROP ROLE %s%s;\n",
728 if_exists ? "IF EXISTS " : "",
729 fmtId(rolename));
732 PQclear(res);
733 destroyPQExpBuffer(buf);
735 fprintf(OPF, "\n\n");
739 * Dump roles
741 static void
742 dumpRoles(PGconn *conn)
744 PQExpBuffer buf = createPQExpBuffer();
745 PGresult *res;
746 int i_oid,
747 i_rolname,
748 i_rolsuper,
749 i_rolinherit,
750 i_rolcreaterole,
751 i_rolcreatedb,
752 i_rolcanlogin,
753 i_rolconnlimit,
754 i_rolpassword,
755 i_rolvaliduntil,
756 i_rolreplication,
757 i_rolbypassrls,
758 i_rolcomment,
759 i_is_current_user;
760 int i;
762 /* note: rolconfig is dumped later */
763 if (server_version >= 90600)
764 printfPQExpBuffer(buf,
765 "SELECT oid, rolname, rolsuper, rolinherit, "
766 "rolcreaterole, rolcreatedb, "
767 "rolcanlogin, rolconnlimit, rolpassword, "
768 "rolvaliduntil, rolreplication, rolbypassrls, "
769 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
770 "rolname = current_user AS is_current_user "
771 "FROM %s "
772 "WHERE rolname !~ '^pg_' "
773 "ORDER BY 2", role_catalog, role_catalog);
774 else if (server_version >= 90500)
775 printfPQExpBuffer(buf,
776 "SELECT oid, rolname, rolsuper, rolinherit, "
777 "rolcreaterole, rolcreatedb, "
778 "rolcanlogin, rolconnlimit, rolpassword, "
779 "rolvaliduntil, rolreplication, rolbypassrls, "
780 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
781 "rolname = current_user AS is_current_user "
782 "FROM %s "
783 "ORDER BY 2", role_catalog, role_catalog);
784 else
785 printfPQExpBuffer(buf,
786 "SELECT oid, rolname, rolsuper, rolinherit, "
787 "rolcreaterole, rolcreatedb, "
788 "rolcanlogin, rolconnlimit, rolpassword, "
789 "rolvaliduntil, rolreplication, "
790 "false as rolbypassrls, "
791 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
792 "rolname = current_user AS is_current_user "
793 "FROM %s "
794 "ORDER BY 2", role_catalog, role_catalog);
796 res = executeQuery(conn, buf->data);
798 i_oid = PQfnumber(res, "oid");
799 i_rolname = PQfnumber(res, "rolname");
800 i_rolsuper = PQfnumber(res, "rolsuper");
801 i_rolinherit = PQfnumber(res, "rolinherit");
802 i_rolcreaterole = PQfnumber(res, "rolcreaterole");
803 i_rolcreatedb = PQfnumber(res, "rolcreatedb");
804 i_rolcanlogin = PQfnumber(res, "rolcanlogin");
805 i_rolconnlimit = PQfnumber(res, "rolconnlimit");
806 i_rolpassword = PQfnumber(res, "rolpassword");
807 i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
808 i_rolreplication = PQfnumber(res, "rolreplication");
809 i_rolbypassrls = PQfnumber(res, "rolbypassrls");
810 i_rolcomment = PQfnumber(res, "rolcomment");
811 i_is_current_user = PQfnumber(res, "is_current_user");
813 if (PQntuples(res) > 0)
814 fprintf(OPF, "--\n-- Roles\n--\n\n");
816 for (i = 0; i < PQntuples(res); i++)
818 const char *rolename;
819 Oid auth_oid;
821 auth_oid = atooid(PQgetvalue(res, i, i_oid));
822 rolename = PQgetvalue(res, i, i_rolname);
824 if (strncmp(rolename, "pg_", 3) == 0)
826 pg_log_warning("role name starting with \"pg_\" skipped (%s)",
827 rolename);
828 continue;
831 resetPQExpBuffer(buf);
833 if (binary_upgrade)
835 appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
836 appendPQExpBuffer(buf,
837 "SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
838 auth_oid);
842 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
843 * will acquire the right properties even if it already exists (ie, it
844 * won't hurt for the CREATE to fail). This is particularly important
845 * for the role we are connected as, since even with --clean we will
846 * have failed to drop it. binary_upgrade cannot generate any errors,
847 * so we assume the current role is already created.
849 if (!binary_upgrade ||
850 strcmp(PQgetvalue(res, i, i_is_current_user), "f") == 0)
851 appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
852 appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
854 if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
855 appendPQExpBufferStr(buf, " SUPERUSER");
856 else
857 appendPQExpBufferStr(buf, " NOSUPERUSER");
859 if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
860 appendPQExpBufferStr(buf, " INHERIT");
861 else
862 appendPQExpBufferStr(buf, " NOINHERIT");
864 if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
865 appendPQExpBufferStr(buf, " CREATEROLE");
866 else
867 appendPQExpBufferStr(buf, " NOCREATEROLE");
869 if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
870 appendPQExpBufferStr(buf, " CREATEDB");
871 else
872 appendPQExpBufferStr(buf, " NOCREATEDB");
874 if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
875 appendPQExpBufferStr(buf, " LOGIN");
876 else
877 appendPQExpBufferStr(buf, " NOLOGIN");
879 if (strcmp(PQgetvalue(res, i, i_rolreplication), "t") == 0)
880 appendPQExpBufferStr(buf, " REPLICATION");
881 else
882 appendPQExpBufferStr(buf, " NOREPLICATION");
884 if (strcmp(PQgetvalue(res, i, i_rolbypassrls), "t") == 0)
885 appendPQExpBufferStr(buf, " BYPASSRLS");
886 else
887 appendPQExpBufferStr(buf, " NOBYPASSRLS");
889 if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
890 appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
891 PQgetvalue(res, i, i_rolconnlimit));
894 if (!PQgetisnull(res, i, i_rolpassword) && !no_role_passwords)
896 appendPQExpBufferStr(buf, " PASSWORD ");
897 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolpassword), conn);
900 if (!PQgetisnull(res, i, i_rolvaliduntil))
901 appendPQExpBuffer(buf, " VALID UNTIL '%s'",
902 PQgetvalue(res, i, i_rolvaliduntil));
904 appendPQExpBufferStr(buf, ";\n");
906 if (!no_comments && !PQgetisnull(res, i, i_rolcomment))
908 appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
909 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolcomment), conn);
910 appendPQExpBufferStr(buf, ";\n");
913 if (!no_security_labels)
914 buildShSecLabels(conn, "pg_authid", auth_oid,
915 "ROLE", rolename,
916 buf);
918 fprintf(OPF, "%s", buf->data);
922 * Dump configuration settings for roles after all roles have been dumped.
923 * We do it this way because config settings for roles could mention the
924 * names of other roles.
926 if (PQntuples(res) > 0)
927 fprintf(OPF, "\n--\n-- User Configurations\n--\n");
929 for (i = 0; i < PQntuples(res); i++)
930 dumpUserConfig(conn, PQgetvalue(res, i, i_rolname));
932 PQclear(res);
934 fprintf(OPF, "\n\n");
936 destroyPQExpBuffer(buf);
941 * Dump role memberships.
943 * Note: we expect dumpRoles already created all the roles, but there is
944 * no membership yet.
946 static void
947 dumpRoleMembership(PGconn *conn)
949 PQExpBuffer buf = createPQExpBuffer();
950 PQExpBuffer optbuf = createPQExpBuffer();
951 PGresult *res;
952 int start = 0,
953 end,
954 total;
955 bool dump_grantors;
956 bool dump_inherit_option;
957 int i_inherit_option;
960 * Previous versions of PostgreSQL didn't used to track the grantor very
961 * carefully in the backend, and the grantor could be any user even if
962 * they didn't have ADMIN OPTION on the role, or a user that no longer
963 * existed. To avoid dump and restore failures, don't dump the grantor
964 * when talking to an old server version.
966 dump_grantors = (PQserverVersion(conn) >= 160000);
969 * Previous versions of PostgreSQL also did not have a grant-level
970 * INHERIT option.
972 dump_inherit_option = (server_version >= 160000);
974 /* Generate and execute query. */
975 printfPQExpBuffer(buf, "SELECT ur.rolname AS role, "
976 "um.rolname AS member, "
977 "ug.oid AS grantorid, "
978 "ug.rolname AS grantor, "
979 "a.admin_option");
980 if (dump_inherit_option)
981 appendPQExpBuffer(buf, ", a.inherit_option");
982 appendPQExpBuffer(buf, " FROM pg_auth_members a "
983 "LEFT JOIN %s ur on ur.oid = a.roleid "
984 "LEFT JOIN %s um on um.oid = a.member "
985 "LEFT JOIN %s ug on ug.oid = a.grantor "
986 "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
987 "ORDER BY 1,2,4", role_catalog, role_catalog, role_catalog);
988 res = executeQuery(conn, buf->data);
989 i_inherit_option = PQfnumber(res, "inherit_option");
991 if (PQntuples(res) > 0)
992 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
995 * We can't dump these GRANT commands in arbitary order, because a role
996 * that is named as a grantor must already have ADMIN OPTION on the
997 * role for which it is granting permissions, except for the boostrap
998 * superuser, who can always be named as the grantor.
1000 * We handle this by considering these grants role by role. For each role,
1001 * we initially consider the only allowable grantor to be the boostrap
1002 * superuser. Every time we grant ADMIN OPTION on the role to some user,
1003 * that user also becomes an allowable grantor. We make repeated passes
1004 * over the grants for the role, each time dumping those whose grantors
1005 * are allowable and which we haven't done yet. Eventually this should
1006 * let us dump all the grants.
1008 total = PQntuples(res);
1009 while (start < total)
1011 char *role = PQgetvalue(res, start, 0);
1012 int i;
1013 bool *done;
1014 int remaining;
1015 int prev_remaining = 0;
1016 rolename_hash *ht;
1018 /* All memberships for a single role should be adjacent. */
1019 for (end = start; end < total; ++end)
1021 char *otherrole;
1023 otherrole = PQgetvalue(res, end, 0);
1024 if (strcmp(role, otherrole) != 0)
1025 break;
1028 role = PQgetvalue(res, start, 0);
1029 remaining = end - start;
1030 done = pg_malloc0(remaining * sizeof(bool));
1031 ht = rolename_create(remaining, NULL);
1034 * Make repeated passses over the grants for this role until all have
1035 * been dumped.
1037 while (remaining > 0)
1040 * We should make progress on every iteration, because a notional
1041 * graph whose vertices are grants and whose edges point from
1042 * grantors to members should be connected and acyclic. If we fail
1043 * to make progress, either we or the server have messed up.
1045 if (remaining == prev_remaining)
1047 pg_log_error("could not find a legal dump ordering for memberships in role \"%s\"",
1048 role);
1049 PQfinish(conn);
1050 exit_nicely(1);
1053 /* Make one pass over the grants for this role. */
1054 for (i = start; i < end; ++i)
1056 char *member;
1057 char *admin_option;
1058 char *grantorid;
1059 char *grantor;
1060 bool found;
1062 /* If we already did this grant, don't do it again. */
1063 if (done[i - start])
1064 continue;
1066 member = PQgetvalue(res, i, 1);
1067 grantorid = PQgetvalue(res, i, 2);
1068 grantor = PQgetvalue(res, i, 3);
1069 admin_option = PQgetvalue(res, i, 4);
1072 * If we're not dumping grantors or if the grantor is the
1073 * bootstrap superuser, it's fine to dump this now. Otherwise,
1074 * it's got to be someone who has already been granted ADMIN
1075 * OPTION.
1077 if (dump_grantors &&
1078 atooid(grantorid) != BOOTSTRAP_SUPERUSERID &&
1079 rolename_lookup(ht, grantor) == NULL)
1080 continue;
1082 /* Remember that we did this so that we don't do it again. */
1083 done[i - start] = true;
1084 --remaining;
1087 * If ADMIN OPTION is being granted, remember that grants
1088 * listing this member as the grantor can now be dumped.
1090 if (*admin_option == 't')
1091 rolename_insert(ht, member, &found);
1093 /* Generate the actual GRANT statement. */
1094 resetPQExpBuffer(optbuf);
1095 fprintf(OPF, "GRANT %s", fmtId(role));
1096 fprintf(OPF, " TO %s", fmtId(member));
1097 if (*admin_option == 't')
1098 appendPQExpBufferStr(optbuf, "ADMIN OPTION");
1099 if (dump_inherit_option)
1101 char *inherit_option;
1103 if (optbuf->data[0] != '\0')
1104 appendPQExpBufferStr(optbuf, ", ");
1105 inherit_option = PQgetvalue(res, i, i_inherit_option);
1106 appendPQExpBuffer(optbuf, "INHERIT %s",
1107 *inherit_option == 't' ?
1108 "TRUE" : "FALSE");
1110 if (optbuf->data[0] != '\0')
1111 fprintf(OPF, " WITH %s", optbuf->data);
1112 if (dump_grantors)
1113 fprintf(OPF, " GRANTED BY %s", fmtId(grantor));
1114 fprintf(OPF, ";\n");
1118 rolename_destroy(ht);
1119 pg_free(done);
1120 start = end;
1123 PQclear(res);
1124 destroyPQExpBuffer(buf);
1126 fprintf(OPF, "\n\n");
1131 * Dump role configuration parameter privileges. This code is used for 15.0
1132 * and later servers.
1134 * Note: we expect dumpRoles already created all the roles, but there are
1135 * no per-role configuration parameter privileges yet.
1137 static void
1138 dumpRoleGUCPrivs(PGconn *conn)
1140 PGresult *res;
1141 int i;
1144 * Get all parameters that have non-default acls defined.
1146 res = executeQuery(conn, "SELECT parname, "
1147 "pg_catalog.pg_get_userbyid(" CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS parowner, "
1148 "paracl, "
1149 "pg_catalog.acldefault('p', " CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS acldefault "
1150 "FROM pg_catalog.pg_parameter_acl "
1151 "ORDER BY 1");
1153 if (PQntuples(res) > 0)
1154 fprintf(OPF, "--\n-- Role privileges on configuration parameters\n--\n\n");
1156 for (i = 0; i < PQntuples(res); i++)
1158 PQExpBuffer buf = createPQExpBuffer();
1159 char *parname = PQgetvalue(res, i, 0);
1160 char *parowner = PQgetvalue(res, i, 1);
1161 char *paracl = PQgetvalue(res, i, 2);
1162 char *acldefault = PQgetvalue(res, i, 3);
1163 char *fparname;
1165 /* needed for buildACLCommands() */
1166 fparname = pg_strdup(fmtId(parname));
1168 if (!buildACLCommands(fparname, NULL, NULL, "PARAMETER",
1169 paracl, acldefault,
1170 parowner, "", server_version, buf))
1172 pg_log_error("could not parse ACL list (%s) for parameter \"%s\"",
1173 paracl, parname);
1174 PQfinish(conn);
1175 exit_nicely(1);
1178 fprintf(OPF, "%s", buf->data);
1180 free(fparname);
1181 destroyPQExpBuffer(buf);
1184 PQclear(res);
1185 fprintf(OPF, "\n\n");
1190 * Drop tablespaces.
1192 static void
1193 dropTablespaces(PGconn *conn)
1195 PGresult *res;
1196 int i;
1199 * Get all tablespaces except built-in ones (which we assume are named
1200 * pg_xxx)
1202 res = executeQuery(conn, "SELECT spcname "
1203 "FROM pg_catalog.pg_tablespace "
1204 "WHERE spcname !~ '^pg_' "
1205 "ORDER BY 1");
1207 if (PQntuples(res) > 0)
1208 fprintf(OPF, "--\n-- Drop tablespaces\n--\n\n");
1210 for (i = 0; i < PQntuples(res); i++)
1212 char *spcname = PQgetvalue(res, i, 0);
1214 fprintf(OPF, "DROP TABLESPACE %s%s;\n",
1215 if_exists ? "IF EXISTS " : "",
1216 fmtId(spcname));
1219 PQclear(res);
1221 fprintf(OPF, "\n\n");
1225 * Dump tablespaces.
1227 static void
1228 dumpTablespaces(PGconn *conn)
1230 PGresult *res;
1231 int i;
1234 * Get all tablespaces except built-in ones (which we assume are named
1235 * pg_xxx)
1237 res = executeQuery(conn, "SELECT oid, spcname, "
1238 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1239 "pg_catalog.pg_tablespace_location(oid), "
1240 "spcacl, acldefault('t', spcowner) AS acldefault, "
1241 "array_to_string(spcoptions, ', '),"
1242 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1243 "FROM pg_catalog.pg_tablespace "
1244 "WHERE spcname !~ '^pg_' "
1245 "ORDER BY 1");
1247 if (PQntuples(res) > 0)
1248 fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
1250 for (i = 0; i < PQntuples(res); i++)
1252 PQExpBuffer buf = createPQExpBuffer();
1253 Oid spcoid = atooid(PQgetvalue(res, i, 0));
1254 char *spcname = PQgetvalue(res, i, 1);
1255 char *spcowner = PQgetvalue(res, i, 2);
1256 char *spclocation = PQgetvalue(res, i, 3);
1257 char *spcacl = PQgetvalue(res, i, 4);
1258 char *acldefault = PQgetvalue(res, i, 5);
1259 char *spcoptions = PQgetvalue(res, i, 6);
1260 char *spccomment = PQgetvalue(res, i, 7);
1261 char *fspcname;
1263 /* needed for buildACLCommands() */
1264 fspcname = pg_strdup(fmtId(spcname));
1266 if (binary_upgrade)
1268 appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_tablespace oid\n");
1269 appendPQExpBuffer(buf, "SELECT pg_catalog.binary_upgrade_set_next_pg_tablespace_oid('%u'::pg_catalog.oid);\n", spcoid);
1272 appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
1273 appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
1275 appendPQExpBufferStr(buf, " LOCATION ");
1276 appendStringLiteralConn(buf, spclocation, conn);
1277 appendPQExpBufferStr(buf, ";\n");
1279 if (spcoptions && spcoptions[0] != '\0')
1280 appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
1281 fspcname, spcoptions);
1283 /* tablespaces can't have initprivs */
1285 if (!skip_acls &&
1286 !buildACLCommands(fspcname, NULL, NULL, "TABLESPACE",
1287 spcacl, acldefault,
1288 spcowner, "", server_version, buf))
1290 pg_log_error("could not parse ACL list (%s) for tablespace \"%s\"",
1291 spcacl, spcname);
1292 PQfinish(conn);
1293 exit_nicely(1);
1296 if (!no_comments && spccomment && spccomment[0] != '\0')
1298 appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
1299 appendStringLiteralConn(buf, spccomment, conn);
1300 appendPQExpBufferStr(buf, ";\n");
1303 if (!no_security_labels)
1304 buildShSecLabels(conn, "pg_tablespace", spcoid,
1305 "TABLESPACE", spcname,
1306 buf);
1308 fprintf(OPF, "%s", buf->data);
1310 free(fspcname);
1311 destroyPQExpBuffer(buf);
1314 PQclear(res);
1315 fprintf(OPF, "\n\n");
1320 * Dump commands to drop each database.
1322 static void
1323 dropDBs(PGconn *conn)
1325 PGresult *res;
1326 int i;
1329 * Skip databases marked not datallowconn, since we'd be unable to connect
1330 * to them anyway. This must agree with dumpDatabases().
1332 res = executeQuery(conn,
1333 "SELECT datname "
1334 "FROM pg_database d "
1335 "WHERE datallowconn "
1336 "ORDER BY datname");
1338 if (PQntuples(res) > 0)
1339 fprintf(OPF, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
1341 for (i = 0; i < PQntuples(res); i++)
1343 char *dbname = PQgetvalue(res, i, 0);
1346 * Skip "postgres" and "template1"; dumpDatabases() will deal with
1347 * them specially. Also, be sure to skip "template0", even if for
1348 * some reason it's not marked !datallowconn.
1350 if (strcmp(dbname, "template1") != 0 &&
1351 strcmp(dbname, "template0") != 0 &&
1352 strcmp(dbname, "postgres") != 0)
1354 fprintf(OPF, "DROP DATABASE %s%s;\n",
1355 if_exists ? "IF EXISTS " : "",
1356 fmtId(dbname));
1360 PQclear(res);
1362 fprintf(OPF, "\n\n");
1367 * Dump user-specific configuration
1369 static void
1370 dumpUserConfig(PGconn *conn, const char *username)
1372 PQExpBuffer buf = createPQExpBuffer();
1373 PGresult *res;
1375 printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
1376 "WHERE setdatabase = 0 AND setrole = "
1377 "(SELECT oid FROM %s WHERE rolname = ",
1378 role_catalog);
1379 appendStringLiteralConn(buf, username, conn);
1380 appendPQExpBufferChar(buf, ')');
1382 res = executeQuery(conn, buf->data);
1384 if (PQntuples(res) > 0)
1385 fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", username);
1387 for (int i = 0; i < PQntuples(res); i++)
1389 resetPQExpBuffer(buf);
1390 makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
1391 "ROLE", username, NULL, NULL,
1392 buf);
1393 fprintf(OPF, "%s", buf->data);
1396 PQclear(res);
1398 destroyPQExpBuffer(buf);
1402 * Find a list of database names that match the given patterns.
1403 * See also expand_table_name_patterns() in pg_dump.c
1405 static void
1406 expand_dbname_patterns(PGconn *conn,
1407 SimpleStringList *patterns,
1408 SimpleStringList *names)
1410 PQExpBuffer query;
1411 PGresult *res;
1413 if (patterns->head == NULL)
1414 return; /* nothing to do */
1416 query = createPQExpBuffer();
1419 * The loop below runs multiple SELECTs, which might sometimes result in
1420 * duplicate entries in the name list, but we don't care, since all we're
1421 * going to do is test membership of the list.
1424 for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next)
1426 int dotcnt;
1428 appendPQExpBufferStr(query,
1429 "SELECT datname FROM pg_catalog.pg_database n\n");
1430 processSQLNamePattern(conn, query, cell->val, false,
1431 false, NULL, "datname", NULL, NULL, NULL,
1432 &dotcnt);
1434 if (dotcnt > 0)
1436 pg_log_error("improper qualified name (too many dotted names): %s",
1437 cell->val);
1438 PQfinish(conn);
1439 exit_nicely(1);
1442 res = executeQuery(conn, query->data);
1443 for (int i = 0; i < PQntuples(res); i++)
1445 simple_string_list_append(names, PQgetvalue(res, i, 0));
1448 PQclear(res);
1449 resetPQExpBuffer(query);
1452 destroyPQExpBuffer(query);
1456 * Dump contents of databases.
1458 static void
1459 dumpDatabases(PGconn *conn)
1461 PGresult *res;
1462 int i;
1465 * Skip databases marked not datallowconn, since we'd be unable to connect
1466 * to them anyway. This must agree with dropDBs().
1468 * We arrange for template1 to be processed first, then we process other
1469 * DBs in alphabetical order. If we just did them all alphabetically, we
1470 * might find ourselves trying to drop the "postgres" database while still
1471 * connected to it. This makes trying to run the restore script while
1472 * connected to "template1" a bad idea, but there's no fixed order that
1473 * doesn't have some failure mode with --clean.
1475 res = executeQuery(conn,
1476 "SELECT datname "
1477 "FROM pg_database d "
1478 "WHERE datallowconn "
1479 "ORDER BY (datname <> 'template1'), datname");
1481 if (PQntuples(res) > 0)
1482 fprintf(OPF, "--\n-- Databases\n--\n\n");
1484 for (i = 0; i < PQntuples(res); i++)
1486 char *dbname = PQgetvalue(res, i, 0);
1487 const char *create_opts;
1488 int ret;
1490 /* Skip template0, even if it's not marked !datallowconn. */
1491 if (strcmp(dbname, "template0") == 0)
1492 continue;
1494 /* Skip any explicitly excluded database */
1495 if (simple_string_list_member(&database_exclude_names, dbname))
1497 pg_log_info("excluding database \"%s\"", dbname);
1498 continue;
1501 pg_log_info("dumping database \"%s\"", dbname);
1503 fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname);
1506 * We assume that "template1" and "postgres" already exist in the
1507 * target installation. dropDBs() won't have removed them, for fear
1508 * of removing the DB the restore script is initially connected to. If
1509 * --clean was specified, tell pg_dump to drop and recreate them;
1510 * otherwise we'll merely restore their contents. Other databases
1511 * should simply be created.
1513 if (strcmp(dbname, "template1") == 0 || strcmp(dbname, "postgres") == 0)
1515 if (output_clean)
1516 create_opts = "--clean --create";
1517 else
1519 create_opts = "";
1520 /* Since pg_dump won't emit a \connect command, we must */
1521 fprintf(OPF, "\\connect %s\n\n", dbname);
1524 else
1525 create_opts = "--create";
1527 if (filename)
1528 fclose(OPF);
1530 ret = runPgDump(dbname, create_opts);
1531 if (ret != 0)
1532 pg_fatal("pg_dump failed on database \"%s\", exiting", dbname);
1534 if (filename)
1536 OPF = fopen(filename, PG_BINARY_A);
1537 if (!OPF)
1538 pg_fatal("could not re-open the output file \"%s\": %m",
1539 filename);
1543 PQclear(res);
1549 * Run pg_dump on dbname, with specified options.
1551 static int
1552 runPgDump(const char *dbname, const char *create_opts)
1554 PQExpBuffer connstrbuf = createPQExpBuffer();
1555 PQExpBuffer cmd = createPQExpBuffer();
1556 int ret;
1558 appendPQExpBuffer(cmd, "\"%s\" %s %s", pg_dump_bin,
1559 pgdumpopts->data, create_opts);
1562 * If we have a filename, use the undocumented plain-append pg_dump
1563 * format.
1565 if (filename)
1566 appendPQExpBufferStr(cmd, " -Fa ");
1567 else
1568 appendPQExpBufferStr(cmd, " -Fp ");
1571 * Append the database name to the already-constructed stem of connection
1572 * string.
1574 appendPQExpBuffer(connstrbuf, "%s dbname=", connstr);
1575 appendConnStrVal(connstrbuf, dbname);
1577 appendShellString(cmd, connstrbuf->data);
1579 pg_log_info("running \"%s\"", cmd->data);
1581 fflush(NULL);
1583 ret = system(cmd->data);
1585 destroyPQExpBuffer(cmd);
1586 destroyPQExpBuffer(connstrbuf);
1588 return ret;
1592 * buildShSecLabels
1594 * Build SECURITY LABEL command(s) for a shared object
1596 * The caller has to provide object type and identity in two separate formats:
1597 * catalog_name (e.g., "pg_database") and object OID, as well as
1598 * type name (e.g., "DATABASE") and object name (not pre-quoted).
1600 * The command(s) are appended to "buffer".
1602 static void
1603 buildShSecLabels(PGconn *conn, const char *catalog_name, Oid objectId,
1604 const char *objtype, const char *objname,
1605 PQExpBuffer buffer)
1607 PQExpBuffer sql = createPQExpBuffer();
1608 PGresult *res;
1610 buildShSecLabelQuery(catalog_name, objectId, sql);
1611 res = executeQuery(conn, sql->data);
1612 emitShSecLabels(conn, res, buffer, objtype, objname);
1614 PQclear(res);
1615 destroyPQExpBuffer(sql);
1619 * Make a database connection with the given parameters. An
1620 * interactive password prompt is automatically issued if required.
1622 * If fail_on_error is false, we return NULL without printing any message
1623 * on failure, but preserve any prompted password for the next try.
1625 * On success, the global variable 'connstr' is set to a connection string
1626 * containing the options used.
1628 static PGconn *
1629 connectDatabase(const char *dbname, const char *connection_string,
1630 const char *pghost, const char *pgport, const char *pguser,
1631 trivalue prompt_password, bool fail_on_error)
1633 PGconn *conn;
1634 bool new_pass;
1635 const char *remoteversion_str;
1636 int my_version;
1637 const char **keywords = NULL;
1638 const char **values = NULL;
1639 PQconninfoOption *conn_opts = NULL;
1640 static char *password = NULL;
1642 if (prompt_password == TRI_YES && !password)
1643 password = simple_prompt("Password: ", false);
1646 * Start the connection. Loop until we have a password if requested by
1647 * backend.
1651 int argcount = 6;
1652 PQconninfoOption *conn_opt;
1653 char *err_msg = NULL;
1654 int i = 0;
1656 free(keywords);
1657 free(values);
1658 PQconninfoFree(conn_opts);
1661 * Merge the connection info inputs given in form of connection string
1662 * and other options. Explicitly discard any dbname value in the
1663 * connection string; otherwise, PQconnectdbParams() would interpret
1664 * that value as being itself a connection string.
1666 if (connection_string)
1668 conn_opts = PQconninfoParse(connection_string, &err_msg);
1669 if (conn_opts == NULL)
1670 pg_fatal("%s", err_msg);
1672 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1674 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1675 strcmp(conn_opt->keyword, "dbname") != 0)
1676 argcount++;
1679 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1680 values = pg_malloc0((argcount + 1) * sizeof(*values));
1682 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1684 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1685 strcmp(conn_opt->keyword, "dbname") != 0)
1687 keywords[i] = conn_opt->keyword;
1688 values[i] = conn_opt->val;
1689 i++;
1693 else
1695 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1696 values = pg_malloc0((argcount + 1) * sizeof(*values));
1699 if (pghost)
1701 keywords[i] = "host";
1702 values[i] = pghost;
1703 i++;
1705 if (pgport)
1707 keywords[i] = "port";
1708 values[i] = pgport;
1709 i++;
1711 if (pguser)
1713 keywords[i] = "user";
1714 values[i] = pguser;
1715 i++;
1717 if (password)
1719 keywords[i] = "password";
1720 values[i] = password;
1721 i++;
1723 if (dbname)
1725 keywords[i] = "dbname";
1726 values[i] = dbname;
1727 i++;
1729 keywords[i] = "fallback_application_name";
1730 values[i] = progname;
1731 i++;
1733 new_pass = false;
1734 conn = PQconnectdbParams(keywords, values, true);
1736 if (!conn)
1737 pg_fatal("could not connect to database \"%s\"", dbname);
1739 if (PQstatus(conn) == CONNECTION_BAD &&
1740 PQconnectionNeedsPassword(conn) &&
1741 !password &&
1742 prompt_password != TRI_NO)
1744 PQfinish(conn);
1745 password = simple_prompt("Password: ", false);
1746 new_pass = true;
1748 } while (new_pass);
1750 /* check to see that the backend connection was successfully made */
1751 if (PQstatus(conn) == CONNECTION_BAD)
1753 if (fail_on_error)
1754 pg_fatal("%s", PQerrorMessage(conn));
1755 else
1757 PQfinish(conn);
1759 free(keywords);
1760 free(values);
1761 PQconninfoFree(conn_opts);
1763 return NULL;
1768 * Ok, connected successfully. Remember the options used, in the form of a
1769 * connection string.
1771 connstr = constructConnStr(keywords, values);
1773 free(keywords);
1774 free(values);
1775 PQconninfoFree(conn_opts);
1777 /* Check version */
1778 remoteversion_str = PQparameterStatus(conn, "server_version");
1779 if (!remoteversion_str)
1780 pg_fatal("could not get server version");
1781 server_version = PQserverVersion(conn);
1782 if (server_version == 0)
1783 pg_fatal("could not parse server version \"%s\"",
1784 remoteversion_str);
1786 my_version = PG_VERSION_NUM;
1789 * We allow the server to be back to 9.2, and up to any minor release of
1790 * our own major version. (See also version check in pg_dump.c.)
1792 if (my_version != server_version
1793 && (server_version < 90200 ||
1794 (server_version / 100) > (my_version / 100)))
1796 pg_log_error("aborting because of server version mismatch");
1797 pg_log_error_detail("server version: %s; %s version: %s",
1798 remoteversion_str, progname, PG_VERSION);
1799 exit_nicely(1);
1802 PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL));
1804 return conn;
1807 /* ----------
1808 * Construct a connection string from the given keyword/value pairs. It is
1809 * used to pass the connection options to the pg_dump subprocess.
1811 * The following parameters are excluded:
1812 * dbname - varies in each pg_dump invocation
1813 * password - it's not secure to pass a password on the command line
1814 * fallback_application_name - we'll let pg_dump set it
1815 * ----------
1817 static char *
1818 constructConnStr(const char **keywords, const char **values)
1820 PQExpBuffer buf = createPQExpBuffer();
1821 char *connstr;
1822 int i;
1823 bool firstkeyword = true;
1825 /* Construct a new connection string in key='value' format. */
1826 for (i = 0; keywords[i] != NULL; i++)
1828 if (strcmp(keywords[i], "dbname") == 0 ||
1829 strcmp(keywords[i], "password") == 0 ||
1830 strcmp(keywords[i], "fallback_application_name") == 0)
1831 continue;
1833 if (!firstkeyword)
1834 appendPQExpBufferChar(buf, ' ');
1835 firstkeyword = false;
1836 appendPQExpBuffer(buf, "%s=", keywords[i]);
1837 appendConnStrVal(buf, values[i]);
1840 connstr = pg_strdup(buf->data);
1841 destroyPQExpBuffer(buf);
1842 return connstr;
1846 * Run a query, return the results, exit program on failure.
1848 static PGresult *
1849 executeQuery(PGconn *conn, const char *query)
1851 PGresult *res;
1853 pg_log_info("executing %s", query);
1855 res = PQexec(conn, query);
1856 if (!res ||
1857 PQresultStatus(res) != PGRES_TUPLES_OK)
1859 pg_log_error("query failed: %s", PQerrorMessage(conn));
1860 pg_log_error_detail("Query was: %s", query);
1861 PQfinish(conn);
1862 exit_nicely(1);
1865 return res;
1869 * As above for a SQL command (which returns nothing).
1871 static void
1872 executeCommand(PGconn *conn, const char *query)
1874 PGresult *res;
1876 pg_log_info("executing %s", query);
1878 res = PQexec(conn, query);
1879 if (!res ||
1880 PQresultStatus(res) != PGRES_COMMAND_OK)
1882 pg_log_error("query failed: %s", PQerrorMessage(conn));
1883 pg_log_error_detail("Query was: %s", query);
1884 PQfinish(conn);
1885 exit_nicely(1);
1888 PQclear(res);
1893 * dumpTimestamp
1895 static void
1896 dumpTimestamp(const char *msg)
1898 char buf[64];
1899 time_t now = time(NULL);
1901 if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0)
1902 fprintf(OPF, "-- %s %s\n\n", msg, buf);
1906 * Helper function for rolenamehash hash table.
1908 static uint32
1909 hash_string_pointer(char *s)
1911 unsigned char *ss = (unsigned char *) s;
1913 return hash_bytes(ss, strlen(s));