PostgreSQL Source Code  git master
pg_dumpall.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_dumpall.c
4  *
5  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * pg_dumpall forces all pg_dump output to be text, since it also outputs
9  * text into the same output stream.
10  *
11  * src/bin/pg_dump/pg_dumpall.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres_fe.h"
17 
18 #include <time.h>
19 #include <unistd.h>
20 
21 #include "getopt_long.h"
22 
23 #include "dumputils.h"
24 #include "pg_backup.h"
25 #include "common/file_utils.h"
26 #include "fe_utils/string_utils.h"
27 
28 /* version string we expect back from pg_dump */
29 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
30 
31 
32 static void help(void);
33 
34 static void dropRoles(PGconn *conn);
35 static void dumpRoles(PGconn *conn);
36 static void dumpRoleMembership(PGconn *conn);
37 static void dumpGroups(PGconn *conn);
38 static void dropTablespaces(PGconn *conn);
39 static void dumpTablespaces(PGconn *conn);
40 static void dropDBs(PGconn *conn);
41 static void dumpUserConfig(PGconn *conn, const char *username);
42 static void dumpDatabases(PGconn *conn);
43 static void dumpTimestamp(const char *msg);
44 static int runPgDump(const char *dbname, const char *create_opts);
45 static void buildShSecLabels(PGconn *conn, const char *catalog_name,
46  uint32 objectId, PQExpBuffer buffer,
47  const char *target, const char *objname);
48 static PGconn *connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport,
49  const char *pguser, trivalue prompt_password, bool fail_on_error);
50 static char *constructConnStr(const char **keywords, const char **values);
51 static PGresult *executeQuery(PGconn *conn, const char *query);
52 static void executeCommand(PGconn *conn, const char *query);
53 
54 static char pg_dump_bin[MAXPGPATH];
55 static const char *progname;
57 static char *connstr = "";
58 static bool output_clean = false;
59 static bool skip_acls = false;
60 static bool verbose = false;
61 static bool dosync = true;
62 
63 static int binary_upgrade = 0;
64 static int column_inserts = 0;
65 static int disable_dollar_quoting = 0;
66 static int disable_triggers = 0;
67 static int if_exists = 0;
68 static int inserts = 0;
69 static int no_tablespaces = 0;
70 static int use_setsessauth = 0;
71 static int no_comments = 0;
72 static int no_publications = 0;
73 static int no_security_labels = 0;
74 static int no_subscriptions = 0;
75 static int no_unlogged_table_data = 0;
76 static int no_role_passwords = 0;
77 static int server_version;
78 static int load_via_partition_root = 0;
79 
80 static char role_catalog[10];
81 #define PG_AUTHID "pg_authid"
82 #define PG_ROLES "pg_roles "
83 
84 static FILE *OPF;
85 static char *filename = NULL;
86 
87 #define exit_nicely(code) exit(code)
88 
89 int
90 main(int argc, char *argv[])
91 {
92  static struct option long_options[] = {
93  {"data-only", no_argument, NULL, 'a'},
94  {"clean", no_argument, NULL, 'c'},
95  {"encoding", required_argument, NULL, 'E'},
96  {"file", required_argument, NULL, 'f'},
97  {"globals-only", no_argument, NULL, 'g'},
98  {"host", required_argument, NULL, 'h'},
99  {"dbname", required_argument, NULL, 'd'},
100  {"database", required_argument, NULL, 'l'},
101  {"oids", no_argument, NULL, 'o'},
102  {"no-owner", no_argument, NULL, 'O'},
103  {"port", required_argument, NULL, 'p'},
104  {"roles-only", no_argument, NULL, 'r'},
105  {"schema-only", no_argument, NULL, 's'},
106  {"superuser", required_argument, NULL, 'S'},
107  {"tablespaces-only", no_argument, NULL, 't'},
108  {"username", required_argument, NULL, 'U'},
109  {"verbose", no_argument, NULL, 'v'},
110  {"no-password", no_argument, NULL, 'w'},
111  {"password", no_argument, NULL, 'W'},
112  {"no-privileges", no_argument, NULL, 'x'},
113  {"no-acl", no_argument, NULL, 'x'},
114 
115  /*
116  * the following options don't have an equivalent short option letter
117  */
118  {"attribute-inserts", no_argument, &column_inserts, 1},
119  {"binary-upgrade", no_argument, &binary_upgrade, 1},
120  {"column-inserts", no_argument, &column_inserts, 1},
121  {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
122  {"disable-triggers", no_argument, &disable_triggers, 1},
123  {"if-exists", no_argument, &if_exists, 1},
124  {"inserts", no_argument, &inserts, 1},
125  {"lock-wait-timeout", required_argument, NULL, 2},
126  {"no-tablespaces", no_argument, &no_tablespaces, 1},
127  {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
128  {"load-via-partition-root", no_argument, &load_via_partition_root, 1},
129  {"role", required_argument, NULL, 3},
130  {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
131  {"no-comments", no_argument, &no_comments, 1},
132  {"no-publications", no_argument, &no_publications, 1},
133  {"no-role-passwords", no_argument, &no_role_passwords, 1},
134  {"no-security-labels", no_argument, &no_security_labels, 1},
135  {"no-subscriptions", no_argument, &no_subscriptions, 1},
136  {"no-sync", no_argument, NULL, 4},
137  {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
138 
139  {NULL, 0, NULL, 0}
140  };
141 
142  char *pghost = NULL;
143  char *pgport = NULL;
144  char *pguser = NULL;
145  char *pgdb = NULL;
146  char *use_role = NULL;
147  const char *dumpencoding = NULL;
148  trivalue prompt_password = TRI_DEFAULT;
149  bool data_only = false;
150  bool globals_only = false;
151  bool roles_only = false;
152  bool tablespaces_only = false;
153  PGconn *conn;
154  int encoding;
155  const char *std_strings;
156  int c,
157  ret;
158  int optindex;
159 
160  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
161 
162  progname = get_progname(argv[0]);
163 
164  if (argc > 1)
165  {
166  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
167  {
168  help();
169  exit_nicely(0);
170  }
171  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
172  {
173  puts("pg_dumpall (PostgreSQL) " PG_VERSION);
174  exit_nicely(0);
175  }
176  }
177 
178  if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
179  pg_dump_bin)) < 0)
180  {
181  char full_path[MAXPGPATH];
182 
183  if (find_my_exec(argv[0], full_path) < 0)
184  strlcpy(full_path, progname, sizeof(full_path));
185 
186  if (ret == -1)
187  fprintf(stderr,
188  _("The program \"pg_dump\" is needed by %s "
189  "but was not found in the\n"
190  "same directory as \"%s\".\n"
191  "Check your installation.\n"),
192  progname, full_path);
193  else
194  fprintf(stderr,
195  _("The program \"pg_dump\" was found by \"%s\"\n"
196  "but was not the same version as %s.\n"
197  "Check your installation.\n"),
198  full_path, progname);
199  exit_nicely(1);
200  }
201 
202  pgdumpopts = createPQExpBuffer();
203 
204  while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1)
205  {
206  switch (c)
207  {
208  case 'a':
209  data_only = true;
210  appendPQExpBufferStr(pgdumpopts, " -a");
211  break;
212 
213  case 'c':
214  output_clean = true;
215  break;
216 
217  case 'd':
219  break;
220 
221  case 'E':
222  dumpencoding = pg_strdup(optarg);
223  appendPQExpBufferStr(pgdumpopts, " -E ");
224  appendShellString(pgdumpopts, optarg);
225  break;
226 
227  case 'f':
229  appendPQExpBufferStr(pgdumpopts, " -f ");
230  appendShellString(pgdumpopts, filename);
231  break;
232 
233  case 'g':
234  globals_only = true;
235  break;
236 
237  case 'h':
238  pghost = pg_strdup(optarg);
239  break;
240 
241  case 'l':
242  pgdb = pg_strdup(optarg);
243  break;
244 
245  case 'o':
246  appendPQExpBufferStr(pgdumpopts, " -o");
247  break;
248 
249  case 'O':
250  appendPQExpBufferStr(pgdumpopts, " -O");
251  break;
252 
253  case 'p':
254  pgport = pg_strdup(optarg);
255  break;
256 
257  case 'r':
258  roles_only = true;
259  break;
260 
261  case 's':
262  appendPQExpBufferStr(pgdumpopts, " -s");
263  break;
264 
265  case 'S':
266  appendPQExpBufferStr(pgdumpopts, " -S ");
267  appendShellString(pgdumpopts, optarg);
268  break;
269 
270  case 't':
271  tablespaces_only = true;
272  break;
273 
274  case 'U':
275  pguser = pg_strdup(optarg);
276  break;
277 
278  case 'v':
279  verbose = true;
280  appendPQExpBufferStr(pgdumpopts, " -v");
281  break;
282 
283  case 'w':
284  prompt_password = TRI_NO;
285  appendPQExpBufferStr(pgdumpopts, " -w");
286  break;
287 
288  case 'W':
289  prompt_password = TRI_YES;
290  appendPQExpBufferStr(pgdumpopts, " -W");
291  break;
292 
293  case 'x':
294  skip_acls = true;
295  appendPQExpBufferStr(pgdumpopts, " -x");
296  break;
297 
298  case 0:
299  break;
300 
301  case 2:
302  appendPQExpBufferStr(pgdumpopts, " --lock-wait-timeout ");
303  appendShellString(pgdumpopts, optarg);
304  break;
305 
306  case 3:
307  use_role = pg_strdup(optarg);
308  appendPQExpBufferStr(pgdumpopts, " --role ");
309  appendShellString(pgdumpopts, use_role);
310  break;
311 
312  case 4:
313  dosync = false;
314  appendPQExpBufferStr(pgdumpopts, " --no-sync");
315  break;
316 
317  default:
318  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
319  exit_nicely(1);
320  }
321  }
322 
323  /* Complain if any arguments remain */
324  if (optind < argc)
325  {
326  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
327  progname, argv[optind]);
328  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
329  progname);
330  exit_nicely(1);
331  }
332 
333  /* Make sure the user hasn't specified a mix of globals-only options */
334  if (globals_only && roles_only)
335  {
336  fprintf(stderr, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"),
337  progname);
338  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
339  progname);
340  exit_nicely(1);
341  }
342 
343  if (globals_only && tablespaces_only)
344  {
345  fprintf(stderr, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"),
346  progname);
347  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
348  progname);
349  exit_nicely(1);
350  }
351 
352  if (if_exists && !output_clean)
353  {
354  fprintf(stderr, _("%s: option --if-exists requires option -c/--clean\n"),
355  progname);
356  exit_nicely(1);
357  }
358 
359  if (roles_only && tablespaces_only)
360  {
361  fprintf(stderr, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"),
362  progname);
363  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
364  progname);
365  exit_nicely(1);
366  }
367 
368  /*
369  * If password values are not required in the dump, switch to using
370  * pg_roles which is equally useful, just more likely to have unrestricted
371  * access than pg_authid.
372  */
373  if (no_role_passwords)
374  sprintf(role_catalog, "%s", PG_ROLES);
375  else
376  sprintf(role_catalog, "%s", PG_AUTHID);
377 
378  /* Add long options to the pg_dump argument list */
379  if (binary_upgrade)
380  appendPQExpBufferStr(pgdumpopts, " --binary-upgrade");
381  if (column_inserts)
382  appendPQExpBufferStr(pgdumpopts, " --column-inserts");
384  appendPQExpBufferStr(pgdumpopts, " --disable-dollar-quoting");
385  if (disable_triggers)
386  appendPQExpBufferStr(pgdumpopts, " --disable-triggers");
387  if (inserts)
388  appendPQExpBufferStr(pgdumpopts, " --inserts");
389  if (no_tablespaces)
390  appendPQExpBufferStr(pgdumpopts, " --no-tablespaces");
392  appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers");
394  appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root");
395  if (use_setsessauth)
396  appendPQExpBufferStr(pgdumpopts, " --use-set-session-authorization");
397  if (no_comments)
398  appendPQExpBufferStr(pgdumpopts, " --no-comments");
399  if (no_publications)
400  appendPQExpBufferStr(pgdumpopts, " --no-publications");
401  if (no_security_labels)
402  appendPQExpBufferStr(pgdumpopts, " --no-security-labels");
403  if (no_subscriptions)
404  appendPQExpBufferStr(pgdumpopts, " --no-subscriptions");
406  appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data");
407 
408  /*
409  * If there was a database specified on the command line, use that,
410  * otherwise try to connect to database "postgres", and failing that
411  * "template1". "postgres" is the preferred choice for 8.1 and later
412  * servers, but it usually will not exist on older ones.
413  */
414  if (pgdb)
415  {
416  conn = connectDatabase(pgdb, connstr, pghost, pgport, pguser,
417  prompt_password, false);
418 
419  if (!conn)
420  {
421  fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
422  progname, pgdb);
423  exit_nicely(1);
424  }
425  }
426  else
427  {
428  conn = connectDatabase("postgres", connstr, pghost, pgport, pguser,
429  prompt_password, false);
430  if (!conn)
431  conn = connectDatabase("template1", connstr, pghost, pgport, pguser,
432  prompt_password, true);
433 
434  if (!conn)
435  {
436  fprintf(stderr, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
437  "Please specify an alternative database.\n"),
438  progname);
439  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
440  progname);
441  exit_nicely(1);
442  }
443  }
444 
445  /*
446  * Open the output file if required, otherwise use stdout
447  */
448  if (filename)
449  {
450  OPF = fopen(filename, PG_BINARY_W);
451  if (!OPF)
452  {
453  fprintf(stderr, _("%s: could not open the output file \"%s\": %s\n"),
454  progname, filename, strerror(errno));
455  exit_nicely(1);
456  }
457  }
458  else
459  OPF = stdout;
460 
461  /*
462  * Set the client encoding if requested.
463  */
464  if (dumpencoding)
465  {
466  if (PQsetClientEncoding(conn, dumpencoding) < 0)
467  {
468  fprintf(stderr, _("%s: invalid client encoding \"%s\" specified\n"),
469  progname, dumpencoding);
470  exit_nicely(1);
471  }
472  }
473 
474  /*
475  * Get the active encoding and the standard_conforming_strings setting, so
476  * we know how to escape strings.
477  */
478  encoding = PQclientEncoding(conn);
479  std_strings = PQparameterStatus(conn, "standard_conforming_strings");
480  if (!std_strings)
481  std_strings = "off";
482 
483  /* Set the role if requested */
484  if (use_role && server_version >= 80100)
485  {
486  PQExpBuffer query = createPQExpBuffer();
487 
488  appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
489  executeCommand(conn, query->data);
490  destroyPQExpBuffer(query);
491  }
492 
493  /* Force quoting of all identifiers if requested. */
494  if (quote_all_identifiers && server_version >= 90100)
495  executeCommand(conn, "SET quote_all_identifiers = true");
496 
497  fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
498  if (verbose)
499  dumpTimestamp("Started on");
500 
501  /*
502  * We used to emit \connect postgres here, but that served no purpose
503  * other than to break things for installations without a postgres
504  * database. Everything we're restoring here is a global, so whichever
505  * database we're connected to at the moment is fine.
506  */
507 
508  /* Restore will need to write to the target cluster */
509  fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
510 
511  /* Replicate encoding and std_strings in output */
512  fprintf(OPF, "SET client_encoding = '%s';\n",
513  pg_encoding_to_char(encoding));
514  fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
515  if (strcmp(std_strings, "off") == 0)
516  fprintf(OPF, "SET escape_string_warning = off;\n");
517  fprintf(OPF, "\n");
518 
519  if (!data_only)
520  {
521  /*
522  * If asked to --clean, do that first. We can avoid detailed
523  * dependency analysis because databases never depend on each other,
524  * and tablespaces never depend on each other. Roles could have
525  * grants to each other, but DROP ROLE will clean those up silently.
526  */
527  if (output_clean)
528  {
529  if (!globals_only && !roles_only && !tablespaces_only)
530  dropDBs(conn);
531 
532  if (!roles_only && !no_tablespaces)
533  dropTablespaces(conn);
534 
535  if (!tablespaces_only)
536  dropRoles(conn);
537  }
538 
539  /*
540  * Now create objects as requested. Be careful that option logic here
541  * is the same as for drops above.
542  */
543  if (!tablespaces_only)
544  {
545  /* Dump roles (users) */
546  dumpRoles(conn);
547 
548  /* Dump role memberships --- need different method for pre-8.1 */
549  if (server_version >= 80100)
550  dumpRoleMembership(conn);
551  else
552  dumpGroups(conn);
553  }
554 
555  /* Dump tablespaces */
556  if (!roles_only && !no_tablespaces)
557  dumpTablespaces(conn);
558  }
559 
560  if (!globals_only && !roles_only && !tablespaces_only)
561  dumpDatabases(conn);
562 
563  PQfinish(conn);
564 
565  if (verbose)
566  dumpTimestamp("Completed on");
567  fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
568 
569  if (filename)
570  {
571  fclose(OPF);
572 
573  /* sync the resulting file, errors are not fatal */
574  if (dosync)
575  (void) fsync_fname(filename, false, progname);
576  }
577 
578  exit_nicely(0);
579 }
580 
581 
582 static void
583 help(void)
584 {
585  printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
586  printf(_("Usage:\n"));
587  printf(_(" %s [OPTION]...\n"), progname);
588 
589  printf(_("\nGeneral options:\n"));
590  printf(_(" -f, --file=FILENAME output file name\n"));
591  printf(_(" -v, --verbose verbose mode\n"));
592  printf(_(" -V, --version output version information, then exit\n"));
593  printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
594  printf(_(" -?, --help show this help, then exit\n"));
595  printf(_("\nOptions controlling the output content:\n"));
596  printf(_(" -a, --data-only dump only the data, not the schema\n"));
597  printf(_(" -c, --clean clean (drop) databases before recreating\n"));
598  printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
599  printf(_(" -g, --globals-only dump only global objects, no databases\n"));
600  printf(_(" -o, --oids include OIDs in dump\n"));
601  printf(_(" -O, --no-owner skip restoration of object ownership\n"));
602  printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
603  printf(_(" -s, --schema-only dump only the schema, no data\n"));
604  printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
605  printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
606  printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
607  printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
608  printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
609  printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
610  printf(_(" --disable-triggers disable triggers during data-only restore\n"));
611  printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
612  printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
613  printf(_(" --no-comments do not dump comments\n"));
614  printf(_(" --no-publications do not dump publications\n"));
615  printf(_(" --no-role-passwords do not dump passwords for roles\n"));
616  printf(_(" --no-security-labels do not dump security label assignments\n"));
617  printf(_(" --no-subscriptions do not dump subscriptions\n"));
618  printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
619  printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
620  printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
621  printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
622  printf(_(" --load-via-partition-root load partitions via the root table\n"));
623  printf(_(" --use-set-session-authorization\n"
624  " use SET SESSION AUTHORIZATION commands instead of\n"
625  " ALTER OWNER commands to set ownership\n"));
626 
627  printf(_("\nConnection options:\n"));
628  printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
629  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
630  printf(_(" -l, --database=DBNAME alternative default database\n"));
631  printf(_(" -p, --port=PORT database server port number\n"));
632  printf(_(" -U, --username=NAME connect as specified database user\n"));
633  printf(_(" -w, --no-password never prompt for password\n"));
634  printf(_(" -W, --password force password prompt (should happen automatically)\n"));
635  printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
636 
637  printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
638  "output.\n\n"));
639  printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
640 }
641 
642 
643 /*
644  * Drop roles
645  */
646 static void
648 {
650  PGresult *res;
651  int i_rolname;
652  int i;
653 
654  if (server_version >= 90600)
655  printfPQExpBuffer(buf,
656  "SELECT rolname "
657  "FROM %s "
658  "WHERE rolname !~ '^pg_' "
659  "ORDER BY 1", role_catalog);
660  else if (server_version >= 80100)
661  printfPQExpBuffer(buf,
662  "SELECT rolname "
663  "FROM %s "
664  "ORDER BY 1", role_catalog);
665  else
666  printfPQExpBuffer(buf,
667  "SELECT usename as rolname "
668  "FROM pg_shadow "
669  "UNION "
670  "SELECT groname as rolname "
671  "FROM pg_group "
672  "ORDER BY 1");
673 
674  res = executeQuery(conn, buf->data);
675 
676  i_rolname = PQfnumber(res, "rolname");
677 
678  if (PQntuples(res) > 0)
679  fprintf(OPF, "--\n-- Drop roles\n--\n\n");
680 
681  for (i = 0; i < PQntuples(res); i++)
682  {
683  const char *rolename;
684 
685  rolename = PQgetvalue(res, i, i_rolname);
686 
687  fprintf(OPF, "DROP ROLE %s%s;\n",
688  if_exists ? "IF EXISTS " : "",
689  fmtId(rolename));
690  }
691 
692  PQclear(res);
693  destroyPQExpBuffer(buf);
694 
695  fprintf(OPF, "\n\n");
696 }
697 
698 /*
699  * Dump roles
700  */
701 static void
703 {
705  PGresult *res;
706  int i_oid,
707  i_rolname,
708  i_rolsuper,
709  i_rolinherit,
710  i_rolcreaterole,
711  i_rolcreatedb,
712  i_rolcanlogin,
713  i_rolconnlimit,
714  i_rolpassword,
715  i_rolvaliduntil,
716  i_rolreplication,
717  i_rolbypassrls,
718  i_rolcomment,
719  i_is_current_user;
720  int i;
721 
722  /* note: rolconfig is dumped later */
723  if (server_version >= 90600)
724  printfPQExpBuffer(buf,
725  "SELECT oid, rolname, rolsuper, rolinherit, "
726  "rolcreaterole, rolcreatedb, "
727  "rolcanlogin, rolconnlimit, rolpassword, "
728  "rolvaliduntil, rolreplication, rolbypassrls, "
729  "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
730  "rolname = current_user AS is_current_user "
731  "FROM %s "
732  "WHERE rolname !~ '^pg_' "
733  "ORDER BY 2", role_catalog, role_catalog);
734  else if (server_version >= 90500)
735  printfPQExpBuffer(buf,
736  "SELECT oid, rolname, rolsuper, rolinherit, "
737  "rolcreaterole, rolcreatedb, "
738  "rolcanlogin, rolconnlimit, rolpassword, "
739  "rolvaliduntil, rolreplication, rolbypassrls, "
740  "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
741  "rolname = current_user AS is_current_user "
742  "FROM %s "
743  "ORDER BY 2", role_catalog, role_catalog);
744  else if (server_version >= 90100)
745  printfPQExpBuffer(buf,
746  "SELECT oid, rolname, rolsuper, rolinherit, "
747  "rolcreaterole, rolcreatedb, "
748  "rolcanlogin, rolconnlimit, rolpassword, "
749  "rolvaliduntil, rolreplication, "
750  "false as rolbypassrls, "
751  "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
752  "rolname = current_user AS is_current_user "
753  "FROM %s "
754  "ORDER BY 2", role_catalog, role_catalog);
755  else if (server_version >= 80200)
756  printfPQExpBuffer(buf,
757  "SELECT oid, rolname, rolsuper, rolinherit, "
758  "rolcreaterole, rolcreatedb, "
759  "rolcanlogin, rolconnlimit, rolpassword, "
760  "rolvaliduntil, false as rolreplication, "
761  "false as rolbypassrls, "
762  "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
763  "rolname = current_user AS is_current_user "
764  "FROM %s "
765  "ORDER BY 2", role_catalog, role_catalog);
766  else if (server_version >= 80100)
767  printfPQExpBuffer(buf,
768  "SELECT oid, rolname, rolsuper, rolinherit, "
769  "rolcreaterole, rolcreatedb, "
770  "rolcanlogin, rolconnlimit, rolpassword, "
771  "rolvaliduntil, false as rolreplication, "
772  "false as rolbypassrls, "
773  "null as rolcomment, "
774  "rolname = current_user AS is_current_user "
775  "FROM %s "
776  "ORDER BY 2", role_catalog);
777  else
778  printfPQExpBuffer(buf,
779  "SELECT 0 as oid, usename as rolname, "
780  "usesuper as rolsuper, "
781  "true as rolinherit, "
782  "usesuper as rolcreaterole, "
783  "usecreatedb as rolcreatedb, "
784  "true as rolcanlogin, "
785  "-1 as rolconnlimit, "
786  "passwd as rolpassword, "
787  "valuntil as rolvaliduntil, "
788  "false as rolreplication, "
789  "false as rolbypassrls, "
790  "null as rolcomment, "
791  "usename = current_user AS is_current_user "
792  "FROM pg_shadow "
793  "UNION ALL "
794  "SELECT 0 as oid, groname as rolname, "
795  "false as rolsuper, "
796  "true as rolinherit, "
797  "false as rolcreaterole, "
798  "false as rolcreatedb, "
799  "false as rolcanlogin, "
800  "-1 as rolconnlimit, "
801  "null::text as rolpassword, "
802  "null::abstime as rolvaliduntil, "
803  "false as rolreplication, "
804  "false as rolbypassrls, "
805  "null as rolcomment, "
806  "false AS is_current_user "
807  "FROM pg_group "
808  "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
809  " WHERE usename = groname) "
810  "ORDER BY 2");
811 
812  res = executeQuery(conn, buf->data);
813 
814  i_oid = PQfnumber(res, "oid");
815  i_rolname = PQfnumber(res, "rolname");
816  i_rolsuper = PQfnumber(res, "rolsuper");
817  i_rolinherit = PQfnumber(res, "rolinherit");
818  i_rolcreaterole = PQfnumber(res, "rolcreaterole");
819  i_rolcreatedb = PQfnumber(res, "rolcreatedb");
820  i_rolcanlogin = PQfnumber(res, "rolcanlogin");
821  i_rolconnlimit = PQfnumber(res, "rolconnlimit");
822  i_rolpassword = PQfnumber(res, "rolpassword");
823  i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
824  i_rolreplication = PQfnumber(res, "rolreplication");
825  i_rolbypassrls = PQfnumber(res, "rolbypassrls");
826  i_rolcomment = PQfnumber(res, "rolcomment");
827  i_is_current_user = PQfnumber(res, "is_current_user");
828 
829  if (PQntuples(res) > 0)
830  fprintf(OPF, "--\n-- Roles\n--\n\n");
831 
832  for (i = 0; i < PQntuples(res); i++)
833  {
834  const char *rolename;
835  Oid auth_oid;
836 
837  auth_oid = atooid(PQgetvalue(res, i, i_oid));
838  rolename = PQgetvalue(res, i, i_rolname);
839 
840  if (strncmp(rolename, "pg_", 3) == 0)
841  {
842  fprintf(stderr, _("%s: role name starting with \"pg_\" skipped (%s)\n"),
843  progname, rolename);
844  continue;
845  }
846 
847  resetPQExpBuffer(buf);
848 
849  if (binary_upgrade)
850  {
851  appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
852  appendPQExpBuffer(buf,
853  "SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
854  auth_oid);
855  }
856 
857  /*
858  * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
859  * will acquire the right properties even if it already exists (ie, it
860  * won't hurt for the CREATE to fail). This is particularly important
861  * for the role we are connected as, since even with --clean we will
862  * have failed to drop it. binary_upgrade cannot generate any errors,
863  * so we assume the current role is already created.
864  */
865  if (!binary_upgrade ||
866  strcmp(PQgetvalue(res, i, i_is_current_user), "f") == 0)
867  appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
868  appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
869 
870  if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
871  appendPQExpBufferStr(buf, " SUPERUSER");
872  else
873  appendPQExpBufferStr(buf, " NOSUPERUSER");
874 
875  if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
876  appendPQExpBufferStr(buf, " INHERIT");
877  else
878  appendPQExpBufferStr(buf, " NOINHERIT");
879 
880  if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
881  appendPQExpBufferStr(buf, " CREATEROLE");
882  else
883  appendPQExpBufferStr(buf, " NOCREATEROLE");
884 
885  if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
886  appendPQExpBufferStr(buf, " CREATEDB");
887  else
888  appendPQExpBufferStr(buf, " NOCREATEDB");
889 
890  if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
891  appendPQExpBufferStr(buf, " LOGIN");
892  else
893  appendPQExpBufferStr(buf, " NOLOGIN");
894 
895  if (strcmp(PQgetvalue(res, i, i_rolreplication), "t") == 0)
896  appendPQExpBufferStr(buf, " REPLICATION");
897  else
898  appendPQExpBufferStr(buf, " NOREPLICATION");
899 
900  if (strcmp(PQgetvalue(res, i, i_rolbypassrls), "t") == 0)
901  appendPQExpBufferStr(buf, " BYPASSRLS");
902  else
903  appendPQExpBufferStr(buf, " NOBYPASSRLS");
904 
905  if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
906  appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
907  PQgetvalue(res, i, i_rolconnlimit));
908 
909 
910  if (!PQgetisnull(res, i, i_rolpassword) && !no_role_passwords)
911  {
912  appendPQExpBufferStr(buf, " PASSWORD ");
913  appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolpassword), conn);
914  }
915 
916  if (!PQgetisnull(res, i, i_rolvaliduntil))
917  appendPQExpBuffer(buf, " VALID UNTIL '%s'",
918  PQgetvalue(res, i, i_rolvaliduntil));
919 
920  appendPQExpBufferStr(buf, ";\n");
921 
922  if (!no_comments && !PQgetisnull(res, i, i_rolcomment))
923  {
924  appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
925  appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolcomment), conn);
926  appendPQExpBufferStr(buf, ";\n");
927  }
928 
929  if (!no_security_labels && server_version >= 90200)
930  buildShSecLabels(conn, "pg_authid", auth_oid,
931  buf, "ROLE", rolename);
932 
933  fprintf(OPF, "%s", buf->data);
934  }
935 
936  /*
937  * Dump configuration settings for roles after all roles have been dumped.
938  * We do it this way because config settings for roles could mention the
939  * names of other roles.
940  */
941  for (i = 0; i < PQntuples(res); i++)
942  dumpUserConfig(conn, PQgetvalue(res, i, i_rolname));
943 
944  PQclear(res);
945 
946  fprintf(OPF, "\n\n");
947 
948  destroyPQExpBuffer(buf);
949 }
950 
951 
952 /*
953  * Dump role memberships. This code is used for 8.1 and later servers.
954  *
955  * Note: we expect dumpRoles already created all the roles, but there is
956  * no membership yet.
957  */
958 static void
960 {
962  PGresult *res;
963  int i;
964 
965  printfPQExpBuffer(buf, "SELECT ur.rolname AS roleid, "
966  "um.rolname AS member, "
967  "a.admin_option, "
968  "ug.rolname AS grantor "
969  "FROM pg_auth_members a "
970  "LEFT JOIN %s ur on ur.oid = a.roleid "
971  "LEFT JOIN %s um on um.oid = a.member "
972  "LEFT JOIN %s ug on ug.oid = a.grantor "
973  "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
974  "ORDER BY 1,2,3", role_catalog, role_catalog, role_catalog);
975  res = executeQuery(conn, buf->data);
976 
977  if (PQntuples(res) > 0)
978  fprintf(OPF, "--\n-- Role memberships\n--\n\n");
979 
980  for (i = 0; i < PQntuples(res); i++)
981  {
982  char *roleid = PQgetvalue(res, i, 0);
983  char *member = PQgetvalue(res, i, 1);
984  char *option = PQgetvalue(res, i, 2);
985 
986  fprintf(OPF, "GRANT %s", fmtId(roleid));
987  fprintf(OPF, " TO %s", fmtId(member));
988  if (*option == 't')
989  fprintf(OPF, " WITH ADMIN OPTION");
990 
991  /*
992  * We don't track the grantor very carefully in the backend, so cope
993  * with the possibility that it has been dropped.
994  */
995  if (!PQgetisnull(res, i, 3))
996  {
997  char *grantor = PQgetvalue(res, i, 3);
998 
999  fprintf(OPF, " GRANTED BY %s", fmtId(grantor));
1000  }
1001  fprintf(OPF, ";\n");
1002  }
1003 
1004  PQclear(res);
1005  destroyPQExpBuffer(buf);
1006 
1007  fprintf(OPF, "\n\n");
1008 }
1009 
1010 /*
1011  * Dump group memberships from a pre-8.1 server. It's annoying that we
1012  * can't share any useful amount of code with the post-8.1 case, but
1013  * the catalog representations are too different.
1014  *
1015  * Note: we expect dumpRoles already created all the roles, but there is
1016  * no membership yet.
1017  */
1018 static void
1020 {
1022  PGresult *res;
1023  int i;
1024 
1025  res = executeQuery(conn,
1026  "SELECT groname, grolist FROM pg_group ORDER BY 1");
1027 
1028  if (PQntuples(res) > 0)
1029  fprintf(OPF, "--\n-- Role memberships\n--\n\n");
1030 
1031  for (i = 0; i < PQntuples(res); i++)
1032  {
1033  char *groname = PQgetvalue(res, i, 0);
1034  char *grolist = PQgetvalue(res, i, 1);
1035  PGresult *res2;
1036  int j;
1037 
1038  /*
1039  * Array representation is {1,2,3} ... convert to (1,2,3)
1040  */
1041  if (strlen(grolist) < 3)
1042  continue;
1043 
1044  grolist = pg_strdup(grolist);
1045  grolist[0] = '(';
1046  grolist[strlen(grolist) - 1] = ')';
1047  printfPQExpBuffer(buf,
1048  "SELECT usename FROM pg_shadow "
1049  "WHERE usesysid IN %s ORDER BY 1",
1050  grolist);
1051  free(grolist);
1052 
1053  res2 = executeQuery(conn, buf->data);
1054 
1055  for (j = 0; j < PQntuples(res2); j++)
1056  {
1057  char *usename = PQgetvalue(res2, j, 0);
1058 
1059  /*
1060  * Don't try to grant a role to itself; can happen if old
1061  * installation has identically named user and group.
1062  */
1063  if (strcmp(groname, usename) == 0)
1064  continue;
1065 
1066  fprintf(OPF, "GRANT %s", fmtId(groname));
1067  fprintf(OPF, " TO %s;\n", fmtId(usename));
1068  }
1069 
1070  PQclear(res2);
1071  }
1072 
1073  PQclear(res);
1074  destroyPQExpBuffer(buf);
1075 
1076  fprintf(OPF, "\n\n");
1077 }
1078 
1079 
1080 /*
1081  * Drop tablespaces.
1082  */
1083 static void
1085 {
1086  PGresult *res;
1087  int i;
1088 
1089  /*
1090  * Get all tablespaces except built-in ones (which we assume are named
1091  * pg_xxx)
1092  */
1093  res = executeQuery(conn, "SELECT spcname "
1094  "FROM pg_catalog.pg_tablespace "
1095  "WHERE spcname !~ '^pg_' "
1096  "ORDER BY 1");
1097 
1098  if (PQntuples(res) > 0)
1099  fprintf(OPF, "--\n-- Drop tablespaces\n--\n\n");
1100 
1101  for (i = 0; i < PQntuples(res); i++)
1102  {
1103  char *spcname = PQgetvalue(res, i, 0);
1104 
1105  fprintf(OPF, "DROP TABLESPACE %s%s;\n",
1106  if_exists ? "IF EXISTS " : "",
1107  fmtId(spcname));
1108  }
1109 
1110  PQclear(res);
1111 
1112  fprintf(OPF, "\n\n");
1113 }
1114 
1115 /*
1116  * Dump tablespaces.
1117  */
1118 static void
1120 {
1121  PGresult *res;
1122  int i;
1123 
1124  /*
1125  * Get all tablespaces except built-in ones (which we assume are named
1126  * pg_xxx)
1127  *
1128  * For the tablespace ACLs, as of 9.6, we extract both the positive (as
1129  * spcacl) and negative (as rspcacl) ACLs, relative to the default ACL for
1130  * tablespaces, which are then passed to buildACLCommands() below.
1131  *
1132  * See buildACLQueries() and buildACLCommands().
1133  *
1134  * Note that we do not support initial privileges (pg_init_privs) on
1135  * tablespaces.
1136  */
1137  if (server_version >= 90600)
1138  res = executeQuery(conn, "SELECT oid, spcname, "
1139  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1140  "pg_catalog.pg_tablespace_location(oid), "
1141  "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner))) AS acl "
1142  "EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner))) as foo)"
1143  "AS spcacl,"
1144  "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner)) AS acl "
1145  "EXCEPT SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner)))) as foo)"
1146  "AS rspcacl,"
1147  "array_to_string(spcoptions, ', '),"
1148  "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1149  "FROM pg_catalog.pg_tablespace "
1150  "WHERE spcname !~ '^pg_' "
1151  "ORDER BY 1");
1152  else if (server_version >= 90200)
1153  res = executeQuery(conn, "SELECT oid, spcname, "
1154  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1155  "pg_catalog.pg_tablespace_location(oid), "
1156  "spcacl, '' as rspcacl, "
1157  "array_to_string(spcoptions, ', '),"
1158  "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1159  "FROM pg_catalog.pg_tablespace "
1160  "WHERE spcname !~ '^pg_' "
1161  "ORDER BY 1");
1162  else if (server_version >= 90000)
1163  res = executeQuery(conn, "SELECT oid, spcname, "
1164  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1165  "spclocation, spcacl, '' as rspcacl, "
1166  "array_to_string(spcoptions, ', '),"
1167  "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1168  "FROM pg_catalog.pg_tablespace "
1169  "WHERE spcname !~ '^pg_' "
1170  "ORDER BY 1");
1171  else if (server_version >= 80200)
1172  res = executeQuery(conn, "SELECT oid, spcname, "
1173  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1174  "spclocation, spcacl, '' as rspcacl, null, "
1175  "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1176  "FROM pg_catalog.pg_tablespace "
1177  "WHERE spcname !~ '^pg_' "
1178  "ORDER BY 1");
1179  else
1180  res = executeQuery(conn, "SELECT oid, spcname, "
1181  "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1182  "spclocation, spcacl, '' as rspcacl, "
1183  "null, null "
1184  "FROM pg_catalog.pg_tablespace "
1185  "WHERE spcname !~ '^pg_' "
1186  "ORDER BY 1");
1187 
1188  if (PQntuples(res) > 0)
1189  fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
1190 
1191  for (i = 0; i < PQntuples(res); i++)
1192  {
1194  uint32 spcoid = atooid(PQgetvalue(res, i, 0));
1195  char *spcname = PQgetvalue(res, i, 1);
1196  char *spcowner = PQgetvalue(res, i, 2);
1197  char *spclocation = PQgetvalue(res, i, 3);
1198  char *spcacl = PQgetvalue(res, i, 4);
1199  char *rspcacl = PQgetvalue(res, i, 5);
1200  char *spcoptions = PQgetvalue(res, i, 6);
1201  char *spccomment = PQgetvalue(res, i, 7);
1202  char *fspcname;
1203 
1204  /* needed for buildACLCommands() */
1205  fspcname = pg_strdup(fmtId(spcname));
1206 
1207  appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
1208  appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
1209 
1210  appendPQExpBufferStr(buf, " LOCATION ");
1211  appendStringLiteralConn(buf, spclocation, conn);
1212  appendPQExpBufferStr(buf, ";\n");
1213 
1214  if (spcoptions && spcoptions[0] != '\0')
1215  appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
1216  fspcname, spcoptions);
1217 
1218  if (!skip_acls &&
1219  !buildACLCommands(fspcname, NULL, "TABLESPACE", spcacl, rspcacl,
1220  spcowner, "", server_version, buf))
1221  {
1222  fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
1223  progname, spcacl, fspcname);
1224  PQfinish(conn);
1225  exit_nicely(1);
1226  }
1227 
1228  if (!no_comments && spccomment && spccomment[0] != '\0')
1229  {
1230  appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
1231  appendStringLiteralConn(buf, spccomment, conn);
1232  appendPQExpBufferStr(buf, ";\n");
1233  }
1234 
1235  if (!no_security_labels && server_version >= 90200)
1236  buildShSecLabels(conn, "pg_tablespace", spcoid,
1237  buf, "TABLESPACE", fspcname);
1238 
1239  fprintf(OPF, "%s", buf->data);
1240 
1241  free(fspcname);
1242  destroyPQExpBuffer(buf);
1243  }
1244 
1245  PQclear(res);
1246  fprintf(OPF, "\n\n");
1247 }
1248 
1249 
1250 /*
1251  * Dump commands to drop each database.
1252  */
1253 static void
1255 {
1256  PGresult *res;
1257  int i;
1258 
1259  /*
1260  * Skip databases marked not datallowconn, since we'd be unable to connect
1261  * to them anyway. This must agree with dumpDatabases().
1262  */
1263  res = executeQuery(conn,
1264  "SELECT datname "
1265  "FROM pg_database d "
1266  "WHERE datallowconn "
1267  "ORDER BY datname");
1268 
1269  if (PQntuples(res) > 0)
1270  fprintf(OPF, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
1271 
1272  for (i = 0; i < PQntuples(res); i++)
1273  {
1274  char *dbname = PQgetvalue(res, i, 0);
1275 
1276  /*
1277  * Skip "postgres" and "template1"; dumpDatabases() will deal with
1278  * them specially. Also, be sure to skip "template0", even if for
1279  * some reason it's not marked !datallowconn.
1280  */
1281  if (strcmp(dbname, "template1") != 0 &&
1282  strcmp(dbname, "template0") != 0 &&
1283  strcmp(dbname, "postgres") != 0)
1284  {
1285  fprintf(OPF, "DROP DATABASE %s%s;\n",
1286  if_exists ? "IF EXISTS " : "",
1287  fmtId(dbname));
1288  }
1289  }
1290 
1291  PQclear(res);
1292 
1293  fprintf(OPF, "\n\n");
1294 }
1295 
1296 
1297 /*
1298  * Dump user-specific configuration
1299  */
1300 static void
1302 {
1304  int count = 1;
1305 
1306  for (;;)
1307  {
1308  PGresult *res;
1309 
1310  if (server_version >= 90000)
1311  printfPQExpBuffer(buf, "SELECT setconfig[%d] FROM pg_db_role_setting WHERE "
1312  "setdatabase = 0 AND setrole = "
1313  "(SELECT oid FROM %s WHERE rolname = ", count, role_catalog);
1314  else if (server_version >= 80100)
1315  printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM %s WHERE rolname = ", count, role_catalog);
1316  else
1317  printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
1318  appendStringLiteralConn(buf, username, conn);
1319  if (server_version >= 90000)
1320  appendPQExpBufferChar(buf, ')');
1321 
1322  res = executeQuery(conn, buf->data);
1323  if (PQntuples(res) == 1 &&
1324  !PQgetisnull(res, 0, 0))
1325  {
1326  resetPQExpBuffer(buf);
1327  makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
1328  "ROLE", username, NULL, NULL,
1329  buf);
1330  fprintf(OPF, "%s", buf->data);
1331  PQclear(res);
1332  count++;
1333  }
1334  else
1335  {
1336  PQclear(res);
1337  break;
1338  }
1339  }
1340 
1341  destroyPQExpBuffer(buf);
1342 }
1343 
1344 
1345 /*
1346  * Dump contents of databases.
1347  */
1348 static void
1350 {
1351  PGresult *res;
1352  int i;
1353 
1354  /*
1355  * Skip databases marked not datallowconn, since we'd be unable to connect
1356  * to them anyway. This must agree with dropDBs().
1357  *
1358  * We arrange for template1 to be processed first, then we process other
1359  * DBs in alphabetical order. If we just did them all alphabetically, we
1360  * might find ourselves trying to drop the "postgres" database while still
1361  * connected to it. This makes trying to run the restore script while
1362  * connected to "template1" a bad idea, but there's no fixed order that
1363  * doesn't have some failure mode with --clean.
1364  */
1365  res = executeQuery(conn,
1366  "SELECT datname "
1367  "FROM pg_database d "
1368  "WHERE datallowconn "
1369  "ORDER BY (datname <> 'template1'), datname");
1370 
1371  for (i = 0; i < PQntuples(res); i++)
1372  {
1373  char *dbname = PQgetvalue(res, i, 0);
1374  const char *create_opts;
1375  int ret;
1376 
1377  /* Skip template0, even if it's not marked !datallowconn. */
1378  if (strcmp(dbname, "template0") == 0)
1379  continue;
1380 
1381  if (verbose)
1382  fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
1383 
1384  /*
1385  * We assume that "template1" and "postgres" already exist in the
1386  * target installation. dropDBs() won't have removed them, for fear
1387  * of removing the DB the restore script is initially connected to. If
1388  * --clean was specified, tell pg_dump to drop and recreate them;
1389  * otherwise we'll merely restore their contents. Other databases
1390  * should simply be created.
1391  */
1392  if (strcmp(dbname, "template1") == 0 || strcmp(dbname, "postgres") == 0)
1393  {
1394  if (output_clean)
1395  create_opts = "--clean --create";
1396  else
1397  {
1398  create_opts = "";
1399  /* Since pg_dump won't emit a \connect command, we must */
1400  fprintf(OPF, "\\connect %s\n\n", dbname);
1401  }
1402  }
1403  else
1404  create_opts = "--create";
1405 
1406  if (filename)
1407  fclose(OPF);
1408 
1409  ret = runPgDump(dbname, create_opts);
1410  if (ret != 0)
1411  {
1412  fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
1413  exit_nicely(1);
1414  }
1415 
1416  if (filename)
1417  {
1418  OPF = fopen(filename, PG_BINARY_A);
1419  if (!OPF)
1420  {
1421  fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"),
1422  progname, filename, strerror(errno));
1423  exit_nicely(1);
1424  }
1425  }
1426 
1427  }
1428 
1429  PQclear(res);
1430 }
1431 
1432 
1433 
1434 /*
1435  * Run pg_dump on dbname, with specified options.
1436  */
1437 static int
1438 runPgDump(const char *dbname, const char *create_opts)
1439 {
1440  PQExpBuffer connstrbuf = createPQExpBuffer();
1442  int ret;
1443 
1444  appendPQExpBuffer(cmd, "\"%s\" %s %s", pg_dump_bin,
1445  pgdumpopts->data, create_opts);
1446 
1447  /*
1448  * If we have a filename, use the undocumented plain-append pg_dump
1449  * format.
1450  */
1451  if (filename)
1452  appendPQExpBufferStr(cmd, " -Fa ");
1453  else
1454  appendPQExpBufferStr(cmd, " -Fp ");
1455 
1456  /*
1457  * Append the database name to the already-constructed stem of connection
1458  * string.
1459  */
1460  appendPQExpBuffer(connstrbuf, "%s dbname=", connstr);
1461  appendConnStrVal(connstrbuf, dbname);
1462 
1463  appendShellString(cmd, connstrbuf->data);
1464 
1465  if (verbose)
1466  fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);
1467 
1468  fflush(stdout);
1469  fflush(stderr);
1470 
1471  ret = system(cmd->data);
1472 
1473  destroyPQExpBuffer(cmd);
1474  destroyPQExpBuffer(connstrbuf);
1475 
1476  return ret;
1477 }
1478 
1479 /*
1480  * buildShSecLabels
1481  *
1482  * Build SECURITY LABEL command(s) for a shared object
1483  *
1484  * The caller has to provide object type and identifier to select security
1485  * labels from pg_seclabels system view.
1486  */
1487 static void
1488 buildShSecLabels(PGconn *conn, const char *catalog_name, uint32 objectId,
1489  PQExpBuffer buffer, const char *target, const char *objname)
1490 {
1492  PGresult *res;
1493 
1494  buildShSecLabelQuery(conn, catalog_name, objectId, sql);
1495  res = executeQuery(conn, sql->data);
1496  emitShSecLabels(conn, res, buffer, target, objname);
1497 
1498  PQclear(res);
1499  destroyPQExpBuffer(sql);
1500 }
1501 
1502 /*
1503  * Make a database connection with the given parameters. An
1504  * interactive password prompt is automatically issued if required.
1505  *
1506  * If fail_on_error is false, we return NULL without printing any message
1507  * on failure, but preserve any prompted password for the next try.
1508  *
1509  * On success, the global variable 'connstr' is set to a connection string
1510  * containing the options used.
1511  */
1512 static PGconn *
1513 connectDatabase(const char *dbname, const char *connection_string,
1514  const char *pghost, const char *pgport, const char *pguser,
1515  trivalue prompt_password, bool fail_on_error)
1516 {
1517  PGconn *conn;
1518  bool new_pass;
1519  const char *remoteversion_str;
1520  int my_version;
1521  const char **keywords = NULL;
1522  const char **values = NULL;
1523  PQconninfoOption *conn_opts = NULL;
1524  static bool have_password = false;
1525  static char password[100];
1526 
1527  if (prompt_password == TRI_YES && !have_password)
1528  {
1529  simple_prompt("Password: ", password, sizeof(password), false);
1530  have_password = true;
1531  }
1532 
1533  /*
1534  * Start the connection. Loop until we have a password if requested by
1535  * backend.
1536  */
1537  do
1538  {
1539  int argcount = 6;
1540  PQconninfoOption *conn_opt;
1541  char *err_msg = NULL;
1542  int i = 0;
1543 
1544  if (keywords)
1545  free(keywords);
1546  if (values)
1547  free(values);
1548  if (conn_opts)
1549  PQconninfoFree(conn_opts);
1550 
1551  /*
1552  * Merge the connection info inputs given in form of connection string
1553  * and other options. Explicitly discard any dbname value in the
1554  * connection string; otherwise, PQconnectdbParams() would interpret
1555  * that value as being itself a connection string.
1556  */
1557  if (connection_string)
1558  {
1559  conn_opts = PQconninfoParse(connection_string, &err_msg);
1560  if (conn_opts == NULL)
1561  {
1562  fprintf(stderr, "%s: %s", progname, err_msg);
1563  exit_nicely(1);
1564  }
1565 
1566  for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1567  {
1568  if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1569  strcmp(conn_opt->keyword, "dbname") != 0)
1570  argcount++;
1571  }
1572 
1573  keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1574  values = pg_malloc0((argcount + 1) * sizeof(*values));
1575 
1576  for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1577  {
1578  if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1579  strcmp(conn_opt->keyword, "dbname") != 0)
1580  {
1581  keywords[i] = conn_opt->keyword;
1582  values[i] = conn_opt->val;
1583  i++;
1584  }
1585  }
1586  }
1587  else
1588  {
1589  keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1590  values = pg_malloc0((argcount + 1) * sizeof(*values));
1591  }
1592 
1593  if (pghost)
1594  {
1595  keywords[i] = "host";
1596  values[i] = pghost;
1597  i++;
1598  }
1599  if (pgport)
1600  {
1601  keywords[i] = "port";
1602  values[i] = pgport;
1603  i++;
1604  }
1605  if (pguser)
1606  {
1607  keywords[i] = "user";
1608  values[i] = pguser;
1609  i++;
1610  }
1611  if (have_password)
1612  {
1613  keywords[i] = "password";
1614  values[i] = password;
1615  i++;
1616  }
1617  if (dbname)
1618  {
1619  keywords[i] = "dbname";
1620  values[i] = dbname;
1621  i++;
1622  }
1623  keywords[i] = "fallback_application_name";
1624  values[i] = progname;
1625  i++;
1626 
1627  new_pass = false;
1628  conn = PQconnectdbParams(keywords, values, true);
1629 
1630  if (!conn)
1631  {
1632  fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
1633  progname, dbname);
1634  exit_nicely(1);
1635  }
1636 
1637  if (PQstatus(conn) == CONNECTION_BAD &&
1638  PQconnectionNeedsPassword(conn) &&
1639  !have_password &&
1640  prompt_password != TRI_NO)
1641  {
1642  PQfinish(conn);
1643  simple_prompt("Password: ", password, sizeof(password), false);
1644  have_password = true;
1645  new_pass = true;
1646  }
1647  } while (new_pass);
1648 
1649  /* check to see that the backend connection was successfully made */
1650  if (PQstatus(conn) == CONNECTION_BAD)
1651  {
1652  if (fail_on_error)
1653  {
1654  fprintf(stderr,
1655  _("%s: could not connect to database \"%s\": %s\n"),
1656  progname, dbname, PQerrorMessage(conn));
1657  exit_nicely(1);
1658  }
1659  else
1660  {
1661  PQfinish(conn);
1662 
1663  free(keywords);
1664  free(values);
1665  PQconninfoFree(conn_opts);
1666 
1667  return NULL;
1668  }
1669  }
1670 
1671  /*
1672  * Ok, connected successfully. Remember the options used, in the form of a
1673  * connection string.
1674  */
1675  connstr = constructConnStr(keywords, values);
1676 
1677  free(keywords);
1678  free(values);
1679  PQconninfoFree(conn_opts);
1680 
1681  /* Check version */
1682  remoteversion_str = PQparameterStatus(conn, "server_version");
1683  if (!remoteversion_str)
1684  {
1685  fprintf(stderr, _("%s: could not get server version\n"), progname);
1686  exit_nicely(1);
1687  }
1689  if (server_version == 0)
1690  {
1691  fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
1692  progname, remoteversion_str);
1693  exit_nicely(1);
1694  }
1695 
1696  my_version = PG_VERSION_NUM;
1697 
1698  /*
1699  * We allow the server to be back to 8.0, and up to any minor release of
1700  * our own major version. (See also version check in pg_dump.c.)
1701  */
1702  if (my_version != server_version
1703  && (server_version < 80000 ||
1704  (server_version / 100) > (my_version / 100)))
1705  {
1706  fprintf(stderr, _("server version: %s; %s version: %s\n"),
1707  remoteversion_str, progname, PG_VERSION);
1708  fprintf(stderr, _("aborting because of server version mismatch\n"));
1709  exit_nicely(1);
1710  }
1711 
1712  /*
1713  * Make sure we are not fooled by non-system schemas in the search path.
1714  */
1715  executeCommand(conn, "SET search_path = pg_catalog");
1716 
1717  return conn;
1718 }
1719 
1720 /* ----------
1721  * Construct a connection string from the given keyword/value pairs. It is
1722  * used to pass the connection options to the pg_dump subprocess.
1723  *
1724  * The following parameters are excluded:
1725  * dbname - varies in each pg_dump invocation
1726  * password - it's not secure to pass a password on the command line
1727  * fallback_application_name - we'll let pg_dump set it
1728  * ----------
1729  */
1730 static char *
1731 constructConnStr(const char **keywords, const char **values)
1732 {
1734  char *connstr;
1735  int i;
1736  bool firstkeyword = true;
1737 
1738  /* Construct a new connection string in key='value' format. */
1739  for (i = 0; keywords[i] != NULL; i++)
1740  {
1741  if (strcmp(keywords[i], "dbname") == 0 ||
1742  strcmp(keywords[i], "password") == 0 ||
1743  strcmp(keywords[i], "fallback_application_name") == 0)
1744  continue;
1745 
1746  if (!firstkeyword)
1747  appendPQExpBufferChar(buf, ' ');
1748  firstkeyword = false;
1749  appendPQExpBuffer(buf, "%s=", keywords[i]);
1750  appendConnStrVal(buf, values[i]);
1751  }
1752 
1753  connstr = pg_strdup(buf->data);
1754  destroyPQExpBuffer(buf);
1755  return connstr;
1756 }
1757 
1758 /*
1759  * Run a query, return the results, exit program on failure.
1760  */
1761 static PGresult *
1762 executeQuery(PGconn *conn, const char *query)
1763 {
1764  PGresult *res;
1765 
1766  if (verbose)
1767  fprintf(stderr, _("%s: executing %s\n"), progname, query);
1768 
1769  res = PQexec(conn, query);
1770  if (!res ||
1772  {
1773  fprintf(stderr, _("%s: query failed: %s"),
1774  progname, PQerrorMessage(conn));
1775  fprintf(stderr, _("%s: query was: %s\n"),
1776  progname, query);
1777  PQfinish(conn);
1778  exit_nicely(1);
1779  }
1780 
1781  return res;
1782 }
1783 
1784 /*
1785  * As above for a SQL command (which returns nothing).
1786  */
1787 static void
1788 executeCommand(PGconn *conn, const char *query)
1789 {
1790  PGresult *res;
1791 
1792  if (verbose)
1793  fprintf(stderr, _("%s: executing %s\n"), progname, query);
1794 
1795  res = PQexec(conn, query);
1796  if (!res ||
1798  {
1799  fprintf(stderr, _("%s: query failed: %s"),
1800  progname, PQerrorMessage(conn));
1801  fprintf(stderr, _("%s: query was: %s\n"),
1802  progname, query);
1803  PQfinish(conn);
1804  exit_nicely(1);
1805  }
1806 
1807  PQclear(res);
1808 }
1809 
1810 
1811 /*
1812  * dumpTimestamp
1813  */
1814 static void
1815 dumpTimestamp(const char *msg)
1816 {
1817  char buf[64];
1818  time_t now = time(NULL);
1819 
1820  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0)
1821  fprintf(OPF, "-- %s %s\n\n", msg, buf);
1822 }
static void dumpTimestamp(const char *msg)
Definition: pg_dumpall.c:1815
static char password[100]
Definition: streamutil.c:45
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
Definition: exec.c:307
static PGresult * executeQuery(PGconn *conn, const char *query)
Definition: pg_dumpall.c:1762
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6115
int main(int argc, char *argv[])
Definition: pg_dumpall.c:90
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static int column_inserts
Definition: pg_dumpall.c:64
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6080
static int disable_dollar_quoting
Definition: pg_dumpall.c:65
static int no_publications
Definition: pg_dumpall.c:72
#define PGDUMP_VERSIONSTR
Definition: pg_dumpall.c:29
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
const char * get_progname(const char *argv0)
Definition: path.c:453
static FILE * OPF
Definition: pg_dumpall.c:84
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
void buildShSecLabelQuery(PGconn *conn, const char *catalog_name, uint32 objectId, PQExpBuffer sql)
Definition: dumputils.c:646
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:582
static void dropRoles(PGconn *conn)
Definition: pg_dumpall.c:647
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:551
static char * constructConnStr(const char **keywords, const char **values)
Definition: pg_dumpall.c:1731
static const char * progname
Definition: pg_dumpall.c:55
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3638
#define PG_BINARY_W
Definition: c.h:1072
static void dumpTablespaces(PGconn *conn)
Definition: pg_dumpall.c:1119
static int inserts
Definition: pg_dumpall.c:68
unsigned int Oid
Definition: postgres_ext.h:31
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6105
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6175
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:536
#define PG_AUTHID
Definition: pg_dumpall.c:81
static bool verbose
Definition: pg_dumpall.c:60
static void dropDBs(PGconn *conn)
Definition: pg_dumpall.c:1254
static void buildShSecLabels(PGconn *conn, const char *catalog_name, uint32 objectId, PQExpBuffer buffer, const char *target, const char *objname)
Definition: pg_dumpall.c:1488
static int disable_triggers
Definition: pg_dumpall.c:66
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
#define required_argument
Definition: getopt_long.h:25
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:4735
int optind
Definition: getopt.c:51
static int no_tablespaces
Definition: pg_dumpall.c:69
char * connection_string
Definition: streamutil.c:38
static bool output_clean
Definition: pg_dumpall.c:58
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PGconn * conn
Definition: streamutil.c:46
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
int find_my_exec(const char *argv0, char *retpath)
Definition: exec.c:119
static void executeCommand(PGconn *conn, const char *query)
Definition: pg_dumpall.c:1788
static int no_unlogged_table_data
Definition: pg_dumpall.c:75
char * c
static char * buf
Definition: pg_test_fsync.c:67
static PQExpBuffer pgdumpopts
Definition: pg_dumpall.c:56
void simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
Definition: sprompt.c:37
static void dumpRoleMembership(PGconn *conn)
Definition: pg_dumpall.c:959
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5965
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void dumpUserConfig(PGconn *conn, const char *username)
Definition: pg_dumpall.c:1301
unsigned int uint32
Definition: c.h:314
static void dumpGroups(PGconn *conn)
Definition: pg_dumpall.c:1019
#define atooid(x)
Definition: postgres_ext.h:42
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
Definition: dumputils.c:823
static bool dosync
Definition: pg_dumpall.c:61
char * pghost
Definition: pgbench.c:180
trivalue
Definition: vacuumlo.c:31
#define no_argument
Definition: getopt_long.h:24
#define exit_nicely(code)
Definition: pg_dumpall.c:87
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1043
static void dumpDatabases(PGconn *conn)
Definition: pg_dumpall.c:1349
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2832
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:6183
static void help(void)
Definition: pg_dumpall.c:583
static char * username
Definition: initdb.c:132
void PQclear(PGresult *res)
Definition: fe-exec.c:671
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:434
static int no_subscriptions
Definition: pg_dumpall.c:74
bool quote_all_identifiers
Definition: ruleutils.c:298
static int load_via_partition_root
Definition: pg_dumpall.c:78
static char * encoding
Definition: initdb.c:123
#define free(a)
Definition: header.h:65
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
static bool have_password
Definition: streamutil.c:44
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *target, const char *objname)
Definition: dumputils.c:662
static int use_setsessauth
Definition: pg_dumpall.c:70
static int no_comments
Definition: pg_dumpall.c:71
static PGconn * connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error)
Definition: pg_dumpall.c:1513
#define PG_BINARY_A
Definition: c.h:1070
static int if_exists
Definition: pg_dumpall.c:67
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
bool buildACLCommands(const char *name, const char *subname, const char *type, const char *acls, const char *racls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
Definition: dumputils.c:55
static int server_version
Definition: pg_dumpall.c:77
static char pg_dump_bin[MAXPGPATH]
Definition: pg_dumpall.c:54
static bool skip_acls
Definition: pg_dumpall.c:59
char * dbname
Definition: streamutil.c:42
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
static int binary_upgrade
Definition: pg_dumpall.c:63
static Datum values[MAXATTR]
Definition: bootstrap.c:164
#define PG_ROLES
Definition: pg_dumpall.c:82
static char * filename
Definition: pg_dumpall.c:85
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:298
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6149
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
char * optarg
Definition: getopt.c:53
static int no_role_passwords
Definition: pg_dumpall.c:76
int i
const char * strerror(int errnum)
Definition: strerror.c:19
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
static int no_security_labels
Definition: pg_dumpall.c:73
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6062
static int runPgDump(const char *dbname, const char *create_opts)
Definition: pg_dumpall.c:1438
#define _(x)
Definition: elog.c:84
char * pgport
Definition: pgbench.c:181
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
static void dumpRoles(PGconn *conn)
Definition: pg_dumpall.c:702
static char * connstr
Definition: pg_dumpall.c:57
static void dropTablespaces(PGconn *conn)
Definition: pg_dumpall.c:1084
static char role_catalog[10]
Definition: pg_dumpall.c:80