1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * pg_dumpall forces all pg_dump output to be text, since it also outputs
9 * text into the same output stream.
11 * src/bin/pg_dump/pg_dumpall.c
13 *-------------------------------------------------------------------------
16 #include "postgres_fe.h"
21 #include "getopt_long.h"
23 #include "dumputils.h"
24 #include "pg_backup.h"
25 #include "common/file_utils.h"
26 #include "fe_utils/connect.h"
27 #include "fe_utils/string_utils.h"
29 /* version string we expect back from pg_dump */
30 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
33 static void help(void);
35 static void dropRoles(PGconn *conn);
36 static void dumpRoles(PGconn *conn);
37 static void dumpRoleMembership(PGconn *conn);
38 static void dumpGroups(PGconn *conn);
39 static void dropTablespaces(PGconn *conn);
40 static void dumpTablespaces(PGconn *conn);
41 static void dropDBs(PGconn *conn);
42 static void dumpUserConfig(PGconn *conn, const char *username);
43 static void dumpDatabases(PGconn *conn);
44 static void dumpTimestamp(const char *msg);
45 static int runPgDump(const char *dbname, const char *create_opts);
46 static void buildShSecLabels(PGconn *conn,
47 const char *catalog_name, Oid objectId,
48 const char *objtype, const char *objname,
50 static PGconn *connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport,
51 const char *pguser, trivalue prompt_password, bool fail_on_error);
52 static char *constructConnStr(const char **keywords, const char **values);
53 static PGresult *executeQuery(PGconn *conn, const char *query);
54 static void executeCommand(PGconn *conn, const char *query);
56 static char pg_dump_bin[MAXPGPATH];
57 static const char *progname;
58 static PQExpBuffer pgdumpopts;
59 static char *connstr = "";
60 static bool output_clean = false;
61 static bool skip_acls = false;
62 static bool verbose = false;
63 static bool dosync = true;
65 static int binary_upgrade = 0;
66 static int column_inserts = 0;
67 static int disable_dollar_quoting = 0;
68 static int disable_triggers = 0;
69 static int if_exists = 0;
70 static int inserts = 0;
71 static int no_tablespaces = 0;
72 static int use_setsessauth = 0;
73 static int no_comments = 0;
74 static int no_publications = 0;
75 static int no_security_labels = 0;
76 static int no_subscriptions = 0;
77 static int no_unlogged_table_data = 0;
78 static int no_role_passwords = 0;
79 static int server_version;
80 static int load_via_partition_root = 0;
82 static char role_catalog[10];
83 #define PG_AUTHID "pg_authid"
84 #define PG_ROLES "pg_roles "
87 static char *filename = NULL;
89 #define exit_nicely(code) exit(code)
92 main(int argc, char *argv[])
94 static struct option long_options[] = {
95 {"data-only", no_argument, NULL, 'a'},
96 {"clean", no_argument, NULL, 'c'},
97 {"encoding", required_argument, NULL, 'E'},
98 {"file", required_argument, NULL, 'f'},
99 {"globals-only", no_argument, NULL, 'g'},
100 {"host", required_argument, NULL, 'h'},
101 {"dbname", required_argument, NULL, 'd'},
102 {"database", required_argument, NULL, 'l'},
103 {"oids", no_argument, NULL, 'o'},
104 {"no-owner", no_argument, NULL, 'O'},
105 {"port", required_argument, NULL, 'p'},
106 {"roles-only", no_argument, NULL, 'r'},
107 {"schema-only", no_argument, NULL, 's'},
108 {"superuser", required_argument, NULL, 'S'},
109 {"tablespaces-only", no_argument, NULL, 't'},
110 {"username", required_argument, NULL, 'U'},
111 {"verbose", no_argument, NULL, 'v'},
112 {"no-password", no_argument, NULL, 'w'},
113 {"password", no_argument, NULL, 'W'},
114 {"no-privileges", no_argument, NULL, 'x'},
115 {"no-acl", no_argument, NULL, 'x'},
118 * the following options don't have an equivalent short option letter
120 {"attribute-inserts", no_argument, &column_inserts, 1},
121 {"binary-upgrade", no_argument, &binary_upgrade, 1},
122 {"column-inserts", no_argument, &column_inserts, 1},
123 {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
124 {"disable-triggers", no_argument, &disable_triggers, 1},
125 {"if-exists", no_argument, &if_exists, 1},
126 {"inserts", no_argument, &inserts, 1},
127 {"lock-wait-timeout", required_argument, NULL, 2},
128 {"no-tablespaces", no_argument, &no_tablespaces, 1},
129 {"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
130 {"load-via-partition-root", no_argument, &load_via_partition_root, 1},
131 {"role", required_argument, NULL, 3},
132 {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
133 {"no-comments", no_argument, &no_comments, 1},
134 {"no-publications", no_argument, &no_publications, 1},
135 {"no-role-passwords", no_argument, &no_role_passwords, 1},
136 {"no-security-labels", no_argument, &no_security_labels, 1},
137 {"no-subscriptions", no_argument, &no_subscriptions, 1},
138 {"no-sync", no_argument, NULL, 4},
139 {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
148 char *use_role = NULL;
149 const char *dumpencoding = NULL;
150 trivalue prompt_password = TRI_DEFAULT;
151 bool data_only = false;
152 bool globals_only = false;
153 bool roles_only = false;
154 bool tablespaces_only = false;
157 const char *std_strings;
162 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
164 progname = get_progname(argv[0]);
168 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
173 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
175 puts("pg_dumpall (PostgreSQL) " PG_VERSION);
180 if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
183 char full_path[MAXPGPATH];
185 if (find_my_exec(argv[0], full_path) < 0)
186 strlcpy(full_path, progname, sizeof(full_path));
190 _("The program \"pg_dump\" is needed by %s "
191 "but was not found in the\n"
192 "same directory as \"%s\".\n"
193 "Check your installation.\n"),
194 progname, full_path);
197 _("The program \"pg_dump\" was found by \"%s\"\n"
198 "but was not the same version as %s.\n"
199 "Check your installation.\n"),
200 full_path, progname);
204 pgdumpopts = createPQExpBuffer();
206 while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1)
212 appendPQExpBufferStr(pgdumpopts, " -a");
220 connstr = pg_strdup(optarg);
224 dumpencoding = pg_strdup(optarg);
225 appendPQExpBufferStr(pgdumpopts, " -E ");
226 appendShellString(pgdumpopts, optarg);
230 filename = pg_strdup(optarg);
231 appendPQExpBufferStr(pgdumpopts, " -f ");
232 appendShellString(pgdumpopts, filename);
240 pghost = pg_strdup(optarg);
244 pgdb = pg_strdup(optarg);
248 appendPQExpBufferStr(pgdumpopts, " -o");
252 appendPQExpBufferStr(pgdumpopts, " -O");
256 pgport = pg_strdup(optarg);
264 appendPQExpBufferStr(pgdumpopts, " -s");
268 appendPQExpBufferStr(pgdumpopts, " -S ");
269 appendShellString(pgdumpopts, optarg);
273 tablespaces_only = true;
277 pguser = pg_strdup(optarg);
282 appendPQExpBufferStr(pgdumpopts, " -v");
286 prompt_password = TRI_NO;
287 appendPQExpBufferStr(pgdumpopts, " -w");
291 prompt_password = TRI_YES;
292 appendPQExpBufferStr(pgdumpopts, " -W");
297 appendPQExpBufferStr(pgdumpopts, " -x");
304 appendPQExpBufferStr(pgdumpopts, " --lock-wait-timeout ");
305 appendShellString(pgdumpopts, optarg);
309 use_role = pg_strdup(optarg);
310 appendPQExpBufferStr(pgdumpopts, " --role ");
311 appendShellString(pgdumpopts, use_role);
316 appendPQExpBufferStr(pgdumpopts, " --no-sync");
320 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
325 /* Complain if any arguments remain */
328 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
329 progname, argv[optind]);
330 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
335 /* Make sure the user hasn't specified a mix of globals-only options */
336 if (globals_only && roles_only)
338 fprintf(stderr, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"),
340 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
345 if (globals_only && tablespaces_only)
347 fprintf(stderr, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"),
349 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
354 if (if_exists && !output_clean)
356 fprintf(stderr, _("%s: option --if-exists requires option -c/--clean\n"),
361 if (roles_only && tablespaces_only)
363 fprintf(stderr, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"),
365 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
371 * If password values are not required in the dump, switch to using
372 * pg_roles which is equally useful, just more likely to have unrestricted
373 * access than pg_authid.
375 if (no_role_passwords)
376 sprintf(role_catalog, "%s", PG_ROLES);
378 sprintf(role_catalog, "%s", PG_AUTHID);
380 /* Add long options to the pg_dump argument list */
382 appendPQExpBufferStr(pgdumpopts, " --binary-upgrade");
384 appendPQExpBufferStr(pgdumpopts, " --column-inserts");
385 if (disable_dollar_quoting)
386 appendPQExpBufferStr(pgdumpopts, " --disable-dollar-quoting");
387 if (disable_triggers)
388 appendPQExpBufferStr(pgdumpopts, " --disable-triggers");
390 appendPQExpBufferStr(pgdumpopts, " --inserts");
392 appendPQExpBufferStr(pgdumpopts, " --no-tablespaces");
393 if (quote_all_identifiers)
394 appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers");
395 if (load_via_partition_root)
396 appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root");
398 appendPQExpBufferStr(pgdumpopts, " --use-set-session-authorization");
400 appendPQExpBufferStr(pgdumpopts, " --no-comments");
402 appendPQExpBufferStr(pgdumpopts, " --no-publications");
403 if (no_security_labels)
404 appendPQExpBufferStr(pgdumpopts, " --no-security-labels");
405 if (no_subscriptions)
406 appendPQExpBufferStr(pgdumpopts, " --no-subscriptions");
407 if (no_unlogged_table_data)
408 appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data");
411 * If there was a database specified on the command line, use that,
412 * otherwise try to connect to database "postgres", and failing that
413 * "template1". "postgres" is the preferred choice for 8.1 and later
414 * servers, but it usually will not exist on older ones.
418 conn = connectDatabase(pgdb, connstr, pghost, pgport, pguser,
419 prompt_password, false);
423 fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
430 conn = connectDatabase("postgres", connstr, pghost, pgport, pguser,
431 prompt_password, false);
433 conn = connectDatabase("template1", connstr, pghost, pgport, pguser,
434 prompt_password, true);
438 fprintf(stderr, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
439 "Please specify an alternative database.\n"),
441 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
448 * Open the output file if required, otherwise use stdout
452 OPF = fopen(filename, PG_BINARY_W);
455 fprintf(stderr, _("%s: could not open the output file \"%s\": %s\n"),
456 progname, filename, strerror(errno));
464 * Set the client encoding if requested.
468 if (PQsetClientEncoding(conn, dumpencoding) < 0)
470 fprintf(stderr, _("%s: invalid client encoding \"%s\" specified\n"),
471 progname, dumpencoding);
477 * Get the active encoding and the standard_conforming_strings setting, so
478 * we know how to escape strings.
480 encoding = PQclientEncoding(conn);
481 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
485 /* Set the role if requested */
486 if (use_role && server_version >= 80100)
488 PQExpBuffer query = createPQExpBuffer();
490 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
491 executeCommand(conn, query->data);
492 destroyPQExpBuffer(query);
495 /* Force quoting of all identifiers if requested. */
496 if (quote_all_identifiers && server_version >= 90100)
497 executeCommand(conn, "SET quote_all_identifiers = true");
499 fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
501 dumpTimestamp("Started on");
504 * We used to emit \connect postgres here, but that served no purpose
505 * other than to break things for installations without a postgres
506 * database. Everything we're restoring here is a global, so whichever
507 * database we're connected to at the moment is fine.
510 /* Restore will need to write to the target cluster */
511 fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
513 /* Replicate encoding and std_strings in output */
514 fprintf(OPF, "SET client_encoding = '%s';\n",
515 pg_encoding_to_char(encoding));
516 fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
517 if (strcmp(std_strings, "off") == 0)
518 fprintf(OPF, "SET escape_string_warning = off;\n");
524 * If asked to --clean, do that first. We can avoid detailed
525 * dependency analysis because databases never depend on each other,
526 * and tablespaces never depend on each other. Roles could have
527 * grants to each other, but DROP ROLE will clean those up silently.
531 if (!globals_only && !roles_only && !tablespaces_only)
534 if (!roles_only && !no_tablespaces)
535 dropTablespaces(conn);
537 if (!tablespaces_only)
542 * Now create objects as requested. Be careful that option logic here
543 * is the same as for drops above.
545 if (!tablespaces_only)
547 /* Dump roles (users) */
550 /* Dump role memberships --- need different method for pre-8.1 */
551 if (server_version >= 80100)
552 dumpRoleMembership(conn);
557 /* Dump tablespaces */
558 if (!roles_only && !no_tablespaces)
559 dumpTablespaces(conn);
562 if (!globals_only && !roles_only && !tablespaces_only)
568 dumpTimestamp("Completed on");
569 fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
575 /* sync the resulting file, errors are not fatal */
577 (void) fsync_fname(filename, false, progname);
587 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
588 printf(_("Usage:\n"));
589 printf(_(" %s [OPTION]...\n"), progname);
591 printf(_("\nGeneral options:\n"));
592 printf(_(" -f, --file=FILENAME output file name\n"));
593 printf(_(" -v, --verbose verbose mode\n"));
594 printf(_(" -V, --version output version information, then exit\n"));
595 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
596 printf(_(" -?, --help show this help, then exit\n"));
597 printf(_("\nOptions controlling the output content:\n"));
598 printf(_(" -a, --data-only dump only the data, not the schema\n"));
599 printf(_(" -c, --clean clean (drop) databases before recreating\n"));
600 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
601 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
602 printf(_(" -o, --oids include OIDs in dump\n"));
603 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
604 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
605 printf(_(" -s, --schema-only dump only the schema, no data\n"));
606 printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
607 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
608 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
609 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
610 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
611 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
612 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
613 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
614 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
615 printf(_(" --no-comments do not dump comments\n"));
616 printf(_(" --no-publications do not dump publications\n"));
617 printf(_(" --no-role-passwords do not dump passwords for roles\n"));
618 printf(_(" --no-security-labels do not dump security label assignments\n"));
619 printf(_(" --no-subscriptions do not dump subscriptions\n"));
620 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
621 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
622 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
623 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
624 printf(_(" --load-via-partition-root load partitions via the root table\n"));
625 printf(_(" --use-set-session-authorization\n"
626 " use SET SESSION AUTHORIZATION commands instead of\n"
627 " ALTER OWNER commands to set ownership\n"));
629 printf(_("\nConnection options:\n"));
630 printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
631 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
632 printf(_(" -l, --database=DBNAME alternative default database\n"));
633 printf(_(" -p, --port=PORT database server port number\n"));
634 printf(_(" -U, --username=NAME connect as specified database user\n"));
635 printf(_(" -w, --no-password never prompt for password\n"));
636 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
637 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
639 printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
641 printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
649 dropRoles(PGconn *conn)
651 PQExpBuffer buf = createPQExpBuffer();
656 if (server_version >= 90600)
657 printfPQExpBuffer(buf,
660 "WHERE rolname !~ '^pg_' "
661 "ORDER BY 1", role_catalog);
662 else if (server_version >= 80100)
663 printfPQExpBuffer(buf,
666 "ORDER BY 1", role_catalog);
668 printfPQExpBuffer(buf,
669 "SELECT usename as rolname "
672 "SELECT groname as rolname "
676 res = executeQuery(conn, buf->data);
678 i_rolname = PQfnumber(res, "rolname");
680 if (PQntuples(res) > 0)
681 fprintf(OPF, "--\n-- Drop roles\n--\n\n");
683 for (i = 0; i < PQntuples(res); i++)
685 const char *rolename;
687 rolename = PQgetvalue(res, i, i_rolname);
689 fprintf(OPF, "DROP ROLE %s%s;\n",
690 if_exists ? "IF EXISTS " : "",
695 destroyPQExpBuffer(buf);
697 fprintf(OPF, "\n\n");
704 dumpRoles(PGconn *conn)
706 PQExpBuffer buf = createPQExpBuffer();
724 /* note: rolconfig is dumped later */
725 if (server_version >= 90600)
726 printfPQExpBuffer(buf,
727 "SELECT oid, rolname, rolsuper, rolinherit, "
728 "rolcreaterole, rolcreatedb, "
729 "rolcanlogin, rolconnlimit, rolpassword, "
730 "rolvaliduntil, rolreplication, rolbypassrls, "
731 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
732 "rolname = current_user AS is_current_user "
734 "WHERE rolname !~ '^pg_' "
735 "ORDER BY 2", role_catalog, role_catalog);
736 else if (server_version >= 90500)
737 printfPQExpBuffer(buf,
738 "SELECT oid, rolname, rolsuper, rolinherit, "
739 "rolcreaterole, rolcreatedb, "
740 "rolcanlogin, rolconnlimit, rolpassword, "
741 "rolvaliduntil, rolreplication, rolbypassrls, "
742 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
743 "rolname = current_user AS is_current_user "
745 "ORDER BY 2", role_catalog, role_catalog);
746 else if (server_version >= 90100)
747 printfPQExpBuffer(buf,
748 "SELECT oid, rolname, rolsuper, rolinherit, "
749 "rolcreaterole, rolcreatedb, "
750 "rolcanlogin, rolconnlimit, rolpassword, "
751 "rolvaliduntil, rolreplication, "
752 "false as rolbypassrls, "
753 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
754 "rolname = current_user AS is_current_user "
756 "ORDER BY 2", role_catalog, role_catalog);
757 else if (server_version >= 80200)
758 printfPQExpBuffer(buf,
759 "SELECT oid, rolname, rolsuper, rolinherit, "
760 "rolcreaterole, rolcreatedb, "
761 "rolcanlogin, rolconnlimit, rolpassword, "
762 "rolvaliduntil, false as rolreplication, "
763 "false as rolbypassrls, "
764 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
765 "rolname = current_user AS is_current_user "
767 "ORDER BY 2", role_catalog, role_catalog);
768 else if (server_version >= 80100)
769 printfPQExpBuffer(buf,
770 "SELECT oid, rolname, rolsuper, rolinherit, "
771 "rolcreaterole, rolcreatedb, "
772 "rolcanlogin, rolconnlimit, rolpassword, "
773 "rolvaliduntil, false as rolreplication, "
774 "false as rolbypassrls, "
775 "null as rolcomment, "
776 "rolname = current_user AS is_current_user "
778 "ORDER BY 2", role_catalog);
780 printfPQExpBuffer(buf,
781 "SELECT 0 as oid, usename as rolname, "
782 "usesuper as rolsuper, "
783 "true as rolinherit, "
784 "usesuper as rolcreaterole, "
785 "usecreatedb as rolcreatedb, "
786 "true as rolcanlogin, "
787 "-1 as rolconnlimit, "
788 "passwd as rolpassword, "
789 "valuntil as rolvaliduntil, "
790 "false as rolreplication, "
791 "false as rolbypassrls, "
792 "null as rolcomment, "
793 "usename = current_user AS is_current_user "
796 "SELECT 0 as oid, groname as rolname, "
797 "false as rolsuper, "
798 "true as rolinherit, "
799 "false as rolcreaterole, "
800 "false as rolcreatedb, "
801 "false as rolcanlogin, "
802 "-1 as rolconnlimit, "
803 "null::text as rolpassword, "
804 "null::abstime as rolvaliduntil, "
805 "false as rolreplication, "
806 "false as rolbypassrls, "
807 "null as rolcomment, "
808 "false AS is_current_user "
810 "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
811 " WHERE usename = groname) "
814 res = executeQuery(conn, buf->data);
816 i_oid = PQfnumber(res, "oid");
817 i_rolname = PQfnumber(res, "rolname");
818 i_rolsuper = PQfnumber(res, "rolsuper");
819 i_rolinherit = PQfnumber(res, "rolinherit");
820 i_rolcreaterole = PQfnumber(res, "rolcreaterole");
821 i_rolcreatedb = PQfnumber(res, "rolcreatedb");
822 i_rolcanlogin = PQfnumber(res, "rolcanlogin");
823 i_rolconnlimit = PQfnumber(res, "rolconnlimit");
824 i_rolpassword = PQfnumber(res, "rolpassword");
825 i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
826 i_rolreplication = PQfnumber(res, "rolreplication");
827 i_rolbypassrls = PQfnumber(res, "rolbypassrls");
828 i_rolcomment = PQfnumber(res, "rolcomment");
829 i_is_current_user = PQfnumber(res, "is_current_user");
831 if (PQntuples(res) > 0)
832 fprintf(OPF, "--\n-- Roles\n--\n\n");
834 for (i = 0; i < PQntuples(res); i++)
836 const char *rolename;
839 auth_oid = atooid(PQgetvalue(res, i, i_oid));
840 rolename = PQgetvalue(res, i, i_rolname);
842 if (strncmp(rolename, "pg_", 3) == 0)
844 fprintf(stderr, _("%s: role name starting with \"pg_\" skipped (%s)\n"),
849 resetPQExpBuffer(buf);
853 appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
854 appendPQExpBuffer(buf,
855 "SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
860 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
861 * will acquire the right properties even if it already exists (ie, it
862 * won't hurt for the CREATE to fail). This is particularly important
863 * for the role we are connected as, since even with --clean we will
864 * have failed to drop it. binary_upgrade cannot generate any errors,
865 * so we assume the current role is already created.
867 if (!binary_upgrade ||
868 strcmp(PQgetvalue(res, i, i_is_current_user), "f") == 0)
869 appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
870 appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
872 if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
873 appendPQExpBufferStr(buf, " SUPERUSER");
875 appendPQExpBufferStr(buf, " NOSUPERUSER");
877 if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
878 appendPQExpBufferStr(buf, " INHERIT");
880 appendPQExpBufferStr(buf, " NOINHERIT");
882 if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
883 appendPQExpBufferStr(buf, " CREATEROLE");
885 appendPQExpBufferStr(buf, " NOCREATEROLE");
887 if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
888 appendPQExpBufferStr(buf, " CREATEDB");
890 appendPQExpBufferStr(buf, " NOCREATEDB");
892 if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
893 appendPQExpBufferStr(buf, " LOGIN");
895 appendPQExpBufferStr(buf, " NOLOGIN");
897 if (strcmp(PQgetvalue(res, i, i_rolreplication), "t") == 0)
898 appendPQExpBufferStr(buf, " REPLICATION");
900 appendPQExpBufferStr(buf, " NOREPLICATION");
902 if (strcmp(PQgetvalue(res, i, i_rolbypassrls), "t") == 0)
903 appendPQExpBufferStr(buf, " BYPASSRLS");
905 appendPQExpBufferStr(buf, " NOBYPASSRLS");
907 if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
908 appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
909 PQgetvalue(res, i, i_rolconnlimit));
912 if (!PQgetisnull(res, i, i_rolpassword) && !no_role_passwords)
914 appendPQExpBufferStr(buf, " PASSWORD ");
915 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolpassword), conn);
918 if (!PQgetisnull(res, i, i_rolvaliduntil))
919 appendPQExpBuffer(buf, " VALID UNTIL '%s'",
920 PQgetvalue(res, i, i_rolvaliduntil));
922 appendPQExpBufferStr(buf, ";\n");
924 if (!no_comments && !PQgetisnull(res, i, i_rolcomment))
926 appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
927 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolcomment), conn);
928 appendPQExpBufferStr(buf, ";\n");
931 if (!no_security_labels && server_version >= 90200)
932 buildShSecLabels(conn, "pg_authid", auth_oid,
936 fprintf(OPF, "%s", buf->data);
940 * Dump configuration settings for roles after all roles have been dumped.
941 * We do it this way because config settings for roles could mention the
942 * names of other roles.
944 for (i = 0; i < PQntuples(res); i++)
945 dumpUserConfig(conn, PQgetvalue(res, i, i_rolname));
949 fprintf(OPF, "\n\n");
951 destroyPQExpBuffer(buf);
956 * Dump role memberships. This code is used for 8.1 and later servers.
958 * Note: we expect dumpRoles already created all the roles, but there is
962 dumpRoleMembership(PGconn *conn)
964 PQExpBuffer buf = createPQExpBuffer();
968 printfPQExpBuffer(buf, "SELECT ur.rolname AS roleid, "
969 "um.rolname AS member, "
971 "ug.rolname AS grantor "
972 "FROM pg_auth_members a "
973 "LEFT JOIN %s ur on ur.oid = a.roleid "
974 "LEFT JOIN %s um on um.oid = a.member "
975 "LEFT JOIN %s ug on ug.oid = a.grantor "
976 "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
977 "ORDER BY 1,2,3", role_catalog, role_catalog, role_catalog);
978 res = executeQuery(conn, buf->data);
980 if (PQntuples(res) > 0)
981 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
983 for (i = 0; i < PQntuples(res); i++)
985 char *roleid = PQgetvalue(res, i, 0);
986 char *member = PQgetvalue(res, i, 1);
987 char *option = PQgetvalue(res, i, 2);
989 fprintf(OPF, "GRANT %s", fmtId(roleid));
990 fprintf(OPF, " TO %s", fmtId(member));
992 fprintf(OPF, " WITH ADMIN OPTION");
995 * We don't track the grantor very carefully in the backend, so cope
996 * with the possibility that it has been dropped.
998 if (!PQgetisnull(res, i, 3))
1000 char *grantor = PQgetvalue(res, i, 3);
1002 fprintf(OPF, " GRANTED BY %s", fmtId(grantor));
1004 fprintf(OPF, ";\n");
1008 destroyPQExpBuffer(buf);
1010 fprintf(OPF, "\n\n");
1014 * Dump group memberships from a pre-8.1 server. It's annoying that we
1015 * can't share any useful amount of code with the post-8.1 case, but
1016 * the catalog representations are too different.
1018 * Note: we expect dumpRoles already created all the roles, but there is
1019 * no membership yet.
1022 dumpGroups(PGconn *conn)
1024 PQExpBuffer buf = createPQExpBuffer();
1028 res = executeQuery(conn,
1029 "SELECT groname, grolist FROM pg_group ORDER BY 1");
1031 if (PQntuples(res) > 0)
1032 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
1034 for (i = 0; i < PQntuples(res); i++)
1036 char *groname = PQgetvalue(res, i, 0);
1037 char *grolist = PQgetvalue(res, i, 1);
1042 * Array representation is {1,2,3} ... convert to (1,2,3)
1044 if (strlen(grolist) < 3)
1047 grolist = pg_strdup(grolist);
1049 grolist[strlen(grolist) - 1] = ')';
1050 printfPQExpBuffer(buf,
1051 "SELECT usename FROM pg_shadow "
1052 "WHERE usesysid IN %s ORDER BY 1",
1056 res2 = executeQuery(conn, buf->data);
1058 for (j = 0; j < PQntuples(res2); j++)
1060 char *usename = PQgetvalue(res2, j, 0);
1063 * Don't try to grant a role to itself; can happen if old
1064 * installation has identically named user and group.
1066 if (strcmp(groname, usename) == 0)
1069 fprintf(OPF, "GRANT %s", fmtId(groname));
1070 fprintf(OPF, " TO %s;\n", fmtId(usename));
1077 destroyPQExpBuffer(buf);
1079 fprintf(OPF, "\n\n");
1087 dropTablespaces(PGconn *conn)
1093 * Get all tablespaces except built-in ones (which we assume are named
1096 res = executeQuery(conn, "SELECT spcname "
1097 "FROM pg_catalog.pg_tablespace "
1098 "WHERE spcname !~ '^pg_' "
1101 if (PQntuples(res) > 0)
1102 fprintf(OPF, "--\n-- Drop tablespaces\n--\n\n");
1104 for (i = 0; i < PQntuples(res); i++)
1106 char *spcname = PQgetvalue(res, i, 0);
1108 fprintf(OPF, "DROP TABLESPACE %s%s;\n",
1109 if_exists ? "IF EXISTS " : "",
1115 fprintf(OPF, "\n\n");
1122 dumpTablespaces(PGconn *conn)
1128 * Get all tablespaces except built-in ones (which we assume are named
1131 * For the tablespace ACLs, as of 9.6, we extract both the positive (as
1132 * spcacl) and negative (as rspcacl) ACLs, relative to the default ACL for
1133 * tablespaces, which are then passed to buildACLCommands() below.
1135 * See buildACLQueries() and buildACLCommands().
1137 * Note that we do not support initial privileges (pg_init_privs) on
1140 if (server_version >= 90600)
1141 res = executeQuery(conn, "SELECT oid, spcname, "
1142 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1143 "pg_catalog.pg_tablespace_location(oid), "
1144 "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner))) AS acl "
1145 "EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner))) as foo)"
1147 "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner)) AS acl "
1148 "EXCEPT SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner)))) as foo)"
1150 "array_to_string(spcoptions, ', '),"
1151 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1152 "FROM pg_catalog.pg_tablespace "
1153 "WHERE spcname !~ '^pg_' "
1155 else if (server_version >= 90200)
1156 res = executeQuery(conn, "SELECT oid, spcname, "
1157 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1158 "pg_catalog.pg_tablespace_location(oid), "
1159 "spcacl, '' as rspcacl, "
1160 "array_to_string(spcoptions, ', '),"
1161 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1162 "FROM pg_catalog.pg_tablespace "
1163 "WHERE spcname !~ '^pg_' "
1165 else if (server_version >= 90000)
1166 res = executeQuery(conn, "SELECT oid, spcname, "
1167 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1168 "spclocation, spcacl, '' as rspcacl, "
1169 "array_to_string(spcoptions, ', '),"
1170 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1171 "FROM pg_catalog.pg_tablespace "
1172 "WHERE spcname !~ '^pg_' "
1174 else if (server_version >= 80200)
1175 res = executeQuery(conn, "SELECT oid, spcname, "
1176 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1177 "spclocation, spcacl, '' as rspcacl, null, "
1178 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1179 "FROM pg_catalog.pg_tablespace "
1180 "WHERE spcname !~ '^pg_' "
1183 res = executeQuery(conn, "SELECT oid, spcname, "
1184 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1185 "spclocation, spcacl, '' as rspcacl, "
1187 "FROM pg_catalog.pg_tablespace "
1188 "WHERE spcname !~ '^pg_' "
1191 if (PQntuples(res) > 0)
1192 fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
1194 for (i = 0; i < PQntuples(res); i++)
1196 PQExpBuffer buf = createPQExpBuffer();
1197 Oid spcoid = atooid(PQgetvalue(res, i, 0));
1198 char *spcname = PQgetvalue(res, i, 1);
1199 char *spcowner = PQgetvalue(res, i, 2);
1200 char *spclocation = PQgetvalue(res, i, 3);
1201 char *spcacl = PQgetvalue(res, i, 4);
1202 char *rspcacl = PQgetvalue(res, i, 5);
1203 char *spcoptions = PQgetvalue(res, i, 6);
1204 char *spccomment = PQgetvalue(res, i, 7);
1207 /* needed for buildACLCommands() */
1208 fspcname = pg_strdup(fmtId(spcname));
1210 appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
1211 appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
1213 appendPQExpBufferStr(buf, " LOCATION ");
1214 appendStringLiteralConn(buf, spclocation, conn);
1215 appendPQExpBufferStr(buf, ";\n");
1217 if (spcoptions && spcoptions[0] != '\0')
1218 appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
1219 fspcname, spcoptions);
1222 !buildACLCommands(fspcname, NULL, NULL, "TABLESPACE",
1224 spcowner, "", server_version, buf))
1226 fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
1227 progname, spcacl, spcname);
1232 if (!no_comments && spccomment && spccomment[0] != '\0')
1234 appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
1235 appendStringLiteralConn(buf, spccomment, conn);
1236 appendPQExpBufferStr(buf, ";\n");
1239 if (!no_security_labels && server_version >= 90200)
1240 buildShSecLabels(conn, "pg_tablespace", spcoid,
1241 "TABLESPACE", spcname,
1244 fprintf(OPF, "%s", buf->data);
1247 destroyPQExpBuffer(buf);
1251 fprintf(OPF, "\n\n");
1256 * Dump commands to drop each database.
1259 dropDBs(PGconn *conn)
1265 * Skip databases marked not datallowconn, since we'd be unable to connect
1266 * to them anyway. This must agree with dumpDatabases().
1268 res = executeQuery(conn,
1270 "FROM pg_database d "
1271 "WHERE datallowconn "
1272 "ORDER BY datname");
1274 if (PQntuples(res) > 0)
1275 fprintf(OPF, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
1277 for (i = 0; i < PQntuples(res); i++)
1279 char *dbname = PQgetvalue(res, i, 0);
1282 * Skip "postgres" and "template1"; dumpDatabases() will deal with
1283 * them specially. Also, be sure to skip "template0", even if for
1284 * some reason it's not marked !datallowconn.
1286 if (strcmp(dbname, "template1") != 0 &&
1287 strcmp(dbname, "template0") != 0 &&
1288 strcmp(dbname, "postgres") != 0)
1290 fprintf(OPF, "DROP DATABASE %s%s;\n",
1291 if_exists ? "IF EXISTS " : "",
1298 fprintf(OPF, "\n\n");
1303 * Dump user-specific configuration
1306 dumpUserConfig(PGconn *conn, const char *username)
1308 PQExpBuffer buf = createPQExpBuffer();
1315 if (server_version >= 90000)
1316 printfPQExpBuffer(buf, "SELECT setconfig[%d] FROM pg_db_role_setting WHERE "
1317 "setdatabase = 0 AND setrole = "
1318 "(SELECT oid FROM %s WHERE rolname = ", count, role_catalog);
1319 else if (server_version >= 80100)
1320 printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM %s WHERE rolname = ", count, role_catalog);
1322 printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
1323 appendStringLiteralConn(buf, username, conn);
1324 if (server_version >= 90000)
1325 appendPQExpBufferChar(buf, ')');
1327 res = executeQuery(conn, buf->data);
1328 if (PQntuples(res) == 1 &&
1329 !PQgetisnull(res, 0, 0))
1331 resetPQExpBuffer(buf);
1332 makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
1333 "ROLE", username, NULL, NULL,
1335 fprintf(OPF, "%s", buf->data);
1346 destroyPQExpBuffer(buf);
1351 * Dump contents of databases.
1354 dumpDatabases(PGconn *conn)
1360 * Skip databases marked not datallowconn, since we'd be unable to connect
1361 * to them anyway. This must agree with dropDBs().
1363 * We arrange for template1 to be processed first, then we process other
1364 * DBs in alphabetical order. If we just did them all alphabetically, we
1365 * might find ourselves trying to drop the "postgres" database while still
1366 * connected to it. This makes trying to run the restore script while
1367 * connected to "template1" a bad idea, but there's no fixed order that
1368 * doesn't have some failure mode with --clean.
1370 res = executeQuery(conn,
1372 "FROM pg_database d "
1373 "WHERE datallowconn "
1374 "ORDER BY (datname <> 'template1'), datname");
1376 for (i = 0; i < PQntuples(res); i++)
1378 char *dbname = PQgetvalue(res, i, 0);
1379 const char *create_opts;
1382 /* Skip template0, even if it's not marked !datallowconn. */
1383 if (strcmp(dbname, "template0") == 0)
1387 fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
1390 * We assume that "template1" and "postgres" already exist in the
1391 * target installation. dropDBs() won't have removed them, for fear
1392 * of removing the DB the restore script is initially connected to. If
1393 * --clean was specified, tell pg_dump to drop and recreate them;
1394 * otherwise we'll merely restore their contents. Other databases
1395 * should simply be created.
1397 if (strcmp(dbname, "template1") == 0 || strcmp(dbname, "postgres") == 0)
1400 create_opts = "--clean --create";
1404 /* Since pg_dump won't emit a \connect command, we must */
1405 fprintf(OPF, "\\connect %s\n\n", dbname);
1409 create_opts = "--create";
1414 ret = runPgDump(dbname, create_opts);
1417 fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
1423 OPF = fopen(filename, PG_BINARY_A);
1426 fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"),
1427 progname, filename, strerror(errno));
1440 * Run pg_dump on dbname, with specified options.
1443 runPgDump(const char *dbname, const char *create_opts)
1445 PQExpBuffer connstrbuf = createPQExpBuffer();
1446 PQExpBuffer cmd = createPQExpBuffer();
1449 appendPQExpBuffer(cmd, "\"%s\" %s %s", pg_dump_bin,
1450 pgdumpopts->data, create_opts);
1453 * If we have a filename, use the undocumented plain-append pg_dump
1457 appendPQExpBufferStr(cmd, " -Fa ");
1459 appendPQExpBufferStr(cmd, " -Fp ");
1462 * Append the database name to the already-constructed stem of connection
1465 appendPQExpBuffer(connstrbuf, "%s dbname=", connstr);
1466 appendConnStrVal(connstrbuf, dbname);
1468 appendShellString(cmd, connstrbuf->data);
1471 fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);
1476 ret = system(cmd->data);
1478 destroyPQExpBuffer(cmd);
1479 destroyPQExpBuffer(connstrbuf);
1487 * Build SECURITY LABEL command(s) for a shared object
1489 * The caller has to provide object type and identity in two separate formats:
1490 * catalog_name (e.g., "pg_database") and object OID, as well as
1491 * type name (e.g., "DATABASE") and object name (not pre-quoted).
1493 * The command(s) are appended to "buffer".
1496 buildShSecLabels(PGconn *conn, const char *catalog_name, Oid objectId,
1497 const char *objtype, const char *objname,
1500 PQExpBuffer sql = createPQExpBuffer();
1503 buildShSecLabelQuery(conn, catalog_name, objectId, sql);
1504 res = executeQuery(conn, sql->data);
1505 emitShSecLabels(conn, res, buffer, objtype, objname);
1508 destroyPQExpBuffer(sql);
1512 * Make a database connection with the given parameters. An
1513 * interactive password prompt is automatically issued if required.
1515 * If fail_on_error is false, we return NULL without printing any message
1516 * on failure, but preserve any prompted password for the next try.
1518 * On success, the global variable 'connstr' is set to a connection string
1519 * containing the options used.
1522 connectDatabase(const char *dbname, const char *connection_string,
1523 const char *pghost, const char *pgport, const char *pguser,
1524 trivalue prompt_password, bool fail_on_error)
1528 const char *remoteversion_str;
1530 const char **keywords = NULL;
1531 const char **values = NULL;
1532 PQconninfoOption *conn_opts = NULL;
1533 static bool have_password = false;
1534 static char password[100];
1536 if (prompt_password == TRI_YES && !have_password)
1538 simple_prompt("Password: ", password, sizeof(password), false);
1539 have_password = true;
1543 * Start the connection. Loop until we have a password if requested by
1549 PQconninfoOption *conn_opt;
1550 char *err_msg = NULL;
1558 PQconninfoFree(conn_opts);
1561 * Merge the connection info inputs given in form of connection string
1562 * and other options. Explicitly discard any dbname value in the
1563 * connection string; otherwise, PQconnectdbParams() would interpret
1564 * that value as being itself a connection string.
1566 if (connection_string)
1568 conn_opts = PQconninfoParse(connection_string, &err_msg);
1569 if (conn_opts == NULL)
1571 fprintf(stderr, "%s: %s", progname, err_msg);
1575 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1577 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1578 strcmp(conn_opt->keyword, "dbname") != 0)
1582 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1583 values = pg_malloc0((argcount + 1) * sizeof(*values));
1585 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
1587 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
1588 strcmp(conn_opt->keyword, "dbname") != 0)
1590 keywords[i] = conn_opt->keyword;
1591 values[i] = conn_opt->val;
1598 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
1599 values = pg_malloc0((argcount + 1) * sizeof(*values));
1604 keywords[i] = "host";
1610 keywords[i] = "port";
1616 keywords[i] = "user";
1622 keywords[i] = "password";
1623 values[i] = password;
1628 keywords[i] = "dbname";
1632 keywords[i] = "fallback_application_name";
1633 values[i] = progname;
1637 conn = PQconnectdbParams(keywords, values, true);
1641 fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
1646 if (PQstatus(conn) == CONNECTION_BAD &&
1647 PQconnectionNeedsPassword(conn) &&
1649 prompt_password != TRI_NO)
1652 simple_prompt("Password: ", password, sizeof(password), false);
1653 have_password = true;
1658 /* check to see that the backend connection was successfully made */
1659 if (PQstatus(conn) == CONNECTION_BAD)
1664 _("%s: could not connect to database \"%s\": %s\n"),
1665 progname, dbname, PQerrorMessage(conn));
1674 PQconninfoFree(conn_opts);
1681 * Ok, connected successfully. Remember the options used, in the form of a
1682 * connection string.
1684 connstr = constructConnStr(keywords, values);
1688 PQconninfoFree(conn_opts);
1691 remoteversion_str = PQparameterStatus(conn, "server_version");
1692 if (!remoteversion_str)
1694 fprintf(stderr, _("%s: could not get server version\n"), progname);
1697 server_version = PQserverVersion(conn);
1698 if (server_version == 0)
1700 fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
1701 progname, remoteversion_str);
1705 my_version = PG_VERSION_NUM;
1708 * We allow the server to be back to 8.0, and up to any minor release of
1709 * our own major version. (See also version check in pg_dump.c.)
1711 if (my_version != server_version
1712 && (server_version < 80000 ||
1713 (server_version / 100) > (my_version / 100)))
1715 fprintf(stderr, _("server version: %s; %s version: %s\n"),
1716 remoteversion_str, progname, PG_VERSION);
1717 fprintf(stderr, _("aborting because of server version mismatch\n"));
1721 PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL));
1727 * Construct a connection string from the given keyword/value pairs. It is
1728 * used to pass the connection options to the pg_dump subprocess.
1730 * The following parameters are excluded:
1731 * dbname - varies in each pg_dump invocation
1732 * password - it's not secure to pass a password on the command line
1733 * fallback_application_name - we'll let pg_dump set it
1737 constructConnStr(const char **keywords, const char **values)
1739 PQExpBuffer buf = createPQExpBuffer();
1742 bool firstkeyword = true;
1744 /* Construct a new connection string in key='value' format. */
1745 for (i = 0; keywords[i] != NULL; i++)
1747 if (strcmp(keywords[i], "dbname") == 0 ||
1748 strcmp(keywords[i], "password") == 0 ||
1749 strcmp(keywords[i], "fallback_application_name") == 0)
1753 appendPQExpBufferChar(buf, ' ');
1754 firstkeyword = false;
1755 appendPQExpBuffer(buf, "%s=", keywords[i]);
1756 appendConnStrVal(buf, values[i]);
1759 connstr = pg_strdup(buf->data);
1760 destroyPQExpBuffer(buf);
1765 * Run a query, return the results, exit program on failure.
1768 executeQuery(PGconn *conn, const char *query)
1773 fprintf(stderr, _("%s: executing %s\n"), progname, query);
1775 res = PQexec(conn, query);
1777 PQresultStatus(res) != PGRES_TUPLES_OK)
1779 fprintf(stderr, _("%s: query failed: %s"),
1780 progname, PQerrorMessage(conn));
1781 fprintf(stderr, _("%s: query was: %s\n"),
1791 * As above for a SQL command (which returns nothing).
1794 executeCommand(PGconn *conn, const char *query)
1799 fprintf(stderr, _("%s: executing %s\n"), progname, query);
1801 res = PQexec(conn, query);
1803 PQresultStatus(res) != PGRES_COMMAND_OK)
1805 fprintf(stderr, _("%s: query failed: %s"),
1806 progname, PQerrorMessage(conn));
1807 fprintf(stderr, _("%s: query was: %s\n"),
1821 dumpTimestamp(const char *msg)
1824 time_t now = time(NULL);
1826 if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0)
1827 fprintf(OPF, "-- %s %s\n\n", msg, buf);