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