1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
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;
64 static int disable_dollar_quoting
= 0;
65 static int disable_triggers
= 0;
66 static int no_tablespaces
= 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 {"no-tablespaces", no_argument
, &no_tablespaces
, 1},
122 {"use-set-session-authorization", no_argument
, &use_setsessauth
, 1},
123 {"lock-wait-timeout", required_argument
, NULL
, 2},
130 set_pglocale_pgservice(argv
[0], "pg_dump");
132 progname
= get_progname(argv
[0]);
136 if (strcmp(argv
[1], "--help") == 0 || strcmp(argv
[1], "-?") == 0)
141 if (strcmp(argv
[1], "--version") == 0 || strcmp(argv
[1], "-V") == 0)
143 puts("pg_dumpall (PostgreSQL) " PG_VERSION
);
148 if ((ret
= find_other_exec(argv
[0], "pg_dump", PGDUMP_VERSIONSTR
,
151 char full_path
[MAXPGPATH
];
153 if (find_my_exec(argv
[0], full_path
) < 0)
154 strlcpy(full_path
, progname
, sizeof(full_path
));
158 _("The program \"pg_dump\" is needed by %s "
159 "but was not found in the\n"
160 "same directory as \"%s\".\n"
161 "Check your installation.\n"),
162 progname
, full_path
);
165 _("The program \"pg_dump\" was found by \"%s\"\n"
166 "but was not the same version as %s.\n"
167 "Check your installation.\n"),
168 full_path
, progname
);
172 pgdumpopts
= createPQExpBuffer();
174 while ((c
= getopt_long(argc
, argv
, "acdDf:gh:il:oOp:rsS:tU:vWxX:", long_options
, &optindex
)) != -1)
180 appendPQExpBuffer(pgdumpopts
, " -a");
189 appendPQExpBuffer(pgdumpopts
, " -%c", c
);
195 appendPQExpBuffer(pgdumpopts
, " -f '%s'", filename
);
197 appendPQExpBuffer(pgdumpopts
, " -f \"%s\"", filename
);
209 appendPQExpBuffer(pgdumpopts
, " -h '%s'", pghost
);
211 appendPQExpBuffer(pgdumpopts
, " -h \"%s\"", pghost
);
217 /* ignored, deprecated option */
225 appendPQExpBuffer(pgdumpopts
, " -o");
229 appendPQExpBuffer(pgdumpopts
, " -O");
235 appendPQExpBuffer(pgdumpopts
, " -p '%s'", pgport
);
237 appendPQExpBuffer(pgdumpopts
, " -p \"%s\"", pgport
);
247 appendPQExpBuffer(pgdumpopts
, " -s");
252 appendPQExpBuffer(pgdumpopts
, " -S '%s'", optarg
);
254 appendPQExpBuffer(pgdumpopts
, " -S \"%s\"", optarg
);
259 tablespaces_only
= true;
265 appendPQExpBuffer(pgdumpopts
, " -U '%s'", pguser
);
267 appendPQExpBuffer(pgdumpopts
, " -U \"%s\"", pguser
);
273 appendPQExpBuffer(pgdumpopts
, " -v");
277 force_password
= true;
278 appendPQExpBuffer(pgdumpopts
, " -W");
283 appendPQExpBuffer(pgdumpopts
, " -x");
287 /* -X is a deprecated alternative to long options */
288 if (strcmp(optarg
, "disable-dollar-quoting") == 0)
289 disable_dollar_quoting
= 1;
290 else if (strcmp(optarg
, "disable-triggers") == 0)
291 disable_triggers
= 1;
292 else if (strcmp(optarg
, "no-tablespaces") == 0)
294 else if (strcmp(optarg
, "use-set-session-authorization") == 0)
299 _("%s: invalid -X option -- %s\n"),
301 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"), progname
);
310 appendPQExpBuffer(pgdumpopts
, " --lock-wait-timeout=");
311 appendPQExpBuffer(pgdumpopts
, optarg
);
315 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"), progname
);
320 /* Add long options to the pg_dump argument list */
321 if (disable_dollar_quoting
)
322 appendPQExpBuffer(pgdumpopts
, " --disable-dollar-quoting");
323 if (disable_triggers
)
324 appendPQExpBuffer(pgdumpopts
, " --disable-triggers");
326 appendPQExpBuffer(pgdumpopts
, " --no-tablespaces");
328 appendPQExpBuffer(pgdumpopts
, " --use-set-session-authorization");
332 fprintf(stderr
, _("%s: too many command-line arguments (first is \"%s\")\n"),
333 progname
, argv
[optind
]);
334 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
339 /* Make sure the user hasn't specified a mix of globals-only options */
340 if (globals_only
&& roles_only
)
342 fprintf(stderr
, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"),
344 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
349 if (globals_only
&& tablespaces_only
)
351 fprintf(stderr
, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"),
353 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
358 if (roles_only
&& tablespaces_only
)
360 fprintf(stderr
, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"),
362 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
368 * If there was a database specified on the command line, use that,
369 * otherwise try to connect to database "postgres", and failing that
370 * "template1". "postgres" is the preferred choice for 8.1 and later
371 * servers, but it usually will not exist on older ones.
375 conn
= connectDatabase(pgdb
, pghost
, pgport
, pguser
,
376 force_password
, false);
380 fprintf(stderr
, _("%s: could not connect to database \"%s\"\n"),
387 conn
= connectDatabase("postgres", pghost
, pgport
, pguser
,
388 force_password
, false);
390 conn
= connectDatabase("template1", pghost
, pgport
, pguser
,
391 force_password
, true);
395 fprintf(stderr
, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
396 "Please specify an alternative database.\n"),
398 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
405 * Open the output file if required, otherwise use stdout
409 OPF
= fopen(filename
, PG_BINARY_W
);
412 fprintf(stderr
, _("%s: could not open the output file \"%s\": %s\n"),
413 progname
, filename
, strerror(errno
));
421 * Get the active encoding and the standard_conforming_strings setting, so
422 * we know how to escape strings.
424 encoding
= PQclientEncoding(conn
);
425 std_strings
= PQparameterStatus(conn
, "standard_conforming_strings");
429 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump\n--\n\n");
431 dumpTimestamp("Started on");
433 fprintf(OPF
, "\\connect postgres\n\n");
437 /* Replicate encoding and std_strings in output */
438 fprintf(OPF
, "SET client_encoding = '%s';\n",
439 pg_encoding_to_char(encoding
));
440 fprintf(OPF
, "SET standard_conforming_strings = %s;\n", std_strings
);
441 if (strcmp(std_strings
, "off") == 0)
442 fprintf(OPF
, "SET escape_string_warning = 'off';\n");
445 if (!tablespaces_only
)
447 /* Dump roles (users) */
450 /* Dump role memberships --- need different method for pre-8.1 */
451 if (server_version
>= 80100)
452 dumpRoleMembership(conn
);
457 if (!roles_only
&& !no_tablespaces
)
459 /* Dump tablespaces */
460 if (server_version
>= 80000)
461 dumpTablespaces(conn
);
464 /* Dump CREATE DATABASE commands */
465 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
469 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
475 dumpTimestamp("Completed on");
476 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
489 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname
);
490 printf(_("Usage:\n"));
491 printf(_(" %s [OPTION]...\n"), progname
);
493 printf(_("\nGeneral options:\n"));
494 printf(_(" -f, --file=FILENAME output file name\n"));
495 printf(_(" --help show this help, then exit\n"));
496 printf(_(" --version output version information, then exit\n"));
497 printf(_(" --lock-wait-timeout=TIMEOUT\n"
498 " fail after waiting TIMEOUT for a table lock\n"));
499 printf(_("\nOptions controlling the output content:\n"));
500 printf(_(" -a, --data-only dump only the data, not the schema\n"));
501 printf(_(" -c, --clean clean (drop) databases prior to create\n"));
502 printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
503 printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
504 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
505 printf(_(" -o, --oids include OIDs in dump\n"));
506 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
507 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
508 printf(_(" -s, --schema-only dump only the schema, no data\n"));
509 printf(_(" -S, --superuser=NAME specify the superuser user name to use in the dump\n"));
510 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
511 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
512 printf(_(" --disable-dollar-quoting\n"
513 " disable dollar quoting, use SQL standard quoting\n"));
514 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
515 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
516 printf(_(" --use-set-session-authorization\n"
517 " use SESSION AUTHORIZATION commands instead of\n"
518 " OWNER TO commands\n"));
520 printf(_("\nConnection options:\n"));
521 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
522 printf(_(" -l, --database=DBNAME specify an alternative default database\n"));
523 printf(_(" -p, --port=PORT database server port number\n"));
524 printf(_(" -U, --username=NAME connect as specified database user\n"));
525 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
527 printf(_("\nThe SQL script will be written to the standard output.\n\n"));
528 printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
537 dumpRoles(PGconn
*conn
)
539 PQExpBuffer buf
= createPQExpBuffer();
554 /* note: rolconfig is dumped later */
555 if (server_version
>= 80200)
556 printfPQExpBuffer(buf
,
557 "SELECT rolname, rolsuper, rolinherit, "
558 "rolcreaterole, rolcreatedb, rolcatupdate, "
559 "rolcanlogin, rolconnlimit, rolpassword, "
561 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
564 else if (server_version
>= 80100)
565 printfPQExpBuffer(buf
,
566 "SELECT rolname, rolsuper, rolinherit, "
567 "rolcreaterole, rolcreatedb, rolcatupdate, "
568 "rolcanlogin, rolconnlimit, rolpassword, "
569 "rolvaliduntil, null as rolcomment "
573 printfPQExpBuffer(buf
,
574 "SELECT usename as rolname, "
575 "usesuper as rolsuper, "
576 "true as rolinherit, "
577 "usesuper as rolcreaterole, "
578 "usecreatedb as rolcreatedb, "
579 "usecatupd as rolcatupdate, "
580 "true as rolcanlogin, "
581 "-1 as rolconnlimit, "
582 "passwd as rolpassword, "
583 "valuntil as rolvaliduntil, "
584 "null as rolcomment "
587 "SELECT groname as rolname, "
588 "false as rolsuper, "
589 "true as rolinherit, "
590 "false as rolcreaterole, "
591 "false as rolcreatedb, "
592 "false as rolcatupdate, "
593 "false as rolcanlogin, "
594 "-1 as rolconnlimit, "
595 "null::text as rolpassword, "
596 "null::abstime as rolvaliduntil, "
597 "null as rolcomment "
599 "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
600 " WHERE usename = groname) "
603 res
= executeQuery(conn
, buf
->data
);
605 i_rolname
= PQfnumber(res
, "rolname");
606 i_rolsuper
= PQfnumber(res
, "rolsuper");
607 i_rolinherit
= PQfnumber(res
, "rolinherit");
608 i_rolcreaterole
= PQfnumber(res
, "rolcreaterole");
609 i_rolcreatedb
= PQfnumber(res
, "rolcreatedb");
610 i_rolcatupdate
= PQfnumber(res
, "rolcatupdate");
611 i_rolcanlogin
= PQfnumber(res
, "rolcanlogin");
612 i_rolconnlimit
= PQfnumber(res
, "rolconnlimit");
613 i_rolpassword
= PQfnumber(res
, "rolpassword");
614 i_rolvaliduntil
= PQfnumber(res
, "rolvaliduntil");
615 i_rolcomment
= PQfnumber(res
, "rolcomment");
617 if (PQntuples(res
) > 0)
618 fprintf(OPF
, "--\n-- Roles\n--\n\n");
620 for (i
= 0; i
< PQntuples(res
); i
++)
622 const char *rolename
;
624 rolename
= PQgetvalue(res
, i
, i_rolname
);
626 resetPQExpBuffer(buf
);
629 appendPQExpBuffer(buf
, "DROP ROLE %s;\n", fmtId(rolename
));
632 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
633 * will acquire the right properties even if it already exists. (The
634 * above DROP may therefore seem redundant, but it isn't really,
635 * because this technique doesn't get rid of role memberships.)
637 appendPQExpBuffer(buf
, "CREATE ROLE %s;\n", fmtId(rolename
));
638 appendPQExpBuffer(buf
, "ALTER ROLE %s WITH", fmtId(rolename
));
640 if (strcmp(PQgetvalue(res
, i
, i_rolsuper
), "t") == 0)
641 appendPQExpBuffer(buf
, " SUPERUSER");
643 appendPQExpBuffer(buf
, " NOSUPERUSER");
645 if (strcmp(PQgetvalue(res
, i
, i_rolinherit
), "t") == 0)
646 appendPQExpBuffer(buf
, " INHERIT");
648 appendPQExpBuffer(buf
, " NOINHERIT");
650 if (strcmp(PQgetvalue(res
, i
, i_rolcreaterole
), "t") == 0)
651 appendPQExpBuffer(buf
, " CREATEROLE");
653 appendPQExpBuffer(buf
, " NOCREATEROLE");
655 if (strcmp(PQgetvalue(res
, i
, i_rolcreatedb
), "t") == 0)
656 appendPQExpBuffer(buf
, " CREATEDB");
658 appendPQExpBuffer(buf
, " NOCREATEDB");
660 if (strcmp(PQgetvalue(res
, i
, i_rolcanlogin
), "t") == 0)
661 appendPQExpBuffer(buf
, " LOGIN");
663 appendPQExpBuffer(buf
, " NOLOGIN");
665 if (strcmp(PQgetvalue(res
, i
, i_rolconnlimit
), "-1") != 0)
666 appendPQExpBuffer(buf
, " CONNECTION LIMIT %s",
667 PQgetvalue(res
, i
, i_rolconnlimit
));
669 if (!PQgetisnull(res
, i
, i_rolpassword
))
671 appendPQExpBuffer(buf
, " PASSWORD ");
672 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolpassword
), conn
);
675 if (!PQgetisnull(res
, i
, i_rolvaliduntil
))
676 appendPQExpBuffer(buf
, " VALID UNTIL '%s'",
677 PQgetvalue(res
, i
, i_rolvaliduntil
));
679 appendPQExpBuffer(buf
, ";\n");
681 if (!PQgetisnull(res
, i
, i_rolcomment
))
683 appendPQExpBuffer(buf
, "COMMENT ON ROLE %s IS ", fmtId(rolename
));
684 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolcomment
), conn
);
685 appendPQExpBuffer(buf
, ";\n");
688 fprintf(OPF
, "%s", buf
->data
);
690 if (server_version
>= 70300)
691 dumpUserConfig(conn
, rolename
);
696 fprintf(OPF
, "\n\n");
698 destroyPQExpBuffer(buf
);
703 * Dump role memberships. This code is used for 8.1 and later servers.
705 * Note: we expect dumpRoles already created all the roles, but there is
709 dumpRoleMembership(PGconn
*conn
)
714 res
= executeQuery(conn
, "SELECT ur.rolname AS roleid, "
715 "um.rolname AS member, "
717 "ug.rolname AS grantor "
718 "FROM pg_auth_members a "
719 "LEFT JOIN pg_authid ur on ur.oid = a.roleid "
720 "LEFT JOIN pg_authid um on um.oid = a.member "
721 "LEFT JOIN pg_authid ug on ug.oid = a.grantor "
724 if (PQntuples(res
) > 0)
725 fprintf(OPF
, "--\n-- Role memberships\n--\n\n");
727 for (i
= 0; i
< PQntuples(res
); i
++)
729 char *roleid
= PQgetvalue(res
, i
, 0);
730 char *member
= PQgetvalue(res
, i
, 1);
731 char *option
= PQgetvalue(res
, i
, 2);
733 fprintf(OPF
, "GRANT %s", fmtId(roleid
));
734 fprintf(OPF
, " TO %s", fmtId(member
));
736 fprintf(OPF
, " WITH ADMIN OPTION");
739 * We don't track the grantor very carefully in the backend, so cope
740 * with the possibility that it has been dropped.
742 if (!PQgetisnull(res
, i
, 3))
744 char *grantor
= PQgetvalue(res
, i
, 3);
746 fprintf(OPF
, " GRANTED BY %s", fmtId(grantor
));
753 fprintf(OPF
, "\n\n");
757 * Dump group memberships from a pre-8.1 server. It's annoying that we
758 * can't share any useful amount of code with the post-8.1 case, but
759 * the catalog representations are too different.
761 * Note: we expect dumpRoles already created all the roles, but there is
765 dumpGroups(PGconn
*conn
)
767 PQExpBuffer buf
= createPQExpBuffer();
771 res
= executeQuery(conn
,
772 "SELECT groname, grolist FROM pg_group ORDER BY 1");
774 if (PQntuples(res
) > 0)
775 fprintf(OPF
, "--\n-- Role memberships\n--\n\n");
777 for (i
= 0; i
< PQntuples(res
); i
++)
779 char *groname
= PQgetvalue(res
, i
, 0);
780 char *grolist
= PQgetvalue(res
, i
, 1);
785 * Array representation is {1,2,3} ... convert to (1,2,3)
787 if (strlen(grolist
) < 3)
790 grolist
= strdup(grolist
);
792 grolist
[strlen(grolist
) - 1] = ')';
793 printfPQExpBuffer(buf
,
794 "SELECT usename FROM pg_shadow "
795 "WHERE usesysid IN %s ORDER BY 1",
799 res2
= executeQuery(conn
, buf
->data
);
801 for (j
= 0; j
< PQntuples(res2
); j
++)
803 char *usename
= PQgetvalue(res2
, j
, 0);
806 * Don't try to grant a role to itself; can happen if old
807 * installation has identically named user and group.
809 if (strcmp(groname
, usename
) == 0)
812 fprintf(OPF
, "GRANT %s", fmtId(groname
));
813 fprintf(OPF
, " TO %s;\n", fmtId(usename
));
820 destroyPQExpBuffer(buf
);
822 fprintf(OPF
, "\n\n");
829 dumpTablespaces(PGconn
*conn
)
835 * Get all tablespaces except built-in ones (which we assume are named
838 if (server_version
>= 80200)
839 res
= executeQuery(conn
, "SELECT spcname, "
840 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
841 "spclocation, spcacl, "
842 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
843 "FROM pg_catalog.pg_tablespace "
844 "WHERE spcname !~ '^pg_' "
847 res
= executeQuery(conn
, "SELECT spcname, "
848 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
849 "spclocation, spcacl, "
851 "FROM pg_catalog.pg_tablespace "
852 "WHERE spcname !~ '^pg_' "
855 if (PQntuples(res
) > 0)
856 fprintf(OPF
, "--\n-- Tablespaces\n--\n\n");
858 for (i
= 0; i
< PQntuples(res
); i
++)
860 PQExpBuffer buf
= createPQExpBuffer();
861 char *spcname
= PQgetvalue(res
, i
, 0);
862 char *spcowner
= PQgetvalue(res
, i
, 1);
863 char *spclocation
= PQgetvalue(res
, i
, 2);
864 char *spcacl
= PQgetvalue(res
, i
, 3);
865 char *spccomment
= PQgetvalue(res
, i
, 4);
868 /* needed for buildACLCommands() */
869 fspcname
= strdup(fmtId(spcname
));
872 appendPQExpBuffer(buf
, "DROP TABLESPACE %s;\n", fspcname
);
874 appendPQExpBuffer(buf
, "CREATE TABLESPACE %s", fspcname
);
875 appendPQExpBuffer(buf
, " OWNER %s", fmtId(spcowner
));
877 appendPQExpBuffer(buf
, " LOCATION ");
878 appendStringLiteralConn(buf
, spclocation
, conn
);
879 appendPQExpBuffer(buf
, ";\n");
882 !buildACLCommands(fspcname
, "TABLESPACE", spcacl
, spcowner
,
883 server_version
, buf
))
885 fprintf(stderr
, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
886 progname
, spcacl
, fspcname
);
891 if (spccomment
&& strlen(spccomment
))
893 appendPQExpBuffer(buf
, "COMMENT ON TABLESPACE %s IS ", fspcname
);
894 appendStringLiteralConn(buf
, spccomment
, conn
);
895 appendPQExpBuffer(buf
, ";\n");
898 fprintf(OPF
, "%s", buf
->data
);
901 destroyPQExpBuffer(buf
);
905 fprintf(OPF
, "\n\n");
909 * Dump commands to create each database.
911 * To minimize the number of reconnections (and possibly ensuing
912 * password prompts) required by the output script, we emit all CREATE
913 * DATABASE commands during the initial phase of the script, and then
914 * run pg_dump for each database to dump the contents of that
915 * database. We skip databases marked not datallowconn, since we'd be
916 * unable to connect to them anyway (and besides, we don't want to
920 dumpCreateDB(PGconn
*conn
)
922 PQExpBuffer buf
= createPQExpBuffer();
926 fprintf(OPF
, "--\n-- Database creation\n--\n\n");
928 if (server_version
>= 80400)
929 res
= executeQuery(conn
,
931 "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
932 "pg_encoding_to_char(d.encoding), "
933 "datcollate, datctype, "
934 "datistemplate, datacl, datconnlimit, "
935 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
936 "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
937 "WHERE datallowconn ORDER BY 1");
938 else if (server_version
>= 80100)
939 res
= executeQuery(conn
,
941 "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
942 "pg_encoding_to_char(d.encoding), "
943 "null::text AS datcollate, null::text AS datctype, "
944 "datistemplate, datacl, datconnlimit, "
945 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
946 "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
947 "WHERE datallowconn ORDER BY 1");
948 else if (server_version
>= 80000)
949 res
= executeQuery(conn
,
951 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
952 "pg_encoding_to_char(d.encoding), "
953 "null::text AS datcollate, null::text AS datctype, "
954 "datistemplate, datacl, -1 as datconnlimit, "
955 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
956 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
957 "WHERE datallowconn ORDER BY 1");
958 else if (server_version
>= 70300)
959 res
= executeQuery(conn
,
961 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
962 "pg_encoding_to_char(d.encoding), "
963 "null::text AS datcollate, null::text AS datctype, "
964 "datistemplate, datacl, -1 as datconnlimit, "
965 "'pg_default' AS dattablespace "
966 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
967 "WHERE datallowconn ORDER BY 1");
968 else if (server_version
>= 70100)
969 res
= executeQuery(conn
,
972 "(select usename from pg_shadow where usesysid=datdba), "
973 "(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
974 "pg_encoding_to_char(d.encoding), "
975 "null::text AS datcollate, null::text AS datctype, "
976 "datistemplate, '' as datacl, -1 as datconnlimit, "
977 "'pg_default' AS dattablespace "
978 "FROM pg_database d "
979 "WHERE datallowconn ORDER BY 1");
983 * Note: 7.0 fails to cope with sub-select in COALESCE, so just deal
984 * with getting a NULL by not printing any OWNER clause.
986 res
= executeQuery(conn
,
988 "(select usename from pg_shadow where usesysid=datdba), "
989 "pg_encoding_to_char(d.encoding), "
990 "null::text AS datcollate, null::text AS datctype, "
991 "'f' as datistemplate, "
992 "'' as datacl, -1 as datconnlimit, "
993 "'pg_default' AS dattablespace "
994 "FROM pg_database d "
998 for (i
= 0; i
< PQntuples(res
); i
++)
1000 char *dbname
= PQgetvalue(res
, i
, 0);
1001 char *dbowner
= PQgetvalue(res
, i
, 1);
1002 char *dbencoding
= PQgetvalue(res
, i
, 2);
1003 char *dbcollate
= PQgetvalue(res
, i
, 3);
1004 char *dbctype
= PQgetvalue(res
, i
, 4);
1005 char *dbistemplate
= PQgetvalue(res
, i
, 5);
1006 char *dbacl
= PQgetvalue(res
, i
, 6);
1007 char *dbconnlimit
= PQgetvalue(res
, i
, 7);
1008 char *dbtablespace
= PQgetvalue(res
, i
, 8);
1011 fdbname
= strdup(fmtId(dbname
));
1013 resetPQExpBuffer(buf
);
1016 * Skip the CREATE DATABASE commands for "template1" and "postgres",
1017 * since they are presumably already there in the destination cluster.
1018 * We do want to emit their ACLs and config options if any, however.
1020 if (strcmp(dbname
, "template1") != 0 &&
1021 strcmp(dbname
, "postgres") != 0)
1024 appendPQExpBuffer(buf
, "DROP DATABASE %s;\n", fdbname
);
1026 appendPQExpBuffer(buf
, "CREATE DATABASE %s", fdbname
);
1028 appendPQExpBuffer(buf
, " WITH TEMPLATE = template0");
1030 if (strlen(dbowner
) != 0)
1031 appendPQExpBuffer(buf
, " OWNER = %s", fmtId(dbowner
));
1033 appendPQExpBuffer(buf
, " ENCODING = ");
1034 appendStringLiteralConn(buf
, dbencoding
, conn
);
1036 if (strlen(dbcollate
) != 0)
1038 appendPQExpBuffer(buf
, " COLLATE = ");
1039 appendStringLiteralConn(buf
, dbcollate
, conn
);
1042 if (strlen(dbctype
) != 0)
1044 appendPQExpBuffer(buf
, " CTYPE = ");
1045 appendStringLiteralConn(buf
, dbctype
, conn
);
1049 * Output tablespace if it isn't the default. For default, it
1050 * uses the default from the template database. If tablespace is
1051 * specified and tablespace creation failed earlier, (e.g. no such
1052 * directory), the database creation will fail too. One solution
1053 * would be to use 'SET default_tablespace' like we do in pg_dump
1054 * for setting non-default database locations.
1056 if (strcmp(dbtablespace
, "pg_default") != 0 && !no_tablespaces
)
1057 appendPQExpBuffer(buf
, " TABLESPACE = %s",
1058 fmtId(dbtablespace
));
1060 if (strcmp(dbconnlimit
, "-1") != 0)
1061 appendPQExpBuffer(buf
, " CONNECTION LIMIT = %s",
1064 appendPQExpBuffer(buf
, ";\n");
1066 if (strcmp(dbistemplate
, "t") == 0)
1068 appendPQExpBuffer(buf
, "UPDATE pg_database SET datistemplate = 't' WHERE datname = ");
1069 appendStringLiteralConn(buf
, dbname
, conn
);
1070 appendPQExpBuffer(buf
, ";\n");
1075 !buildACLCommands(fdbname
, "DATABASE", dbacl
, dbowner
,
1076 server_version
, buf
))
1078 fprintf(stderr
, _("%s: could not parse ACL list (%s) for database \"%s\"\n"),
1079 progname
, dbacl
, fdbname
);
1084 fprintf(OPF
, "%s", buf
->data
);
1086 if (server_version
>= 70300)
1087 dumpDatabaseConfig(conn
, dbname
);
1093 destroyPQExpBuffer(buf
);
1095 fprintf(OPF
, "\n\n");
1101 * Dump database-specific configuration
1104 dumpDatabaseConfig(PGconn
*conn
, const char *dbname
)
1106 PQExpBuffer buf
= createPQExpBuffer();
1113 printfPQExpBuffer(buf
, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count
);
1114 appendStringLiteralConn(buf
, dbname
, conn
);
1115 appendPQExpBuffer(buf
, ";");
1117 res
= executeQuery(conn
, buf
->data
);
1118 if (!PQgetisnull(res
, 0, 0))
1120 makeAlterConfigCommand(conn
, PQgetvalue(res
, 0, 0),
1121 "DATABASE", dbname
);
1132 destroyPQExpBuffer(buf
);
1138 * Dump user-specific configuration
1141 dumpUserConfig(PGconn
*conn
, const char *username
)
1143 PQExpBuffer buf
= createPQExpBuffer();
1150 if (server_version
>= 80100)
1151 printfPQExpBuffer(buf
, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count
);
1153 printfPQExpBuffer(buf
, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count
);
1154 appendStringLiteralConn(buf
, username
, conn
);
1156 res
= executeQuery(conn
, buf
->data
);
1157 if (PQntuples(res
) == 1 &&
1158 !PQgetisnull(res
, 0, 0))
1160 makeAlterConfigCommand(conn
, PQgetvalue(res
, 0, 0),
1172 destroyPQExpBuffer(buf
);
1178 * Helper function for dumpXXXConfig().
1181 makeAlterConfigCommand(PGconn
*conn
, const char *arrayitem
,
1182 const char *type
, const char *name
)
1186 PQExpBuffer buf
= createPQExpBuffer();
1188 mine
= strdup(arrayitem
);
1189 pos
= strchr(mine
, '=');
1194 appendPQExpBuffer(buf
, "ALTER %s %s ", type
, fmtId(name
));
1195 appendPQExpBuffer(buf
, "SET %s TO ", fmtId(mine
));
1198 * Some GUC variable names are 'LIST' type and hence must not be quoted.
1200 if (pg_strcasecmp(mine
, "DateStyle") == 0
1201 || pg_strcasecmp(mine
, "search_path") == 0)
1202 appendPQExpBuffer(buf
, "%s", pos
+ 1);
1204 appendStringLiteralConn(buf
, pos
+ 1, conn
);
1205 appendPQExpBuffer(buf
, ";\n");
1207 fprintf(OPF
, "%s", buf
->data
);
1208 destroyPQExpBuffer(buf
);
1215 * Dump contents of databases.
1218 dumpDatabases(PGconn
*conn
)
1223 if (server_version
>= 70100)
1224 res
= executeQuery(conn
, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1");
1226 res
= executeQuery(conn
, "SELECT datname FROM pg_database ORDER BY 1");
1228 for (i
= 0; i
< PQntuples(res
); i
++)
1232 char *dbname
= PQgetvalue(res
, i
, 0);
1235 fprintf(stderr
, _("%s: dumping database \"%s\"...\n"), progname
, dbname
);
1237 fprintf(OPF
, "\\connect %s\n\n", fmtId(dbname
));
1242 ret
= runPgDump(dbname
);
1245 fprintf(stderr
, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname
, dbname
);
1251 OPF
= fopen(filename
, PG_BINARY_A
);
1254 fprintf(stderr
, _("%s: could not re-open the output file \"%s\": %s\n"),
1255 progname
, filename
, strerror(errno
));
1268 * Run pg_dump on dbname.
1271 runPgDump(const char *dbname
)
1273 PQExpBuffer cmd
= createPQExpBuffer();
1278 * Win32 has to use double-quotes for args, rather than single quotes.
1279 * Strangely enough, this is the only place we pass a database name on the
1280 * command line, except "postgres" which doesn't need quoting.
1282 * If we have a filename, use the undocumented plain-append pg_dump
1288 appendPQExpBuffer(cmd
, SYSTEMQUOTE
"\"%s\" %s -Fa '", pg_dump_bin
,
1290 appendPQExpBuffer(cmd
, SYSTEMQUOTE
"\"%s\" %s -Fa \"", pg_dump_bin
,
1297 appendPQExpBuffer(cmd
, SYSTEMQUOTE
"\"%s\" %s -Fp '", pg_dump_bin
,
1299 appendPQExpBuffer(cmd
, SYSTEMQUOTE
"\"%s\" %s -Fp \"", pg_dump_bin
,
1305 /* Shell quoting is not quite like SQL quoting, so can't use fmtId */
1306 for (p
= dbname
; *p
; p
++)
1310 appendPQExpBuffer(cmd
, "'\"'\"'");
1313 appendPQExpBuffer(cmd
, "\\\"");
1316 appendPQExpBufferChar(cmd
, *p
);
1320 appendPQExpBufferChar(cmd
, '\'');
1322 appendPQExpBufferChar(cmd
, '"');
1325 appendPQExpBuffer(cmd
, "%s", SYSTEMQUOTE
);
1328 fprintf(stderr
, _("%s: running \"%s\"\n"), progname
, cmd
->data
);
1333 ret
= system(cmd
->data
);
1335 destroyPQExpBuffer(cmd
);
1343 * Make a database connection with the given parameters. An
1344 * interactive password prompt is automatically issued if required.
1346 * If fail_on_error is false, we return NULL without printing any message
1347 * on failure, but preserve any prompted password for the next try.
1350 connectDatabase(const char *dbname
, const char *pghost
, const char *pgport
,
1351 const char *pguser
, bool require_password
, bool fail_on_error
)
1355 const char *remoteversion_str
;
1357 static char *password
= NULL
;
1359 if (require_password
&& !password
)
1360 password
= simple_prompt("Password: ", 100, false);
1363 * Start the connection. Loop until we have a password if requested by
1369 conn
= PQsetdbLogin(pghost
, pgport
, NULL
, NULL
, dbname
, pguser
, password
);
1373 fprintf(stderr
, _("%s: could not connect to database \"%s\"\n"),
1378 if (PQstatus(conn
) == CONNECTION_BAD
&&
1379 PQconnectionNeedsPassword(conn
) &&
1384 password
= simple_prompt("Password: ", 100, false);
1389 /* check to see that the backend connection was successfully made */
1390 if (PQstatus(conn
) == CONNECTION_BAD
)
1395 _("%s: could not connect to database \"%s\": %s\n"),
1396 progname
, dbname
, PQerrorMessage(conn
));
1406 remoteversion_str
= PQparameterStatus(conn
, "server_version");
1407 if (!remoteversion_str
)
1409 fprintf(stderr
, _("%s: could not get server version\n"), progname
);
1412 server_version
= parse_version(remoteversion_str
);
1413 if (server_version
< 0)
1415 fprintf(stderr
, _("%s: could not parse server version \"%s\"\n"),
1416 progname
, remoteversion_str
);
1420 my_version
= parse_version(PG_VERSION
);
1423 fprintf(stderr
, _("%s: could not parse version \"%s\"\n"),
1424 progname
, PG_VERSION
);
1429 * We allow the server to be back to 7.0, and up to any minor release
1430 * of our own major version. (See also version check in pg_dump.c.)
1432 if (my_version
!= server_version
1433 && (server_version
< 70000 ||
1434 (server_version
/ 100) > (my_version
/ 100)))
1436 fprintf(stderr
, _("server version: %s; %s version: %s\n"),
1437 remoteversion_str
, progname
, PG_VERSION
);
1438 fprintf(stderr
, _("aborting because of server version mismatch\n"));
1443 * On 7.3 and later, make sure we are not fooled by non-system schemas in
1446 if (server_version
>= 70300)
1447 executeCommand(conn
, "SET search_path = pg_catalog");
1454 * Run a query, return the results, exit program on failure.
1457 executeQuery(PGconn
*conn
, const char *query
)
1462 fprintf(stderr
, _("%s: executing %s\n"), progname
, query
);
1464 res
= PQexec(conn
, query
);
1466 PQresultStatus(res
) != PGRES_TUPLES_OK
)
1468 fprintf(stderr
, _("%s: query failed: %s"),
1469 progname
, PQerrorMessage(conn
));
1470 fprintf(stderr
, _("%s: query was: %s\n"),
1480 * As above for a SQL command (which returns nothing).
1483 executeCommand(PGconn
*conn
, const char *query
)
1488 fprintf(stderr
, _("%s: executing %s\n"), progname
, query
);
1490 res
= PQexec(conn
, query
);
1492 PQresultStatus(res
) != PGRES_COMMAND_OK
)
1494 fprintf(stderr
, _("%s: query failed: %s"),
1495 progname
, PQerrorMessage(conn
));
1496 fprintf(stderr
, _("%s: query was: %s\n"),
1510 dumpTimestamp(char *msg
)
1513 time_t now
= time(NULL
);
1516 * We don't print the timezone on Win32, because the names are long and
1517 * localized, which means they may contain characters in various random
1518 * encodings; this has been seen to cause encoding errors when reading the
1521 if (strftime(buf
, sizeof(buf
),
1523 "%Y-%m-%d %H:%M:%S %Z",
1525 "%Y-%m-%d %H:%M:%S",
1527 localtime(&now
)) != 0)
1528 fprintf(OPF
, "-- %s %s\n\n", msg
, buf
);