1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
9 * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.99 2007/12/09 19:01:40 tgl Exp $
11 *-------------------------------------------------------------------------
14 #include "postgres_fe.h"
23 #include "getopt_long.h"
25 #ifndef HAVE_INT_OPTRESET
29 #include "dumputils.h"
32 /* version string we expect back from pg_dump */
33 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
36 static const char *progname;
38 static void help(void);
40 static void dumpRoles(PGconn *conn);
41 static void dumpRoleMembership(PGconn *conn);
42 static void dumpGroups(PGconn *conn);
43 static void dumpTablespaces(PGconn *conn);
44 static void dumpCreateDB(PGconn *conn);
45 static void dumpDatabaseConfig(PGconn *conn, const char *dbname);
46 static void dumpUserConfig(PGconn *conn, const char *username);
47 static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
48 const char *type, const char *name);
49 static void dumpDatabases(PGconn *conn);
50 static void dumpTimestamp(char *msg);
52 static int runPgDump(const char *dbname);
53 static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
54 const char *pguser, bool require_password, bool fail_on_error);
55 static PGresult *executeQuery(PGconn *conn, const char *query);
56 static void executeCommand(PGconn *conn, const char *query);
58 static char pg_dump_bin[MAXPGPATH];
59 static PQExpBuffer pgdumpopts;
60 static bool output_clean = false;
61 static bool skip_acls = false;
62 static bool verbose = false;
63 static bool ignoreVersion = false;
65 static int disable_dollar_quoting = 0;
66 static int disable_triggers = 0;
67 static int use_setsessauth = 0;
68 static int server_version;
71 static char *filename = NULL;
74 main(int argc, char *argv[])
80 bool force_password = false;
81 bool data_only = false;
82 bool globals_only = false;
83 bool roles_only = false;
84 bool tablespaces_only = false;
85 bool schema_only = false;
88 const char *std_strings;
92 static struct option long_options[] = {
93 {"data-only", no_argument, NULL, 'a'},
94 {"clean", no_argument, NULL, 'c'},
95 {"inserts", no_argument, NULL, 'd'},
96 {"attribute-inserts", no_argument, NULL, 'D'},
97 {"column-inserts", no_argument, NULL, 'D'},
98 {"file", required_argument, NULL, 'f'},
99 {"globals-only", no_argument, NULL, 'g'},
100 {"host", required_argument, NULL, 'h'},
101 {"ignore-version", no_argument, NULL, 'i'},
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 {"password", no_argument, NULL, 'W'},
113 {"no-privileges", no_argument, NULL, 'x'},
114 {"no-acl", no_argument, NULL, 'x'},
117 * the following options don't have an equivalent short option letter
119 {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
120 {"disable-triggers", no_argument, &disable_triggers, 1},
121 {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
128 set_pglocale_pgservice(argv[0], "pg_dump");
130 progname = get_progname(argv[0]);
134 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
139 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
141 puts("pg_dumpall (PostgreSQL) " PG_VERSION);
146 if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
149 char full_path[MAXPGPATH];
151 if (find_my_exec(argv[0], full_path) < 0)
152 strlcpy(full_path, progname, sizeof(full_path));
156 _("The program \"pg_dump\" is needed by %s "
157 "but was not found in the\n"
158 "same directory as \"%s\".\n"
159 "Check your installation.\n"),
160 progname, full_path);
163 _("The program \"pg_dump\" was found by \"%s\"\n"
164 "but was not the same version as %s.\n"
165 "Check your installation.\n"),
166 full_path, progname);
170 pgdumpopts = createPQExpBuffer();
172 while ((c = getopt_long(argc, argv, "acdDf:gh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1)
178 appendPQExpBuffer(pgdumpopts, " -a");
187 appendPQExpBuffer(pgdumpopts, " -%c", c);
193 appendPQExpBuffer(pgdumpopts, " -f '%s'", filename);
195 appendPQExpBuffer(pgdumpopts, " -f \"%s\"", filename);
207 appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost);
209 appendPQExpBuffer(pgdumpopts, " -h \"%s\"", pghost);
215 ignoreVersion = true;
216 appendPQExpBuffer(pgdumpopts, " -i");
224 appendPQExpBuffer(pgdumpopts, " -o");
228 appendPQExpBuffer(pgdumpopts, " -O");
234 appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport);
236 appendPQExpBuffer(pgdumpopts, " -p \"%s\"", pgport);
246 appendPQExpBuffer(pgdumpopts, " -s");
251 appendPQExpBuffer(pgdumpopts, " -S '%s'", optarg);
253 appendPQExpBuffer(pgdumpopts, " -S \"%s\"", optarg);
258 tablespaces_only = true;
264 appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser);
266 appendPQExpBuffer(pgdumpopts, " -U \"%s\"", pguser);
272 appendPQExpBuffer(pgdumpopts, " -v");
276 force_password = true;
277 appendPQExpBuffer(pgdumpopts, " -W");
282 appendPQExpBuffer(pgdumpopts, " -x");
286 /* -X is a deprecated alternative to long options */
287 if (strcmp(optarg, "disable-dollar-quoting") == 0)
288 appendPQExpBuffer(pgdumpopts, " --disable-dollar-quoting");
289 else if (strcmp(optarg, "disable-triggers") == 0)
290 appendPQExpBuffer(pgdumpopts, " --disable-triggers");
291 else if (strcmp(optarg, "use-set-session-authorization") == 0)
292 /* no-op, still allowed for compatibility */ ;
296 _("%s: invalid -X option -- %s\n"),
298 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
307 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
312 /* Add long options to the pg_dump argument list */
313 if (disable_dollar_quoting)
314 appendPQExpBuffer(pgdumpopts, " --disable-dollar-quoting");
315 if (disable_triggers)
316 appendPQExpBuffer(pgdumpopts, " --disable-triggers");
318 appendPQExpBuffer(pgdumpopts, " --use-set-session-authorization");
322 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
323 progname, argv[optind]);
324 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
329 /* Make sure the user hasn't specified a mix of globals-only options */
330 if (globals_only && roles_only)
332 fprintf(stderr, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"),
334 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
339 if (globals_only && tablespaces_only)
341 fprintf(stderr, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"),
343 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
348 if (roles_only && tablespaces_only)
350 fprintf(stderr, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"),
352 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
358 * If there was a database specified on the command line, use that,
359 * otherwise try to connect to database "postgres", and failing that
360 * "template1". "postgres" is the preferred choice for 8.1 and later
361 * servers, but it usually will not exist on older ones.
365 conn = connectDatabase(pgdb, pghost, pgport, pguser,
366 force_password, false);
370 fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
377 conn = connectDatabase("postgres", pghost, pgport, pguser,
378 force_password, false);
380 conn = connectDatabase("template1", pghost, pgport, pguser,
381 force_password, true);
385 fprintf(stderr, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
386 "Please specify an alternative database.\n"),
388 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
395 * Open the output file if required, otherwise use stdout
399 OPF = fopen(filename, PG_BINARY_W);
402 fprintf(stderr, _("%s: could not open the output file \"%s\": %s\n"),
403 progname, filename, strerror(errno));
411 * Get the active encoding and the standard_conforming_strings setting, so
412 * we know how to escape strings.
414 encoding = PQclientEncoding(conn);
415 std_strings = PQparameterStatus(conn, "standard_conforming_strings");
419 fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
421 dumpTimestamp("Started on");
423 fprintf(OPF, "\\connect postgres\n\n");
427 /* Replicate encoding and std_strings in output */
428 fprintf(OPF, "SET client_encoding = '%s';\n",
429 pg_encoding_to_char(encoding));
430 fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
431 if (strcmp(std_strings, "off") == 0)
432 fprintf(OPF, "SET escape_string_warning = 'off';\n");
435 if (!tablespaces_only)
437 /* Dump roles (users) */
440 /* Dump role memberships --- need different method for pre-8.1 */
441 if (server_version >= 80100)
442 dumpRoleMembership(conn);
449 /* Dump tablespaces */
450 if (server_version >= 80000)
451 dumpTablespaces(conn);
454 /* Dump CREATE DATABASE commands */
455 if (!globals_only && !roles_only && !tablespaces_only)
459 if (!globals_only && !roles_only && !tablespaces_only)
465 dumpTimestamp("Completed on");
466 fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
479 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname);
480 printf(_("Usage:\n"));
481 printf(_(" %s [OPTION]...\n"), progname);
483 printf(_("\nGeneral options:\n"));
484 printf(_(" -f, --file=FILENAME output file name\n"));
485 printf(_(" -i, --ignore-version proceed even when server version mismatches\n"
486 " pg_dumpall version\n"));
487 printf(_(" --help show this help, then exit\n"));
488 printf(_(" --version output version information, then exit\n"));
489 printf(_("\nOptions controlling the output content:\n"));
490 printf(_(" -a, --data-only dump only the data, not the schema\n"));
491 printf(_(" -c, --clean clean (drop) databases prior to create\n"));
492 printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
493 printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
494 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
495 printf(_(" -o, --oids include OIDs in dump\n"));
496 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
497 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
498 printf(_(" -s, --schema-only dump only the schema, no data\n"));
499 printf(_(" -S, --superuser=NAME specify the superuser user name to use in the dump\n"));
500 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
501 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
502 printf(_(" --disable-dollar-quoting\n"
503 " disable dollar quoting, use SQL standard quoting\n"));
504 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
505 printf(_(" --use-set-session-authorization\n"
506 " use SESSION AUTHORIZATION commands instead of\n"
507 " OWNER TO commands\n"));
509 printf(_("\nConnection options:\n"));
510 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
511 printf(_(" -l, --database=DBNAME specify an alternative default database\n"));
512 printf(_(" -p, --port=PORT database server port number\n"));
513 printf(_(" -U, --username=NAME connect as specified database user\n"));
514 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
516 printf(_("\nThe SQL script will be written to the standard output.\n\n"));
517 printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
526 dumpRoles(PGconn *conn)
528 PQExpBuffer buf = createPQExpBuffer();
543 /* note: rolconfig is dumped later */
544 if (server_version >= 80200)
545 printfPQExpBuffer(buf,
546 "SELECT rolname, rolsuper, rolinherit, "
547 "rolcreaterole, rolcreatedb, rolcatupdate, "
548 "rolcanlogin, rolconnlimit, rolpassword, "
550 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
553 else if (server_version >= 80100)
554 printfPQExpBuffer(buf,
555 "SELECT rolname, rolsuper, rolinherit, "
556 "rolcreaterole, rolcreatedb, rolcatupdate, "
557 "rolcanlogin, rolconnlimit, rolpassword, "
558 "rolvaliduntil, null as rolcomment "
562 printfPQExpBuffer(buf,
563 "SELECT usename as rolname, "
564 "usesuper as rolsuper, "
565 "true as rolinherit, "
566 "usesuper as rolcreaterole, "
567 "usecreatedb as rolcreatedb, "
568 "usecatupd as rolcatupdate, "
569 "true as rolcanlogin, "
570 "-1 as rolconnlimit, "
571 "passwd as rolpassword, "
572 "valuntil as rolvaliduntil, "
573 "null as rolcomment "
576 "SELECT groname as rolname, "
577 "false as rolsuper, "
578 "true as rolinherit, "
579 "false as rolcreaterole, "
580 "false as rolcreatedb, "
581 "false as rolcatupdate, "
582 "false as rolcanlogin, "
583 "-1 as rolconnlimit, "
584 "null::text as rolpassword, "
585 "null::abstime as rolvaliduntil, "
586 "null as rolcomment "
588 "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
589 " WHERE usename = groname) "
592 res = executeQuery(conn, buf->data);
594 i_rolname = PQfnumber(res, "rolname");
595 i_rolsuper = PQfnumber(res, "rolsuper");
596 i_rolinherit = PQfnumber(res, "rolinherit");
597 i_rolcreaterole = PQfnumber(res, "rolcreaterole");
598 i_rolcreatedb = PQfnumber(res, "rolcreatedb");
599 i_rolcatupdate = PQfnumber(res, "rolcatupdate");
600 i_rolcanlogin = PQfnumber(res, "rolcanlogin");
601 i_rolconnlimit = PQfnumber(res, "rolconnlimit");
602 i_rolpassword = PQfnumber(res, "rolpassword");
603 i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
604 i_rolcomment = PQfnumber(res, "rolcomment");
606 if (PQntuples(res) > 0)
607 fprintf(OPF, "--\n-- Roles\n--\n\n");
609 for (i = 0; i < PQntuples(res); i++)
611 const char *rolename;
613 rolename = PQgetvalue(res, i, i_rolname);
615 resetPQExpBuffer(buf);
618 appendPQExpBuffer(buf, "DROP ROLE %s;\n", fmtId(rolename));
621 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
622 * will acquire the right properties even if it already exists. (The
623 * above DROP may therefore seem redundant, but it isn't really,
624 * because this technique doesn't get rid of role memberships.)
626 appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
627 appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
629 if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
630 appendPQExpBuffer(buf, " SUPERUSER");
632 appendPQExpBuffer(buf, " NOSUPERUSER");
634 if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
635 appendPQExpBuffer(buf, " INHERIT");
637 appendPQExpBuffer(buf, " NOINHERIT");
639 if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
640 appendPQExpBuffer(buf, " CREATEROLE");
642 appendPQExpBuffer(buf, " NOCREATEROLE");
644 if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
645 appendPQExpBuffer(buf, " CREATEDB");
647 appendPQExpBuffer(buf, " NOCREATEDB");
649 if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
650 appendPQExpBuffer(buf, " LOGIN");
652 appendPQExpBuffer(buf, " NOLOGIN");
654 if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
655 appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
656 PQgetvalue(res, i, i_rolconnlimit));
658 if (!PQgetisnull(res, i, i_rolpassword))
660 appendPQExpBuffer(buf, " PASSWORD ");
661 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolpassword), conn);
664 if (!PQgetisnull(res, i, i_rolvaliduntil))
665 appendPQExpBuffer(buf, " VALID UNTIL '%s'",
666 PQgetvalue(res, i, i_rolvaliduntil));
668 appendPQExpBuffer(buf, ";\n");
670 if (!PQgetisnull(res, i, i_rolcomment))
672 appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
673 appendStringLiteralConn(buf, PQgetvalue(res, i, i_rolcomment), conn);
674 appendPQExpBuffer(buf, ";\n");
677 fprintf(OPF, "%s", buf->data);
679 if (server_version >= 70300)
680 dumpUserConfig(conn, rolename);
685 fprintf(OPF, "\n\n");
687 destroyPQExpBuffer(buf);
692 * Dump role memberships. This code is used for 8.1 and later servers.
694 * Note: we expect dumpRoles already created all the roles, but there is
698 dumpRoleMembership(PGconn *conn)
703 res = executeQuery(conn, "SELECT ur.rolname AS roleid, "
704 "um.rolname AS member, "
706 "ug.rolname AS grantor "
707 "FROM pg_auth_members a "
708 "LEFT JOIN pg_authid ur on ur.oid = a.roleid "
709 "LEFT JOIN pg_authid um on um.oid = a.member "
710 "LEFT JOIN pg_authid ug on ug.oid = a.grantor "
713 if (PQntuples(res) > 0)
714 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
716 for (i = 0; i < PQntuples(res); i++)
718 char *roleid = PQgetvalue(res, i, 0);
719 char *member = PQgetvalue(res, i, 1);
720 char *option = PQgetvalue(res, i, 2);
722 fprintf(OPF, "GRANT %s", fmtId(roleid));
723 fprintf(OPF, " TO %s", fmtId(member));
725 fprintf(OPF, " WITH ADMIN OPTION");
728 * We don't track the grantor very carefully in the backend, so cope
729 * with the possibility that it has been dropped.
731 if (!PQgetisnull(res, i, 3))
733 char *grantor = PQgetvalue(res, i, 3);
735 fprintf(OPF, " GRANTED BY %s", fmtId(grantor));
742 fprintf(OPF, "\n\n");
746 * Dump group memberships from a pre-8.1 server. It's annoying that we
747 * can't share any useful amount of code with the post-8.1 case, but
748 * the catalog representations are too different.
750 * Note: we expect dumpRoles already created all the roles, but there is
754 dumpGroups(PGconn *conn)
756 PQExpBuffer buf = createPQExpBuffer();
760 res = executeQuery(conn,
761 "SELECT groname, grolist FROM pg_group ORDER BY 1");
763 if (PQntuples(res) > 0)
764 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
766 for (i = 0; i < PQntuples(res); i++)
768 char *groname = PQgetvalue(res, i, 0);
769 char *grolist = PQgetvalue(res, i, 1);
774 * Array representation is {1,2,3} ... convert to (1,2,3)
776 if (strlen(grolist) < 3)
779 grolist = strdup(grolist);
781 grolist[strlen(grolist) - 1] = ')';
782 printfPQExpBuffer(buf,
783 "SELECT usename FROM pg_shadow "
784 "WHERE usesysid IN %s ORDER BY 1",
788 res2 = executeQuery(conn, buf->data);
790 for (j = 0; j < PQntuples(res2); j++)
792 char *usename = PQgetvalue(res2, j, 0);
795 * Don't try to grant a role to itself; can happen if old
796 * installation has identically named user and group.
798 if (strcmp(groname, usename) == 0)
801 fprintf(OPF, "GRANT %s", fmtId(groname));
802 fprintf(OPF, " TO %s;\n", fmtId(usename));
809 destroyPQExpBuffer(buf);
811 fprintf(OPF, "\n\n");
818 dumpTablespaces(PGconn *conn)
824 * Get all tablespaces except built-in ones (which we assume are named
827 if (server_version >= 80200)
828 res = executeQuery(conn, "SELECT spcname, "
829 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
830 "spclocation, spcacl, "
831 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
832 "FROM pg_catalog.pg_tablespace "
833 "WHERE spcname !~ '^pg_' "
836 res = executeQuery(conn, "SELECT spcname, "
837 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
838 "spclocation, spcacl, "
840 "FROM pg_catalog.pg_tablespace "
841 "WHERE spcname !~ '^pg_' "
844 if (PQntuples(res) > 0)
845 fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
847 for (i = 0; i < PQntuples(res); i++)
849 PQExpBuffer buf = createPQExpBuffer();
850 char *spcname = PQgetvalue(res, i, 0);
851 char *spcowner = PQgetvalue(res, i, 1);
852 char *spclocation = PQgetvalue(res, i, 2);
853 char *spcacl = PQgetvalue(res, i, 3);
854 char *spccomment = PQgetvalue(res, i, 4);
857 /* needed for buildACLCommands() */
858 fspcname = strdup(fmtId(spcname));
861 appendPQExpBuffer(buf, "DROP TABLESPACE %s;\n", fspcname);
863 appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
864 appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
866 appendPQExpBuffer(buf, " LOCATION ");
867 appendStringLiteralConn(buf, spclocation, conn);
868 appendPQExpBuffer(buf, ";\n");
871 !buildACLCommands(fspcname, "TABLESPACE", spcacl, spcowner,
872 server_version, buf))
874 fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
875 progname, spcacl, fspcname);
880 if (spccomment && strlen(spccomment))
882 appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
883 appendStringLiteralConn(buf, spccomment, conn);
884 appendPQExpBuffer(buf, ";\n");
887 fprintf(OPF, "%s", buf->data);
890 destroyPQExpBuffer(buf);
894 fprintf(OPF, "\n\n");
898 * Dump commands to create each database.
900 * To minimize the number of reconnections (and possibly ensuing
901 * password prompts) required by the output script, we emit all CREATE
902 * DATABASE commands during the initial phase of the script, and then
903 * run pg_dump for each database to dump the contents of that
904 * database. We skip databases marked not datallowconn, since we'd be
905 * unable to connect to them anyway (and besides, we don't want to
909 dumpCreateDB(PGconn *conn)
911 PQExpBuffer buf = createPQExpBuffer();
915 fprintf(OPF, "--\n-- Database creation\n--\n\n");
917 if (server_version >= 80100)
918 res = executeQuery(conn,
920 "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
921 "pg_encoding_to_char(d.encoding), "
922 "datistemplate, datacl, datconnlimit, "
923 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
924 "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
925 "WHERE datallowconn ORDER BY 1");
926 else if (server_version >= 80000)
927 res = executeQuery(conn,
929 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
930 "pg_encoding_to_char(d.encoding), "
931 "datistemplate, datacl, -1 as datconnlimit, "
932 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
933 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
934 "WHERE datallowconn ORDER BY 1");
935 else if (server_version >= 70300)
936 res = executeQuery(conn,
938 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
939 "pg_encoding_to_char(d.encoding), "
940 "datistemplate, datacl, -1 as datconnlimit, "
941 "'pg_default' AS dattablespace "
942 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
943 "WHERE datallowconn ORDER BY 1");
944 else if (server_version >= 70100)
945 res = executeQuery(conn,
948 "(select usename from pg_shadow where usesysid=datdba), "
949 "(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
950 "pg_encoding_to_char(d.encoding), "
951 "datistemplate, '' as datacl, -1 as datconnlimit, "
952 "'pg_default' AS dattablespace "
953 "FROM pg_database d "
954 "WHERE datallowconn ORDER BY 1");
958 * Note: 7.0 fails to cope with sub-select in COALESCE, so just deal
959 * with getting a NULL by not printing any OWNER clause.
961 res = executeQuery(conn,
963 "(select usename from pg_shadow where usesysid=datdba), "
964 "pg_encoding_to_char(d.encoding), "
965 "'f' as datistemplate, "
966 "'' as datacl, -1 as datconnlimit, "
967 "'pg_default' AS dattablespace "
968 "FROM pg_database d "
972 for (i = 0; i < PQntuples(res); i++)
974 char *dbname = PQgetvalue(res, i, 0);
975 char *dbowner = PQgetvalue(res, i, 1);
976 char *dbencoding = PQgetvalue(res, i, 2);
977 char *dbistemplate = PQgetvalue(res, i, 3);
978 char *dbacl = PQgetvalue(res, i, 4);
979 char *dbconnlimit = PQgetvalue(res, i, 5);
980 char *dbtablespace = PQgetvalue(res, i, 6);
983 fdbname = strdup(fmtId(dbname));
985 resetPQExpBuffer(buf);
988 * Skip the CREATE DATABASE commands for "template1" and "postgres",
989 * since they are presumably already there in the destination cluster.
990 * We do want to emit their ACLs and config options if any, however.
992 if (strcmp(dbname, "template1") != 0 &&
993 strcmp(dbname, "postgres") != 0)
996 appendPQExpBuffer(buf, "DROP DATABASE %s;\n", fdbname);
998 appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname);
1000 appendPQExpBuffer(buf, " WITH TEMPLATE = template0");
1002 if (strlen(dbowner) != 0)
1003 appendPQExpBuffer(buf, " OWNER = %s", fmtId(dbowner));
1005 appendPQExpBuffer(buf, " ENCODING = ");
1006 appendStringLiteralConn(buf, dbencoding, conn);
1009 * Output tablespace if it isn't the default. For default, it
1010 * uses the default from the template database. If tablespace is
1011 * specified and tablespace creation failed earlier, (e.g. no such
1012 * directory), the database creation will fail too. One solution
1013 * would be to use 'SET default_tablespace' like we do in pg_dump
1014 * for setting non-default database locations.
1016 if (strcmp(dbtablespace, "pg_default") != 0)
1017 appendPQExpBuffer(buf, " TABLESPACE = %s",
1018 fmtId(dbtablespace));
1020 if (strcmp(dbconnlimit, "-1") != 0)
1021 appendPQExpBuffer(buf, " CONNECTION LIMIT = %s",
1024 appendPQExpBuffer(buf, ";\n");
1026 if (strcmp(dbistemplate, "t") == 0)
1028 appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 't' WHERE datname = ");
1029 appendStringLiteralConn(buf, dbname, conn);
1030 appendPQExpBuffer(buf, ";\n");
1035 !buildACLCommands(fdbname, "DATABASE", dbacl, dbowner,
1036 server_version, buf))
1038 fprintf(stderr, _("%s: could not parse ACL list (%s) for database \"%s\"\n"),
1039 progname, dbacl, fdbname);
1044 fprintf(OPF, "%s", buf->data);
1046 if (server_version >= 70300)
1047 dumpDatabaseConfig(conn, dbname);
1053 destroyPQExpBuffer(buf);
1055 fprintf(OPF, "\n\n");
1061 * Dump database-specific configuration
1064 dumpDatabaseConfig(PGconn *conn, const char *dbname)
1066 PQExpBuffer buf = createPQExpBuffer();
1073 printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
1074 appendStringLiteralConn(buf, dbname, conn);
1075 appendPQExpBuffer(buf, ";");
1077 res = executeQuery(conn, buf->data);
1078 if (!PQgetisnull(res, 0, 0))
1080 makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
1081 "DATABASE", dbname);
1092 destroyPQExpBuffer(buf);
1098 * Dump user-specific configuration
1101 dumpUserConfig(PGconn *conn, const char *username)
1103 PQExpBuffer buf = createPQExpBuffer();
1110 if (server_version >= 80100)
1111 printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count);
1113 printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
1114 appendStringLiteralConn(buf, username, conn);
1116 res = executeQuery(conn, buf->data);
1117 if (PQntuples(res) == 1 &&
1118 !PQgetisnull(res, 0, 0))
1120 makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
1132 destroyPQExpBuffer(buf);
1138 * Helper function for dumpXXXConfig().
1141 makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
1142 const char *type, const char *name)
1146 PQExpBuffer buf = createPQExpBuffer();
1148 mine = strdup(arrayitem);
1149 pos = strchr(mine, '=');
1154 appendPQExpBuffer(buf, "ALTER %s %s ", type, fmtId(name));
1155 appendPQExpBuffer(buf, "SET %s TO ", fmtId(mine));
1158 * Some GUC variable names are 'LIST' type and hence must not be quoted.
1160 if (pg_strcasecmp(mine, "DateStyle") == 0
1161 || pg_strcasecmp(mine, "search_path") == 0)
1162 appendPQExpBuffer(buf, "%s", pos + 1);
1164 appendStringLiteralConn(buf, pos + 1, conn);
1165 appendPQExpBuffer(buf, ";\n");
1167 fprintf(OPF, "%s", buf->data);
1168 destroyPQExpBuffer(buf);
1175 * Dump contents of databases.
1178 dumpDatabases(PGconn *conn)
1183 if (server_version >= 70100)
1184 res = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1");
1186 res = executeQuery(conn, "SELECT datname FROM pg_database ORDER BY 1");
1188 for (i = 0; i < PQntuples(res); i++)
1192 char *dbname = PQgetvalue(res, i, 0);
1195 fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
1197 fprintf(OPF, "\\connect %s\n\n", fmtId(dbname));
1202 ret = runPgDump(dbname);
1205 fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
1211 OPF = fopen(filename, PG_BINARY_A);
1214 fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"),
1215 progname, filename, strerror(errno));
1228 * Run pg_dump on dbname.
1231 runPgDump(const char *dbname)
1233 PQExpBuffer cmd = createPQExpBuffer();
1238 * Win32 has to use double-quotes for args, rather than single quotes.
1239 * Strangely enough, this is the only place we pass a database name on the
1240 * command line, except "postgres" which doesn't need quoting.
1242 * If we have a filename, use the undocumented plain-append pg_dump
1248 appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa '", SYSTEMQUOTE, pg_dump_bin,
1250 appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa \"", SYSTEMQUOTE, pg_dump_bin,
1257 appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp '", SYSTEMQUOTE, pg_dump_bin,
1259 appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp \"", SYSTEMQUOTE, pg_dump_bin,
1265 /* Shell quoting is not quite like SQL quoting, so can't use fmtId */
1266 for (p = dbname; *p; p++)
1270 appendPQExpBuffer(cmd, "'\"'\"'");
1273 appendPQExpBuffer(cmd, "\\\"");
1276 appendPQExpBufferChar(cmd, *p);
1280 appendPQExpBufferChar(cmd, '\'');
1282 appendPQExpBufferChar(cmd, '"');
1285 appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
1288 fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);
1293 ret = system(cmd->data);
1295 destroyPQExpBuffer(cmd);
1303 * Make a database connection with the given parameters. An
1304 * interactive password prompt is automatically issued if required.
1306 * If fail_on_error is false, we return NULL without printing any message
1307 * on failure, but preserve any prompted password for the next try.
1310 connectDatabase(const char *dbname, const char *pghost, const char *pgport,
1311 const char *pguser, bool require_password, bool fail_on_error)
1315 const char *remoteversion_str;
1317 static char *password = NULL;
1319 if (require_password && !password)
1320 password = simple_prompt("Password: ", 100, false);
1323 * Start the connection. Loop until we have a password if requested by
1329 conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
1333 fprintf(stderr, _("%s: could not connect to database \"%s\"\n"),
1338 if (PQstatus(conn) == CONNECTION_BAD &&
1339 PQconnectionNeedsPassword(conn) &&
1344 password = simple_prompt("Password: ", 100, false);
1349 /* check to see that the backend connection was successfully made */
1350 if (PQstatus(conn) == CONNECTION_BAD)
1355 _("%s: could not connect to database \"%s\": %s\n"),
1356 progname, dbname, PQerrorMessage(conn));
1366 remoteversion_str = PQparameterStatus(conn, "server_version");
1367 if (!remoteversion_str)
1369 fprintf(stderr, _("%s: could not get server version\n"), progname);
1372 server_version = parse_version(remoteversion_str);
1373 if (server_version < 0)
1375 fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
1376 progname, remoteversion_str);
1380 my_version = parse_version(PG_VERSION);
1383 fprintf(stderr, _("%s: could not parse version \"%s\"\n"),
1384 progname, PG_VERSION);
1388 if (my_version != server_version
1389 && (server_version < 70000 /* we can handle back to 7.0 */
1390 || server_version > my_version))
1392 fprintf(stderr, _("server version: %s; %s version: %s\n"),
1393 remoteversion_str, progname, PG_VERSION);
1395 fprintf(stderr, _("proceeding despite version mismatch\n"));
1398 fprintf(stderr, _("aborting because of version mismatch (Use the -i option to proceed anyway.)\n"));
1404 * On 7.3 and later, make sure we are not fooled by non-system schemas in
1407 if (server_version >= 70300)
1408 executeCommand(conn, "SET search_path = pg_catalog");
1415 * Run a query, return the results, exit program on failure.
1418 executeQuery(PGconn *conn, const char *query)
1423 fprintf(stderr, _("%s: executing %s\n"), progname, query);
1425 res = PQexec(conn, query);
1427 PQresultStatus(res) != PGRES_TUPLES_OK)
1429 fprintf(stderr, _("%s: query failed: %s"),
1430 progname, PQerrorMessage(conn));
1431 fprintf(stderr, _("%s: query was: %s\n"),
1441 * As above for a SQL command (which returns nothing).
1444 executeCommand(PGconn *conn, const char *query)
1449 fprintf(stderr, _("%s: executing %s\n"), progname, query);
1451 res = PQexec(conn, query);
1453 PQresultStatus(res) != PGRES_COMMAND_OK)
1455 fprintf(stderr, _("%s: query failed: %s"),
1456 progname, PQerrorMessage(conn));
1457 fprintf(stderr, _("%s: query was: %s\n"),
1471 dumpTimestamp(char *msg)
1474 time_t now = time(NULL);
1477 * We don't print the timezone on Win32, because the names are long and
1478 * localized, which means they may contain characters in various random
1479 * encodings; this has been seen to cause encoding errors when reading the
1482 if (strftime(buf, sizeof(buf),
1484 "%Y-%m-%d %H:%M:%S %Z",
1486 "%Y-%m-%d %H:%M:%S",
1488 localtime(&now)) != 0)
1489 fprintf(OPF, "-- %s %s\n\n", msg, buf);