1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2022, 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 "catalog/pg_authid_d.h"
22 #include "common/connect.h"
23 #include "common/file_utils.h"
24 #include "common/hashfn.h"
25 #include "common/logging.h"
26 #include "common/string.h"
27 #include "dumputils.h"
28 #include "fe_utils/string_utils.h"
29 #include "getopt_long.h"
30 #include "pg_backup.h"
32 /* version string we expect back from pg_dump */
33 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
35 static uint32
hash_string_pointer(char *s
);
44 #define SH_PREFIX rolename
45 #define SH_ELEMENT_TYPE RoleNameEntry
46 #define SH_KEY_TYPE char *
47 #define SH_KEY rolename
48 #define SH_HASH_KEY(tb, key) hash_string_pointer(key)
49 #define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
51 #define SH_GET_HASH(tb, a) (a)->hashval
52 #define SH_SCOPE static inline
53 #define SH_RAW_ALLOCATOR pg_malloc0
56 #include "lib/simplehash.h"
58 static void help(void);
60 static void dropRoles(PGconn
*conn
);
61 static void dumpRoles(PGconn
*conn
);
62 static void dumpRoleMembership(PGconn
*conn
);
63 static void dumpRoleGUCPrivs(PGconn
*conn
);
64 static void dropTablespaces(PGconn
*conn
);
65 static void dumpTablespaces(PGconn
*conn
);
66 static void dropDBs(PGconn
*conn
);
67 static void dumpUserConfig(PGconn
*conn
, const char *username
);
68 static void dumpDatabases(PGconn
*conn
);
69 static void dumpTimestamp(const char *msg
);
70 static int runPgDump(const char *dbname
, const char *create_opts
);
71 static void buildShSecLabels(PGconn
*conn
,
72 const char *catalog_name
, Oid objectId
,
73 const char *objtype
, const char *objname
,
75 static PGconn
*connectDatabase(const char *dbname
, const char *connstr
, const char *pghost
, const char *pgport
,
76 const char *pguser
, trivalue prompt_password
, bool fail_on_error
);
77 static char *constructConnStr(const char **keywords
, const char **values
);
78 static PGresult
*executeQuery(PGconn
*conn
, const char *query
);
79 static void executeCommand(PGconn
*conn
, const char *query
);
80 static void expand_dbname_patterns(PGconn
*conn
, SimpleStringList
*patterns
,
81 SimpleStringList
*names
);
83 static char pg_dump_bin
[MAXPGPATH
];
84 static const char *progname
;
85 static PQExpBuffer pgdumpopts
;
86 static char *connstr
= "";
87 static bool output_clean
= false;
88 static bool skip_acls
= false;
89 static bool verbose
= false;
90 static bool dosync
= true;
92 static int binary_upgrade
= 0;
93 static int column_inserts
= 0;
94 static int disable_dollar_quoting
= 0;
95 static int disable_triggers
= 0;
96 static int if_exists
= 0;
97 static int inserts
= 0;
98 static int no_table_access_method
= 0;
99 static int no_tablespaces
= 0;
100 static int use_setsessauth
= 0;
101 static int no_comments
= 0;
102 static int no_publications
= 0;
103 static int no_security_labels
= 0;
104 static int no_subscriptions
= 0;
105 static int no_toast_compression
= 0;
106 static int no_unlogged_table_data
= 0;
107 static int no_role_passwords
= 0;
108 static int server_version
;
109 static int load_via_partition_root
= 0;
110 static int on_conflict_do_nothing
= 0;
112 static char role_catalog
[10];
113 #define PG_AUTHID "pg_authid"
114 #define PG_ROLES "pg_roles "
117 static char *filename
= NULL
;
119 static SimpleStringList database_exclude_patterns
= {NULL
, NULL
};
120 static SimpleStringList database_exclude_names
= {NULL
, NULL
};
122 #define exit_nicely(code) exit(code)
125 main(int argc
, char *argv
[])
127 static struct option long_options
[] = {
128 {"data-only", no_argument
, NULL
, 'a'},
129 {"clean", no_argument
, NULL
, 'c'},
130 {"encoding", required_argument
, NULL
, 'E'},
131 {"file", required_argument
, NULL
, 'f'},
132 {"globals-only", no_argument
, NULL
, 'g'},
133 {"host", required_argument
, NULL
, 'h'},
134 {"dbname", required_argument
, NULL
, 'd'},
135 {"database", required_argument
, NULL
, 'l'},
136 {"no-owner", no_argument
, NULL
, 'O'},
137 {"port", required_argument
, NULL
, 'p'},
138 {"roles-only", no_argument
, NULL
, 'r'},
139 {"schema-only", no_argument
, NULL
, 's'},
140 {"superuser", required_argument
, NULL
, 'S'},
141 {"tablespaces-only", no_argument
, NULL
, 't'},
142 {"username", required_argument
, NULL
, 'U'},
143 {"verbose", no_argument
, NULL
, 'v'},
144 {"no-password", no_argument
, NULL
, 'w'},
145 {"password", no_argument
, NULL
, 'W'},
146 {"no-privileges", no_argument
, NULL
, 'x'},
147 {"no-acl", no_argument
, NULL
, 'x'},
150 * the following options don't have an equivalent short option letter
152 {"attribute-inserts", no_argument
, &column_inserts
, 1},
153 {"binary-upgrade", no_argument
, &binary_upgrade
, 1},
154 {"column-inserts", no_argument
, &column_inserts
, 1},
155 {"disable-dollar-quoting", no_argument
, &disable_dollar_quoting
, 1},
156 {"disable-triggers", no_argument
, &disable_triggers
, 1},
157 {"exclude-database", required_argument
, NULL
, 6},
158 {"extra-float-digits", required_argument
, NULL
, 5},
159 {"if-exists", no_argument
, &if_exists
, 1},
160 {"inserts", no_argument
, &inserts
, 1},
161 {"lock-wait-timeout", required_argument
, NULL
, 2},
162 {"no-table-access-method", no_argument
, &no_table_access_method
, 1},
163 {"no-tablespaces", no_argument
, &no_tablespaces
, 1},
164 {"quote-all-identifiers", no_argument
, "e_all_identifiers
, 1},
165 {"load-via-partition-root", no_argument
, &load_via_partition_root
, 1},
166 {"role", required_argument
, NULL
, 3},
167 {"use-set-session-authorization", no_argument
, &use_setsessauth
, 1},
168 {"no-comments", no_argument
, &no_comments
, 1},
169 {"no-publications", no_argument
, &no_publications
, 1},
170 {"no-role-passwords", no_argument
, &no_role_passwords
, 1},
171 {"no-security-labels", no_argument
, &no_security_labels
, 1},
172 {"no-subscriptions", no_argument
, &no_subscriptions
, 1},
173 {"no-sync", no_argument
, NULL
, 4},
174 {"no-toast-compression", no_argument
, &no_toast_compression
, 1},
175 {"no-unlogged-table-data", no_argument
, &no_unlogged_table_data
, 1},
176 {"on-conflict-do-nothing", no_argument
, &on_conflict_do_nothing
, 1},
177 {"rows-per-insert", required_argument
, NULL
, 7},
186 char *use_role
= NULL
;
187 const char *dumpencoding
= NULL
;
188 trivalue prompt_password
= TRI_DEFAULT
;
189 bool data_only
= false;
190 bool globals_only
= false;
191 bool roles_only
= false;
192 bool tablespaces_only
= false;
195 const char *std_strings
;
200 pg_logging_init(argv
[0]);
201 pg_logging_set_level(PG_LOG_WARNING
);
202 set_pglocale_pgservice(argv
[0], PG_TEXTDOMAIN("pg_dump"));
203 progname
= get_progname(argv
[0]);
207 if (strcmp(argv
[1], "--help") == 0 || strcmp(argv
[1], "-?") == 0)
212 if (strcmp(argv
[1], "--version") == 0 || strcmp(argv
[1], "-V") == 0)
214 puts("pg_dumpall (PostgreSQL) " PG_VERSION
);
219 if ((ret
= find_other_exec(argv
[0], "pg_dump", PGDUMP_VERSIONSTR
,
222 char full_path
[MAXPGPATH
];
224 if (find_my_exec(argv
[0], full_path
) < 0)
225 strlcpy(full_path
, progname
, sizeof(full_path
));
228 pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
229 "pg_dump", progname
, full_path
);
231 pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s",
232 "pg_dump", full_path
, progname
);
235 pgdumpopts
= createPQExpBuffer();
237 while ((c
= getopt_long(argc
, argv
, "acd:E:f:gh:l:Op:rsS:tU:vwWx", long_options
, &optindex
)) != -1)
243 appendPQExpBufferStr(pgdumpopts
, " -a");
251 connstr
= pg_strdup(optarg
);
255 dumpencoding
= pg_strdup(optarg
);
256 appendPQExpBufferStr(pgdumpopts
, " -E ");
257 appendShellString(pgdumpopts
, optarg
);
261 filename
= pg_strdup(optarg
);
262 appendPQExpBufferStr(pgdumpopts
, " -f ");
263 appendShellString(pgdumpopts
, filename
);
271 pghost
= pg_strdup(optarg
);
275 pgdb
= pg_strdup(optarg
);
279 appendPQExpBufferStr(pgdumpopts
, " -O");
283 pgport
= pg_strdup(optarg
);
291 appendPQExpBufferStr(pgdumpopts
, " -s");
295 appendPQExpBufferStr(pgdumpopts
, " -S ");
296 appendShellString(pgdumpopts
, optarg
);
300 tablespaces_only
= true;
304 pguser
= pg_strdup(optarg
);
309 pg_logging_increase_verbosity();
310 appendPQExpBufferStr(pgdumpopts
, " -v");
314 prompt_password
= TRI_NO
;
315 appendPQExpBufferStr(pgdumpopts
, " -w");
319 prompt_password
= TRI_YES
;
320 appendPQExpBufferStr(pgdumpopts
, " -W");
325 appendPQExpBufferStr(pgdumpopts
, " -x");
332 appendPQExpBufferStr(pgdumpopts
, " --lock-wait-timeout ");
333 appendShellString(pgdumpopts
, optarg
);
337 use_role
= pg_strdup(optarg
);
338 appendPQExpBufferStr(pgdumpopts
, " --role ");
339 appendShellString(pgdumpopts
, use_role
);
344 appendPQExpBufferStr(pgdumpopts
, " --no-sync");
348 appendPQExpBufferStr(pgdumpopts
, " --extra-float-digits ");
349 appendShellString(pgdumpopts
, optarg
);
353 simple_string_list_append(&database_exclude_patterns
, optarg
);
357 appendPQExpBufferStr(pgdumpopts
, " --rows-per-insert ");
358 appendShellString(pgdumpopts
, optarg
);
362 /* getopt_long already emitted a complaint */
363 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
368 /* Complain if any arguments remain */
371 pg_log_error("too many command-line arguments (first is \"%s\")",
373 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
377 if (database_exclude_patterns
.head
!= NULL
&&
378 (globals_only
|| roles_only
|| tablespaces_only
))
380 pg_log_error("option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only");
381 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
385 /* Make sure the user hasn't specified a mix of globals-only options */
386 if (globals_only
&& roles_only
)
388 pg_log_error("options -g/--globals-only and -r/--roles-only cannot be used together");
389 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
393 if (globals_only
&& tablespaces_only
)
395 pg_log_error("options -g/--globals-only and -t/--tablespaces-only cannot be used together");
396 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
400 if (if_exists
&& !output_clean
)
401 pg_fatal("option --if-exists requires option -c/--clean");
403 if (roles_only
&& tablespaces_only
)
405 pg_log_error("options -r/--roles-only and -t/--tablespaces-only cannot be used together");
406 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
411 * If password values are not required in the dump, switch to using
412 * pg_roles which is equally useful, just more likely to have unrestricted
413 * access than pg_authid.
415 if (no_role_passwords
)
416 sprintf(role_catalog
, "%s", PG_ROLES
);
418 sprintf(role_catalog
, "%s", PG_AUTHID
);
420 /* Add long options to the pg_dump argument list */
422 appendPQExpBufferStr(pgdumpopts
, " --binary-upgrade");
424 appendPQExpBufferStr(pgdumpopts
, " --column-inserts");
425 if (disable_dollar_quoting
)
426 appendPQExpBufferStr(pgdumpopts
, " --disable-dollar-quoting");
427 if (disable_triggers
)
428 appendPQExpBufferStr(pgdumpopts
, " --disable-triggers");
430 appendPQExpBufferStr(pgdumpopts
, " --inserts");
431 if (no_table_access_method
)
432 appendPQExpBufferStr(pgdumpopts
, " --no-table-access-method");
434 appendPQExpBufferStr(pgdumpopts
, " --no-tablespaces");
435 if (quote_all_identifiers
)
436 appendPQExpBufferStr(pgdumpopts
, " --quote-all-identifiers");
437 if (load_via_partition_root
)
438 appendPQExpBufferStr(pgdumpopts
, " --load-via-partition-root");
440 appendPQExpBufferStr(pgdumpopts
, " --use-set-session-authorization");
442 appendPQExpBufferStr(pgdumpopts
, " --no-comments");
444 appendPQExpBufferStr(pgdumpopts
, " --no-publications");
445 if (no_security_labels
)
446 appendPQExpBufferStr(pgdumpopts
, " --no-security-labels");
447 if (no_subscriptions
)
448 appendPQExpBufferStr(pgdumpopts
, " --no-subscriptions");
449 if (no_toast_compression
)
450 appendPQExpBufferStr(pgdumpopts
, " --no-toast-compression");
451 if (no_unlogged_table_data
)
452 appendPQExpBufferStr(pgdumpopts
, " --no-unlogged-table-data");
453 if (on_conflict_do_nothing
)
454 appendPQExpBufferStr(pgdumpopts
, " --on-conflict-do-nothing");
457 * If there was a database specified on the command line, use that,
458 * otherwise try to connect to database "postgres", and failing that
463 conn
= connectDatabase(pgdb
, connstr
, pghost
, pgport
, pguser
,
464 prompt_password
, false);
467 pg_fatal("could not connect to database \"%s\"", pgdb
);
471 conn
= connectDatabase("postgres", connstr
, pghost
, pgport
, pguser
,
472 prompt_password
, false);
474 conn
= connectDatabase("template1", connstr
, pghost
, pgport
, pguser
,
475 prompt_password
, true);
479 pg_log_error("could not connect to databases \"postgres\" or \"template1\"\n"
480 "Please specify an alternative database.");
481 pg_log_error_hint("Try \"%s --help\" for more information.", progname
);
487 * Get a list of database names that match the exclude patterns
489 expand_dbname_patterns(conn
, &database_exclude_patterns
,
490 &database_exclude_names
);
493 * Open the output file if required, otherwise use stdout
497 OPF
= fopen(filename
, PG_BINARY_W
);
499 pg_fatal("could not open output file \"%s\": %m",
506 * Set the client encoding if requested.
510 if (PQsetClientEncoding(conn
, dumpencoding
) < 0)
511 pg_fatal("invalid client encoding \"%s\" specified",
516 * Get the active encoding and the standard_conforming_strings setting, so
517 * we know how to escape strings.
519 encoding
= PQclientEncoding(conn
);
520 std_strings
= PQparameterStatus(conn
, "standard_conforming_strings");
524 /* Set the role if requested */
527 PQExpBuffer query
= createPQExpBuffer();
529 appendPQExpBuffer(query
, "SET ROLE %s", fmtId(use_role
));
530 executeCommand(conn
, query
->data
);
531 destroyPQExpBuffer(query
);
534 /* Force quoting of all identifiers if requested. */
535 if (quote_all_identifiers
)
536 executeCommand(conn
, "SET quote_all_identifiers = true");
538 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump\n--\n\n");
540 dumpTimestamp("Started on");
543 * We used to emit \connect postgres here, but that served no purpose
544 * other than to break things for installations without a postgres
545 * database. Everything we're restoring here is a global, so whichever
546 * database we're connected to at the moment is fine.
549 /* Restore will need to write to the target cluster */
550 fprintf(OPF
, "SET default_transaction_read_only = off;\n\n");
552 /* Replicate encoding and std_strings in output */
553 fprintf(OPF
, "SET client_encoding = '%s';\n",
554 pg_encoding_to_char(encoding
));
555 fprintf(OPF
, "SET standard_conforming_strings = %s;\n", std_strings
);
556 if (strcmp(std_strings
, "off") == 0)
557 fprintf(OPF
, "SET escape_string_warning = off;\n");
563 * If asked to --clean, do that first. We can avoid detailed
564 * dependency analysis because databases never depend on each other,
565 * and tablespaces never depend on each other. Roles could have
566 * grants to each other, but DROP ROLE will clean those up silently.
570 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
573 if (!roles_only
&& !no_tablespaces
)
574 dropTablespaces(conn
);
576 if (!tablespaces_only
)
581 * Now create objects as requested. Be careful that option logic here
582 * is the same as for drops above.
584 if (!tablespaces_only
)
586 /* Dump roles (users) */
589 /* Dump role memberships */
590 dumpRoleMembership(conn
);
592 /* Dump role GUC privileges */
593 if (server_version
>= 150000 && !skip_acls
)
594 dumpRoleGUCPrivs(conn
);
597 /* Dump tablespaces */
598 if (!roles_only
&& !no_tablespaces
)
599 dumpTablespaces(conn
);
602 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
608 dumpTimestamp("Completed on");
609 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
615 /* sync the resulting file, errors are not fatal */
617 (void) fsync_fname(filename
, false);
627 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname
);
628 printf(_("Usage:\n"));
629 printf(_(" %s [OPTION]...\n"), progname
);
631 printf(_("\nGeneral options:\n"));
632 printf(_(" -f, --file=FILENAME output file name\n"));
633 printf(_(" -v, --verbose verbose mode\n"));
634 printf(_(" -V, --version output version information, then exit\n"));
635 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
636 printf(_(" -?, --help show this help, then exit\n"));
637 printf(_("\nOptions controlling the output content:\n"));
638 printf(_(" -a, --data-only dump only the data, not the schema\n"));
639 printf(_(" -c, --clean clean (drop) databases before recreating\n"));
640 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
641 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
642 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
643 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
644 printf(_(" -s, --schema-only dump only the schema, no data\n"));
645 printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
646 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
647 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
648 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
649 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
650 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
651 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
652 printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n"));
653 printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
654 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
655 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
656 printf(_(" --load-via-partition-root load partitions via the root table\n"));
657 printf(_(" --no-comments do not dump comments\n"));
658 printf(_(" --no-publications do not dump publications\n"));
659 printf(_(" --no-role-passwords do not dump passwords for roles\n"));
660 printf(_(" --no-security-labels do not dump security label assignments\n"));
661 printf(_(" --no-subscriptions do not dump subscriptions\n"));
662 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
663 printf(_(" --no-table-access-method do not dump table access methods\n"));
664 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
665 printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
666 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
667 printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
668 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
669 printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
670 printf(_(" --use-set-session-authorization\n"
671 " use SET SESSION AUTHORIZATION commands instead of\n"
672 " ALTER OWNER commands to set ownership\n"));
674 printf(_("\nConnection options:\n"));
675 printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
676 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
677 printf(_(" -l, --database=DBNAME alternative default database\n"));
678 printf(_(" -p, --port=PORT database server port number\n"));
679 printf(_(" -U, --username=NAME connect as specified database user\n"));
680 printf(_(" -w, --no-password never prompt for password\n"));
681 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
682 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
684 printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
686 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
687 printf(_("%s home page: <%s>\n"), PACKAGE_NAME
, PACKAGE_URL
);
695 dropRoles(PGconn
*conn
)
697 PQExpBuffer buf
= createPQExpBuffer();
702 if (server_version
>= 90600)
703 printfPQExpBuffer(buf
,
706 "WHERE rolname !~ '^pg_' "
707 "ORDER BY 1", role_catalog
);
709 printfPQExpBuffer(buf
,
712 "ORDER BY 1", role_catalog
);
714 res
= executeQuery(conn
, buf
->data
);
716 i_rolname
= PQfnumber(res
, "rolname");
718 if (PQntuples(res
) > 0)
719 fprintf(OPF
, "--\n-- Drop roles\n--\n\n");
721 for (i
= 0; i
< PQntuples(res
); i
++)
723 const char *rolename
;
725 rolename
= PQgetvalue(res
, i
, i_rolname
);
727 fprintf(OPF
, "DROP ROLE %s%s;\n",
728 if_exists
? "IF EXISTS " : "",
733 destroyPQExpBuffer(buf
);
735 fprintf(OPF
, "\n\n");
742 dumpRoles(PGconn
*conn
)
744 PQExpBuffer buf
= createPQExpBuffer();
762 /* note: rolconfig is dumped later */
763 if (server_version
>= 90600)
764 printfPQExpBuffer(buf
,
765 "SELECT oid, rolname, rolsuper, rolinherit, "
766 "rolcreaterole, rolcreatedb, "
767 "rolcanlogin, rolconnlimit, rolpassword, "
768 "rolvaliduntil, rolreplication, rolbypassrls, "
769 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
770 "rolname = current_user AS is_current_user "
772 "WHERE rolname !~ '^pg_' "
773 "ORDER BY 2", role_catalog
, role_catalog
);
774 else if (server_version
>= 90500)
775 printfPQExpBuffer(buf
,
776 "SELECT oid, rolname, rolsuper, rolinherit, "
777 "rolcreaterole, rolcreatedb, "
778 "rolcanlogin, rolconnlimit, rolpassword, "
779 "rolvaliduntil, rolreplication, rolbypassrls, "
780 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
781 "rolname = current_user AS is_current_user "
783 "ORDER BY 2", role_catalog
, role_catalog
);
785 printfPQExpBuffer(buf
,
786 "SELECT oid, rolname, rolsuper, rolinherit, "
787 "rolcreaterole, rolcreatedb, "
788 "rolcanlogin, rolconnlimit, rolpassword, "
789 "rolvaliduntil, rolreplication, "
790 "false as rolbypassrls, "
791 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
792 "rolname = current_user AS is_current_user "
794 "ORDER BY 2", role_catalog
, role_catalog
);
796 res
= executeQuery(conn
, buf
->data
);
798 i_oid
= PQfnumber(res
, "oid");
799 i_rolname
= PQfnumber(res
, "rolname");
800 i_rolsuper
= PQfnumber(res
, "rolsuper");
801 i_rolinherit
= PQfnumber(res
, "rolinherit");
802 i_rolcreaterole
= PQfnumber(res
, "rolcreaterole");
803 i_rolcreatedb
= PQfnumber(res
, "rolcreatedb");
804 i_rolcanlogin
= PQfnumber(res
, "rolcanlogin");
805 i_rolconnlimit
= PQfnumber(res
, "rolconnlimit");
806 i_rolpassword
= PQfnumber(res
, "rolpassword");
807 i_rolvaliduntil
= PQfnumber(res
, "rolvaliduntil");
808 i_rolreplication
= PQfnumber(res
, "rolreplication");
809 i_rolbypassrls
= PQfnumber(res
, "rolbypassrls");
810 i_rolcomment
= PQfnumber(res
, "rolcomment");
811 i_is_current_user
= PQfnumber(res
, "is_current_user");
813 if (PQntuples(res
) > 0)
814 fprintf(OPF
, "--\n-- Roles\n--\n\n");
816 for (i
= 0; i
< PQntuples(res
); i
++)
818 const char *rolename
;
821 auth_oid
= atooid(PQgetvalue(res
, i
, i_oid
));
822 rolename
= PQgetvalue(res
, i
, i_rolname
);
824 if (strncmp(rolename
, "pg_", 3) == 0)
826 pg_log_warning("role name starting with \"pg_\" skipped (%s)",
831 resetPQExpBuffer(buf
);
835 appendPQExpBufferStr(buf
, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
836 appendPQExpBuffer(buf
,
837 "SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
842 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
843 * will acquire the right properties even if it already exists (ie, it
844 * won't hurt for the CREATE to fail). This is particularly important
845 * for the role we are connected as, since even with --clean we will
846 * have failed to drop it. binary_upgrade cannot generate any errors,
847 * so we assume the current role is already created.
849 if (!binary_upgrade
||
850 strcmp(PQgetvalue(res
, i
, i_is_current_user
), "f") == 0)
851 appendPQExpBuffer(buf
, "CREATE ROLE %s;\n", fmtId(rolename
));
852 appendPQExpBuffer(buf
, "ALTER ROLE %s WITH", fmtId(rolename
));
854 if (strcmp(PQgetvalue(res
, i
, i_rolsuper
), "t") == 0)
855 appendPQExpBufferStr(buf
, " SUPERUSER");
857 appendPQExpBufferStr(buf
, " NOSUPERUSER");
859 if (strcmp(PQgetvalue(res
, i
, i_rolinherit
), "t") == 0)
860 appendPQExpBufferStr(buf
, " INHERIT");
862 appendPQExpBufferStr(buf
, " NOINHERIT");
864 if (strcmp(PQgetvalue(res
, i
, i_rolcreaterole
), "t") == 0)
865 appendPQExpBufferStr(buf
, " CREATEROLE");
867 appendPQExpBufferStr(buf
, " NOCREATEROLE");
869 if (strcmp(PQgetvalue(res
, i
, i_rolcreatedb
), "t") == 0)
870 appendPQExpBufferStr(buf
, " CREATEDB");
872 appendPQExpBufferStr(buf
, " NOCREATEDB");
874 if (strcmp(PQgetvalue(res
, i
, i_rolcanlogin
), "t") == 0)
875 appendPQExpBufferStr(buf
, " LOGIN");
877 appendPQExpBufferStr(buf
, " NOLOGIN");
879 if (strcmp(PQgetvalue(res
, i
, i_rolreplication
), "t") == 0)
880 appendPQExpBufferStr(buf
, " REPLICATION");
882 appendPQExpBufferStr(buf
, " NOREPLICATION");
884 if (strcmp(PQgetvalue(res
, i
, i_rolbypassrls
), "t") == 0)
885 appendPQExpBufferStr(buf
, " BYPASSRLS");
887 appendPQExpBufferStr(buf
, " NOBYPASSRLS");
889 if (strcmp(PQgetvalue(res
, i
, i_rolconnlimit
), "-1") != 0)
890 appendPQExpBuffer(buf
, " CONNECTION LIMIT %s",
891 PQgetvalue(res
, i
, i_rolconnlimit
));
894 if (!PQgetisnull(res
, i
, i_rolpassword
) && !no_role_passwords
)
896 appendPQExpBufferStr(buf
, " PASSWORD ");
897 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolpassword
), conn
);
900 if (!PQgetisnull(res
, i
, i_rolvaliduntil
))
901 appendPQExpBuffer(buf
, " VALID UNTIL '%s'",
902 PQgetvalue(res
, i
, i_rolvaliduntil
));
904 appendPQExpBufferStr(buf
, ";\n");
906 if (!no_comments
&& !PQgetisnull(res
, i
, i_rolcomment
))
908 appendPQExpBuffer(buf
, "COMMENT ON ROLE %s IS ", fmtId(rolename
));
909 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolcomment
), conn
);
910 appendPQExpBufferStr(buf
, ";\n");
913 if (!no_security_labels
)
914 buildShSecLabels(conn
, "pg_authid", auth_oid
,
918 fprintf(OPF
, "%s", buf
->data
);
922 * Dump configuration settings for roles after all roles have been dumped.
923 * We do it this way because config settings for roles could mention the
924 * names of other roles.
926 if (PQntuples(res
) > 0)
927 fprintf(OPF
, "\n--\n-- User Configurations\n--\n");
929 for (i
= 0; i
< PQntuples(res
); i
++)
930 dumpUserConfig(conn
, PQgetvalue(res
, i
, i_rolname
));
934 fprintf(OPF
, "\n\n");
936 destroyPQExpBuffer(buf
);
941 * Dump role memberships.
943 * Note: we expect dumpRoles already created all the roles, but there is
947 dumpRoleMembership(PGconn
*conn
)
949 PQExpBuffer buf
= createPQExpBuffer();
950 PQExpBuffer optbuf
= createPQExpBuffer();
956 bool dump_inherit_option
;
957 int i_inherit_option
;
960 * Previous versions of PostgreSQL didn't used to track the grantor very
961 * carefully in the backend, and the grantor could be any user even if
962 * they didn't have ADMIN OPTION on the role, or a user that no longer
963 * existed. To avoid dump and restore failures, don't dump the grantor
964 * when talking to an old server version.
966 dump_grantors
= (PQserverVersion(conn
) >= 160000);
969 * Previous versions of PostgreSQL also did not have a grant-level
972 dump_inherit_option
= (server_version
>= 160000);
974 /* Generate and execute query. */
975 printfPQExpBuffer(buf
, "SELECT ur.rolname AS role, "
976 "um.rolname AS member, "
977 "ug.oid AS grantorid, "
978 "ug.rolname AS grantor, "
980 if (dump_inherit_option
)
981 appendPQExpBuffer(buf
, ", a.inherit_option");
982 appendPQExpBuffer(buf
, " FROM pg_auth_members a "
983 "LEFT JOIN %s ur on ur.oid = a.roleid "
984 "LEFT JOIN %s um on um.oid = a.member "
985 "LEFT JOIN %s ug on ug.oid = a.grantor "
986 "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
987 "ORDER BY 1,2,4", role_catalog
, role_catalog
, role_catalog
);
988 res
= executeQuery(conn
, buf
->data
);
989 i_inherit_option
= PQfnumber(res
, "inherit_option");
991 if (PQntuples(res
) > 0)
992 fprintf(OPF
, "--\n-- Role memberships\n--\n\n");
995 * We can't dump these GRANT commands in arbitary order, because a role
996 * that is named as a grantor must already have ADMIN OPTION on the
997 * role for which it is granting permissions, except for the boostrap
998 * superuser, who can always be named as the grantor.
1000 * We handle this by considering these grants role by role. For each role,
1001 * we initially consider the only allowable grantor to be the boostrap
1002 * superuser. Every time we grant ADMIN OPTION on the role to some user,
1003 * that user also becomes an allowable grantor. We make repeated passes
1004 * over the grants for the role, each time dumping those whose grantors
1005 * are allowable and which we haven't done yet. Eventually this should
1006 * let us dump all the grants.
1008 total
= PQntuples(res
);
1009 while (start
< total
)
1011 char *role
= PQgetvalue(res
, start
, 0);
1015 int prev_remaining
= 0;
1018 /* All memberships for a single role should be adjacent. */
1019 for (end
= start
; end
< total
; ++end
)
1023 otherrole
= PQgetvalue(res
, end
, 0);
1024 if (strcmp(role
, otherrole
) != 0)
1028 role
= PQgetvalue(res
, start
, 0);
1029 remaining
= end
- start
;
1030 done
= pg_malloc0(remaining
* sizeof(bool));
1031 ht
= rolename_create(remaining
, NULL
);
1034 * Make repeated passses over the grants for this role until all have
1037 while (remaining
> 0)
1040 * We should make progress on every iteration, because a notional
1041 * graph whose vertices are grants and whose edges point from
1042 * grantors to members should be connected and acyclic. If we fail
1043 * to make progress, either we or the server have messed up.
1045 if (remaining
== prev_remaining
)
1047 pg_log_error("could not find a legal dump ordering for memberships in role \"%s\"",
1053 /* Make one pass over the grants for this role. */
1054 for (i
= start
; i
< end
; ++i
)
1062 /* If we already did this grant, don't do it again. */
1063 if (done
[i
- start
])
1066 member
= PQgetvalue(res
, i
, 1);
1067 grantorid
= PQgetvalue(res
, i
, 2);
1068 grantor
= PQgetvalue(res
, i
, 3);
1069 admin_option
= PQgetvalue(res
, i
, 4);
1072 * If we're not dumping grantors or if the grantor is the
1073 * bootstrap superuser, it's fine to dump this now. Otherwise,
1074 * it's got to be someone who has already been granted ADMIN
1077 if (dump_grantors
&&
1078 atooid(grantorid
) != BOOTSTRAP_SUPERUSERID
&&
1079 rolename_lookup(ht
, grantor
) == NULL
)
1082 /* Remember that we did this so that we don't do it again. */
1083 done
[i
- start
] = true;
1087 * If ADMIN OPTION is being granted, remember that grants
1088 * listing this member as the grantor can now be dumped.
1090 if (*admin_option
== 't')
1091 rolename_insert(ht
, member
, &found
);
1093 /* Generate the actual GRANT statement. */
1094 resetPQExpBuffer(optbuf
);
1095 fprintf(OPF
, "GRANT %s", fmtId(role
));
1096 fprintf(OPF
, " TO %s", fmtId(member
));
1097 if (*admin_option
== 't')
1098 appendPQExpBufferStr(optbuf
, "ADMIN OPTION");
1099 if (dump_inherit_option
)
1101 char *inherit_option
;
1103 if (optbuf
->data
[0] != '\0')
1104 appendPQExpBufferStr(optbuf
, ", ");
1105 inherit_option
= PQgetvalue(res
, i
, i_inherit_option
);
1106 appendPQExpBuffer(optbuf
, "INHERIT %s",
1107 *inherit_option
== 't' ?
1110 if (optbuf
->data
[0] != '\0')
1111 fprintf(OPF
, " WITH %s", optbuf
->data
);
1113 fprintf(OPF
, " GRANTED BY %s", fmtId(grantor
));
1114 fprintf(OPF
, ";\n");
1118 rolename_destroy(ht
);
1124 destroyPQExpBuffer(buf
);
1126 fprintf(OPF
, "\n\n");
1131 * Dump role configuration parameter privileges. This code is used for 15.0
1132 * and later servers.
1134 * Note: we expect dumpRoles already created all the roles, but there are
1135 * no per-role configuration parameter privileges yet.
1138 dumpRoleGUCPrivs(PGconn
*conn
)
1144 * Get all parameters that have non-default acls defined.
1146 res
= executeQuery(conn
, "SELECT parname, "
1147 "pg_catalog.pg_get_userbyid(" CppAsString2(BOOTSTRAP_SUPERUSERID
) ") AS parowner, "
1149 "pg_catalog.acldefault('p', " CppAsString2(BOOTSTRAP_SUPERUSERID
) ") AS acldefault "
1150 "FROM pg_catalog.pg_parameter_acl "
1153 if (PQntuples(res
) > 0)
1154 fprintf(OPF
, "--\n-- Role privileges on configuration parameters\n--\n\n");
1156 for (i
= 0; i
< PQntuples(res
); i
++)
1158 PQExpBuffer buf
= createPQExpBuffer();
1159 char *parname
= PQgetvalue(res
, i
, 0);
1160 char *parowner
= PQgetvalue(res
, i
, 1);
1161 char *paracl
= PQgetvalue(res
, i
, 2);
1162 char *acldefault
= PQgetvalue(res
, i
, 3);
1165 /* needed for buildACLCommands() */
1166 fparname
= pg_strdup(fmtId(parname
));
1168 if (!buildACLCommands(fparname
, NULL
, NULL
, "PARAMETER",
1170 parowner
, "", server_version
, buf
))
1172 pg_log_error("could not parse ACL list (%s) for parameter \"%s\"",
1178 fprintf(OPF
, "%s", buf
->data
);
1181 destroyPQExpBuffer(buf
);
1185 fprintf(OPF
, "\n\n");
1193 dropTablespaces(PGconn
*conn
)
1199 * Get all tablespaces except built-in ones (which we assume are named
1202 res
= executeQuery(conn
, "SELECT spcname "
1203 "FROM pg_catalog.pg_tablespace "
1204 "WHERE spcname !~ '^pg_' "
1207 if (PQntuples(res
) > 0)
1208 fprintf(OPF
, "--\n-- Drop tablespaces\n--\n\n");
1210 for (i
= 0; i
< PQntuples(res
); i
++)
1212 char *spcname
= PQgetvalue(res
, i
, 0);
1214 fprintf(OPF
, "DROP TABLESPACE %s%s;\n",
1215 if_exists
? "IF EXISTS " : "",
1221 fprintf(OPF
, "\n\n");
1228 dumpTablespaces(PGconn
*conn
)
1234 * Get all tablespaces except built-in ones (which we assume are named
1237 res
= executeQuery(conn
, "SELECT oid, spcname, "
1238 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1239 "pg_catalog.pg_tablespace_location(oid), "
1240 "spcacl, acldefault('t', spcowner) AS acldefault, "
1241 "array_to_string(spcoptions, ', '),"
1242 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1243 "FROM pg_catalog.pg_tablespace "
1244 "WHERE spcname !~ '^pg_' "
1247 if (PQntuples(res
) > 0)
1248 fprintf(OPF
, "--\n-- Tablespaces\n--\n\n");
1250 for (i
= 0; i
< PQntuples(res
); i
++)
1252 PQExpBuffer buf
= createPQExpBuffer();
1253 Oid spcoid
= atooid(PQgetvalue(res
, i
, 0));
1254 char *spcname
= PQgetvalue(res
, i
, 1);
1255 char *spcowner
= PQgetvalue(res
, i
, 2);
1256 char *spclocation
= PQgetvalue(res
, i
, 3);
1257 char *spcacl
= PQgetvalue(res
, i
, 4);
1258 char *acldefault
= PQgetvalue(res
, i
, 5);
1259 char *spcoptions
= PQgetvalue(res
, i
, 6);
1260 char *spccomment
= PQgetvalue(res
, i
, 7);
1263 /* needed for buildACLCommands() */
1264 fspcname
= pg_strdup(fmtId(spcname
));
1268 appendPQExpBufferStr(buf
, "\n-- For binary upgrade, must preserve pg_tablespace oid\n");
1269 appendPQExpBuffer(buf
, "SELECT pg_catalog.binary_upgrade_set_next_pg_tablespace_oid('%u'::pg_catalog.oid);\n", spcoid
);
1272 appendPQExpBuffer(buf
, "CREATE TABLESPACE %s", fspcname
);
1273 appendPQExpBuffer(buf
, " OWNER %s", fmtId(spcowner
));
1275 appendPQExpBufferStr(buf
, " LOCATION ");
1276 appendStringLiteralConn(buf
, spclocation
, conn
);
1277 appendPQExpBufferStr(buf
, ";\n");
1279 if (spcoptions
&& spcoptions
[0] != '\0')
1280 appendPQExpBuffer(buf
, "ALTER TABLESPACE %s SET (%s);\n",
1281 fspcname
, spcoptions
);
1283 /* tablespaces can't have initprivs */
1286 !buildACLCommands(fspcname
, NULL
, NULL
, "TABLESPACE",
1288 spcowner
, "", server_version
, buf
))
1290 pg_log_error("could not parse ACL list (%s) for tablespace \"%s\"",
1296 if (!no_comments
&& spccomment
&& spccomment
[0] != '\0')
1298 appendPQExpBuffer(buf
, "COMMENT ON TABLESPACE %s IS ", fspcname
);
1299 appendStringLiteralConn(buf
, spccomment
, conn
);
1300 appendPQExpBufferStr(buf
, ";\n");
1303 if (!no_security_labels
)
1304 buildShSecLabels(conn
, "pg_tablespace", spcoid
,
1305 "TABLESPACE", spcname
,
1308 fprintf(OPF
, "%s", buf
->data
);
1311 destroyPQExpBuffer(buf
);
1315 fprintf(OPF
, "\n\n");
1320 * Dump commands to drop each database.
1323 dropDBs(PGconn
*conn
)
1329 * Skip databases marked not datallowconn, since we'd be unable to connect
1330 * to them anyway. This must agree with dumpDatabases().
1332 res
= executeQuery(conn
,
1334 "FROM pg_database d "
1335 "WHERE datallowconn "
1336 "ORDER BY datname");
1338 if (PQntuples(res
) > 0)
1339 fprintf(OPF
, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
1341 for (i
= 0; i
< PQntuples(res
); i
++)
1343 char *dbname
= PQgetvalue(res
, i
, 0);
1346 * Skip "postgres" and "template1"; dumpDatabases() will deal with
1347 * them specially. Also, be sure to skip "template0", even if for
1348 * some reason it's not marked !datallowconn.
1350 if (strcmp(dbname
, "template1") != 0 &&
1351 strcmp(dbname
, "template0") != 0 &&
1352 strcmp(dbname
, "postgres") != 0)
1354 fprintf(OPF
, "DROP DATABASE %s%s;\n",
1355 if_exists
? "IF EXISTS " : "",
1362 fprintf(OPF
, "\n\n");
1367 * Dump user-specific configuration
1370 dumpUserConfig(PGconn
*conn
, const char *username
)
1372 PQExpBuffer buf
= createPQExpBuffer();
1375 printfPQExpBuffer(buf
, "SELECT unnest(setconfig) FROM pg_db_role_setting "
1376 "WHERE setdatabase = 0 AND setrole = "
1377 "(SELECT oid FROM %s WHERE rolname = ",
1379 appendStringLiteralConn(buf
, username
, conn
);
1380 appendPQExpBufferChar(buf
, ')');
1382 res
= executeQuery(conn
, buf
->data
);
1384 if (PQntuples(res
) > 0)
1385 fprintf(OPF
, "\n--\n-- User Config \"%s\"\n--\n\n", username
);
1387 for (int i
= 0; i
< PQntuples(res
); i
++)
1389 resetPQExpBuffer(buf
);
1390 makeAlterConfigCommand(conn
, PQgetvalue(res
, i
, 0),
1391 "ROLE", username
, NULL
, NULL
,
1393 fprintf(OPF
, "%s", buf
->data
);
1398 destroyPQExpBuffer(buf
);
1402 * Find a list of database names that match the given patterns.
1403 * See also expand_table_name_patterns() in pg_dump.c
1406 expand_dbname_patterns(PGconn
*conn
,
1407 SimpleStringList
*patterns
,
1408 SimpleStringList
*names
)
1413 if (patterns
->head
== NULL
)
1414 return; /* nothing to do */
1416 query
= createPQExpBuffer();
1419 * The loop below runs multiple SELECTs, which might sometimes result in
1420 * duplicate entries in the name list, but we don't care, since all we're
1421 * going to do is test membership of the list.
1424 for (SimpleStringListCell
*cell
= patterns
->head
; cell
; cell
= cell
->next
)
1428 appendPQExpBufferStr(query
,
1429 "SELECT datname FROM pg_catalog.pg_database n\n");
1430 processSQLNamePattern(conn
, query
, cell
->val
, false,
1431 false, NULL
, "datname", NULL
, NULL
, NULL
,
1436 pg_log_error("improper qualified name (too many dotted names): %s",
1442 res
= executeQuery(conn
, query
->data
);
1443 for (int i
= 0; i
< PQntuples(res
); i
++)
1445 simple_string_list_append(names
, PQgetvalue(res
, i
, 0));
1449 resetPQExpBuffer(query
);
1452 destroyPQExpBuffer(query
);
1456 * Dump contents of databases.
1459 dumpDatabases(PGconn
*conn
)
1465 * Skip databases marked not datallowconn, since we'd be unable to connect
1466 * to them anyway. This must agree with dropDBs().
1468 * We arrange for template1 to be processed first, then we process other
1469 * DBs in alphabetical order. If we just did them all alphabetically, we
1470 * might find ourselves trying to drop the "postgres" database while still
1471 * connected to it. This makes trying to run the restore script while
1472 * connected to "template1" a bad idea, but there's no fixed order that
1473 * doesn't have some failure mode with --clean.
1475 res
= executeQuery(conn
,
1477 "FROM pg_database d "
1478 "WHERE datallowconn "
1479 "ORDER BY (datname <> 'template1'), datname");
1481 if (PQntuples(res
) > 0)
1482 fprintf(OPF
, "--\n-- Databases\n--\n\n");
1484 for (i
= 0; i
< PQntuples(res
); i
++)
1486 char *dbname
= PQgetvalue(res
, i
, 0);
1487 const char *create_opts
;
1490 /* Skip template0, even if it's not marked !datallowconn. */
1491 if (strcmp(dbname
, "template0") == 0)
1494 /* Skip any explicitly excluded database */
1495 if (simple_string_list_member(&database_exclude_names
, dbname
))
1497 pg_log_info("excluding database \"%s\"", dbname
);
1501 pg_log_info("dumping database \"%s\"", dbname
);
1503 fprintf(OPF
, "--\n-- Database \"%s\" dump\n--\n\n", dbname
);
1506 * We assume that "template1" and "postgres" already exist in the
1507 * target installation. dropDBs() won't have removed them, for fear
1508 * of removing the DB the restore script is initially connected to. If
1509 * --clean was specified, tell pg_dump to drop and recreate them;
1510 * otherwise we'll merely restore their contents. Other databases
1511 * should simply be created.
1513 if (strcmp(dbname
, "template1") == 0 || strcmp(dbname
, "postgres") == 0)
1516 create_opts
= "--clean --create";
1520 /* Since pg_dump won't emit a \connect command, we must */
1521 fprintf(OPF
, "\\connect %s\n\n", dbname
);
1525 create_opts
= "--create";
1530 ret
= runPgDump(dbname
, create_opts
);
1532 pg_fatal("pg_dump failed on database \"%s\", exiting", dbname
);
1536 OPF
= fopen(filename
, PG_BINARY_A
);
1538 pg_fatal("could not re-open the output file \"%s\": %m",
1549 * Run pg_dump on dbname, with specified options.
1552 runPgDump(const char *dbname
, const char *create_opts
)
1554 PQExpBuffer connstrbuf
= createPQExpBuffer();
1555 PQExpBuffer cmd
= createPQExpBuffer();
1558 appendPQExpBuffer(cmd
, "\"%s\" %s %s", pg_dump_bin
,
1559 pgdumpopts
->data
, create_opts
);
1562 * If we have a filename, use the undocumented plain-append pg_dump
1566 appendPQExpBufferStr(cmd
, " -Fa ");
1568 appendPQExpBufferStr(cmd
, " -Fp ");
1571 * Append the database name to the already-constructed stem of connection
1574 appendPQExpBuffer(connstrbuf
, "%s dbname=", connstr
);
1575 appendConnStrVal(connstrbuf
, dbname
);
1577 appendShellString(cmd
, connstrbuf
->data
);
1579 pg_log_info("running \"%s\"", cmd
->data
);
1583 ret
= system(cmd
->data
);
1585 destroyPQExpBuffer(cmd
);
1586 destroyPQExpBuffer(connstrbuf
);
1594 * Build SECURITY LABEL command(s) for a shared object
1596 * The caller has to provide object type and identity in two separate formats:
1597 * catalog_name (e.g., "pg_database") and object OID, as well as
1598 * type name (e.g., "DATABASE") and object name (not pre-quoted).
1600 * The command(s) are appended to "buffer".
1603 buildShSecLabels(PGconn
*conn
, const char *catalog_name
, Oid objectId
,
1604 const char *objtype
, const char *objname
,
1607 PQExpBuffer sql
= createPQExpBuffer();
1610 buildShSecLabelQuery(catalog_name
, objectId
, sql
);
1611 res
= executeQuery(conn
, sql
->data
);
1612 emitShSecLabels(conn
, res
, buffer
, objtype
, objname
);
1615 destroyPQExpBuffer(sql
);
1619 * Make a database connection with the given parameters. An
1620 * interactive password prompt is automatically issued if required.
1622 * If fail_on_error is false, we return NULL without printing any message
1623 * on failure, but preserve any prompted password for the next try.
1625 * On success, the global variable 'connstr' is set to a connection string
1626 * containing the options used.
1629 connectDatabase(const char *dbname
, const char *connection_string
,
1630 const char *pghost
, const char *pgport
, const char *pguser
,
1631 trivalue prompt_password
, bool fail_on_error
)
1635 const char *remoteversion_str
;
1637 const char **keywords
= NULL
;
1638 const char **values
= NULL
;
1639 PQconninfoOption
*conn_opts
= NULL
;
1640 static char *password
= NULL
;
1642 if (prompt_password
== TRI_YES
&& !password
)
1643 password
= simple_prompt("Password: ", false);
1646 * Start the connection. Loop until we have a password if requested by
1652 PQconninfoOption
*conn_opt
;
1653 char *err_msg
= NULL
;
1658 PQconninfoFree(conn_opts
);
1661 * Merge the connection info inputs given in form of connection string
1662 * and other options. Explicitly discard any dbname value in the
1663 * connection string; otherwise, PQconnectdbParams() would interpret
1664 * that value as being itself a connection string.
1666 if (connection_string
)
1668 conn_opts
= PQconninfoParse(connection_string
, &err_msg
);
1669 if (conn_opts
== NULL
)
1670 pg_fatal("%s", err_msg
);
1672 for (conn_opt
= conn_opts
; conn_opt
->keyword
!= NULL
; conn_opt
++)
1674 if (conn_opt
->val
!= NULL
&& conn_opt
->val
[0] != '\0' &&
1675 strcmp(conn_opt
->keyword
, "dbname") != 0)
1679 keywords
= pg_malloc0((argcount
+ 1) * sizeof(*keywords
));
1680 values
= pg_malloc0((argcount
+ 1) * sizeof(*values
));
1682 for (conn_opt
= conn_opts
; conn_opt
->keyword
!= NULL
; conn_opt
++)
1684 if (conn_opt
->val
!= NULL
&& conn_opt
->val
[0] != '\0' &&
1685 strcmp(conn_opt
->keyword
, "dbname") != 0)
1687 keywords
[i
] = conn_opt
->keyword
;
1688 values
[i
] = conn_opt
->val
;
1695 keywords
= pg_malloc0((argcount
+ 1) * sizeof(*keywords
));
1696 values
= pg_malloc0((argcount
+ 1) * sizeof(*values
));
1701 keywords
[i
] = "host";
1707 keywords
[i
] = "port";
1713 keywords
[i
] = "user";
1719 keywords
[i
] = "password";
1720 values
[i
] = password
;
1725 keywords
[i
] = "dbname";
1729 keywords
[i
] = "fallback_application_name";
1730 values
[i
] = progname
;
1734 conn
= PQconnectdbParams(keywords
, values
, true);
1737 pg_fatal("could not connect to database \"%s\"", dbname
);
1739 if (PQstatus(conn
) == CONNECTION_BAD
&&
1740 PQconnectionNeedsPassword(conn
) &&
1742 prompt_password
!= TRI_NO
)
1745 password
= simple_prompt("Password: ", false);
1750 /* check to see that the backend connection was successfully made */
1751 if (PQstatus(conn
) == CONNECTION_BAD
)
1754 pg_fatal("%s", PQerrorMessage(conn
));
1761 PQconninfoFree(conn_opts
);
1768 * Ok, connected successfully. Remember the options used, in the form of a
1769 * connection string.
1771 connstr
= constructConnStr(keywords
, values
);
1775 PQconninfoFree(conn_opts
);
1778 remoteversion_str
= PQparameterStatus(conn
, "server_version");
1779 if (!remoteversion_str
)
1780 pg_fatal("could not get server version");
1781 server_version
= PQserverVersion(conn
);
1782 if (server_version
== 0)
1783 pg_fatal("could not parse server version \"%s\"",
1786 my_version
= PG_VERSION_NUM
;
1789 * We allow the server to be back to 9.2, and up to any minor release of
1790 * our own major version. (See also version check in pg_dump.c.)
1792 if (my_version
!= server_version
1793 && (server_version
< 90200 ||
1794 (server_version
/ 100) > (my_version
/ 100)))
1796 pg_log_error("aborting because of server version mismatch");
1797 pg_log_error_detail("server version: %s; %s version: %s",
1798 remoteversion_str
, progname
, PG_VERSION
);
1802 PQclear(executeQuery(conn
, ALWAYS_SECURE_SEARCH_PATH_SQL
));
1808 * Construct a connection string from the given keyword/value pairs. It is
1809 * used to pass the connection options to the pg_dump subprocess.
1811 * The following parameters are excluded:
1812 * dbname - varies in each pg_dump invocation
1813 * password - it's not secure to pass a password on the command line
1814 * fallback_application_name - we'll let pg_dump set it
1818 constructConnStr(const char **keywords
, const char **values
)
1820 PQExpBuffer buf
= createPQExpBuffer();
1823 bool firstkeyword
= true;
1825 /* Construct a new connection string in key='value' format. */
1826 for (i
= 0; keywords
[i
] != NULL
; i
++)
1828 if (strcmp(keywords
[i
], "dbname") == 0 ||
1829 strcmp(keywords
[i
], "password") == 0 ||
1830 strcmp(keywords
[i
], "fallback_application_name") == 0)
1834 appendPQExpBufferChar(buf
, ' ');
1835 firstkeyword
= false;
1836 appendPQExpBuffer(buf
, "%s=", keywords
[i
]);
1837 appendConnStrVal(buf
, values
[i
]);
1840 connstr
= pg_strdup(buf
->data
);
1841 destroyPQExpBuffer(buf
);
1846 * Run a query, return the results, exit program on failure.
1849 executeQuery(PGconn
*conn
, const char *query
)
1853 pg_log_info("executing %s", query
);
1855 res
= PQexec(conn
, query
);
1857 PQresultStatus(res
) != PGRES_TUPLES_OK
)
1859 pg_log_error("query failed: %s", PQerrorMessage(conn
));
1860 pg_log_error_detail("Query was: %s", query
);
1869 * As above for a SQL command (which returns nothing).
1872 executeCommand(PGconn
*conn
, const char *query
)
1876 pg_log_info("executing %s", query
);
1878 res
= PQexec(conn
, query
);
1880 PQresultStatus(res
) != PGRES_COMMAND_OK
)
1882 pg_log_error("query failed: %s", PQerrorMessage(conn
));
1883 pg_log_error_detail("Query was: %s", query
);
1896 dumpTimestamp(const char *msg
)
1899 time_t now
= time(NULL
);
1901 if (strftime(buf
, sizeof(buf
), PGDUMP_STRFTIME_FMT
, localtime(&now
)) != 0)
1902 fprintf(OPF
, "-- %s %s\n\n", msg
, buf
);
1906 * Helper function for rolenamehash hash table.
1909 hash_string_pointer(char *s
)
1911 unsigned char *ss
= (unsigned char *) s
;
1913 return hash_bytes(ss
, strlen(s
));