1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2009, 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 #include "dumputils.h"
26 #include "pg_backup.h"
28 /* version string we expect back from pg_dump */
29 #define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
32 static const char *progname
;
34 static void help(void);
36 static void dropRoles(PGconn
*conn
);
37 static void dumpRoles(PGconn
*conn
);
38 static void dumpRoleMembership(PGconn
*conn
);
39 static void dumpGroups(PGconn
*conn
);
40 static void dropTablespaces(PGconn
*conn
);
41 static void dumpTablespaces(PGconn
*conn
);
42 static void dropDBs(PGconn
*conn
);
43 static void dumpCreateDB(PGconn
*conn
);
44 static void dumpDatabaseConfig(PGconn
*conn
, const char *dbname
);
45 static void dumpUserConfig(PGconn
*conn
, const char *username
);
46 static void makeAlterConfigCommand(PGconn
*conn
, const char *arrayitem
,
47 const char *type
, const char *name
);
48 static void dumpDatabases(PGconn
*conn
);
49 static void dumpTimestamp(char *msg
);
50 static void doShellQuoting(PQExpBuffer buf
, const char *str
);
52 static int runPgDump(const char *dbname
);
53 static PGconn
*connectDatabase(const char *dbname
, const char *pghost
, const char *pgport
,
54 const char *pguser
, enum trivalue prompt_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 skip_acls
= false;
61 static bool verbose
= false;
63 static int binary_upgrade
= 0;
64 static int column_inserts
= 0;
65 static int disable_dollar_quoting
= 0;
66 static int disable_triggers
= 0;
67 static int inserts
= 0;
68 static int no_tablespaces
= 0;
69 static int use_setsessauth
= 0;
70 static int server_version
;
73 static char *filename
= NULL
;
77 main(int argc
, char *argv
[])
83 char *use_role
= NULL
;
84 enum trivalue prompt_password
= TRI_DEFAULT
;
85 bool data_only
= false;
86 bool globals_only
= false;
87 bool output_clean
= false;
88 bool roles_only
= false;
89 bool tablespaces_only
= false;
90 bool schema_only
= false;
93 const char *std_strings
;
98 static struct option long_options
[] = {
99 {"data-only", no_argument
, NULL
, 'a'},
100 {"clean", no_argument
, NULL
, 'c'},
101 {"file", required_argument
, NULL
, 'f'},
102 {"globals-only", no_argument
, NULL
, 'g'},
103 {"host", required_argument
, NULL
, 'h'},
104 {"ignore-version", no_argument
, NULL
, 'i'},
105 {"database", required_argument
, NULL
, 'l'},
106 {"oids", no_argument
, NULL
, 'o'},
107 {"no-owner", no_argument
, NULL
, 'O'},
108 {"port", required_argument
, NULL
, 'p'},
109 {"roles-only", no_argument
, NULL
, 'r'},
110 {"schema-only", no_argument
, NULL
, 's'},
111 {"superuser", required_argument
, NULL
, 'S'},
112 {"tablespaces-only", no_argument
, NULL
, 't'},
113 {"username", required_argument
, NULL
, 'U'},
114 {"verbose", no_argument
, NULL
, 'v'},
115 {"no-password", no_argument
, NULL
, 'w'},
116 {"password", no_argument
, NULL
, 'W'},
117 {"no-privileges", no_argument
, NULL
, 'x'},
118 {"no-acl", no_argument
, NULL
, 'x'},
121 * the following options don't have an equivalent short option letter
123 {"attribute-inserts", no_argument
, &column_inserts
, 1},
124 {"binary-upgrade", no_argument
, &binary_upgrade
, 1},
125 {"column-inserts", no_argument
, &column_inserts
, 1},
126 {"disable-dollar-quoting", no_argument
, &disable_dollar_quoting
, 1},
127 {"disable-triggers", no_argument
, &disable_triggers
, 1},
128 {"inserts", no_argument
, &inserts
, 1},
129 {"lock-wait-timeout", required_argument
, NULL
, 2},
130 {"no-tablespaces", no_argument
, &no_tablespaces
, 1},
131 {"role", required_argument
, NULL
, 3},
132 {"use-set-session-authorization", no_argument
, &use_setsessauth
, 1},
137 set_pglocale_pgservice(argv
[0], PG_TEXTDOMAIN("pg_dump"));
139 progname
= get_progname(argv
[0]);
143 if (strcmp(argv
[1], "--help") == 0 || strcmp(argv
[1], "-?") == 0)
148 if (strcmp(argv
[1], "--version") == 0 || strcmp(argv
[1], "-V") == 0)
150 puts("pg_dumpall (PostgreSQL) " PG_VERSION
);
155 if ((ret
= find_other_exec(argv
[0], "pg_dump", PGDUMP_VERSIONSTR
,
158 char full_path
[MAXPGPATH
];
160 if (find_my_exec(argv
[0], full_path
) < 0)
161 strlcpy(full_path
, progname
, sizeof(full_path
));
165 _("The program \"pg_dump\" is needed by %s "
166 "but was not found in the\n"
167 "same directory as \"%s\".\n"
168 "Check your installation.\n"),
169 progname
, full_path
);
172 _("The program \"pg_dump\" was found by \"%s\"\n"
173 "but was not the same version as %s.\n"
174 "Check your installation.\n"),
175 full_path
, progname
);
179 pgdumpopts
= createPQExpBuffer();
181 while ((c
= getopt_long(argc
, argv
, "acf:gh:il:oOp:rsS:tU:vwWxX:", long_options
, &optindex
)) != -1)
187 appendPQExpBuffer(pgdumpopts
, " -a");
196 appendPQExpBuffer(pgdumpopts
, " -f ");
197 doShellQuoting(pgdumpopts
, filename
);
206 appendPQExpBuffer(pgdumpopts
, " -h ");
207 doShellQuoting(pgdumpopts
, pghost
);
211 /* ignored, deprecated option */
219 appendPQExpBuffer(pgdumpopts
, " -o");
223 appendPQExpBuffer(pgdumpopts
, " -O");
228 appendPQExpBuffer(pgdumpopts
, " -p ");
229 doShellQuoting(pgdumpopts
, pgport
);
238 appendPQExpBuffer(pgdumpopts
, " -s");
242 appendPQExpBuffer(pgdumpopts
, " -S ");
243 doShellQuoting(pgdumpopts
, optarg
);
247 tablespaces_only
= true;
252 appendPQExpBuffer(pgdumpopts
, " -U ");
253 doShellQuoting(pgdumpopts
, pguser
);
258 appendPQExpBuffer(pgdumpopts
, " -v");
262 prompt_password
= TRI_NO
;
263 appendPQExpBuffer(pgdumpopts
, " -w");
267 prompt_password
= TRI_YES
;
268 appendPQExpBuffer(pgdumpopts
, " -W");
273 appendPQExpBuffer(pgdumpopts
, " -x");
277 /* -X is a deprecated alternative to long options */
278 if (strcmp(optarg
, "disable-dollar-quoting") == 0)
279 disable_dollar_quoting
= 1;
280 else if (strcmp(optarg
, "disable-triggers") == 0)
281 disable_triggers
= 1;
282 else if (strcmp(optarg
, "no-tablespaces") == 0)
284 else if (strcmp(optarg
, "use-set-session-authorization") == 0)
289 _("%s: invalid -X option -- %s\n"),
291 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"), progname
);
300 appendPQExpBuffer(pgdumpopts
, " --lock-wait-timeout ");
301 doShellQuoting(pgdumpopts
, optarg
);
306 appendPQExpBuffer(pgdumpopts
, " --role ");
307 doShellQuoting(pgdumpopts
, use_role
);
311 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"), progname
);
316 /* Add long options to the pg_dump argument list */
318 appendPQExpBuffer(pgdumpopts
, " --binary-upgrade");
320 appendPQExpBuffer(pgdumpopts
, " --column-inserts");
321 if (disable_dollar_quoting
)
322 appendPQExpBuffer(pgdumpopts
, " --disable-dollar-quoting");
323 if (disable_triggers
)
324 appendPQExpBuffer(pgdumpopts
, " --disable-triggers");
326 appendPQExpBuffer(pgdumpopts
, " --inserts");
328 appendPQExpBuffer(pgdumpopts
, " --no-tablespaces");
330 appendPQExpBuffer(pgdumpopts
, " --use-set-session-authorization");
334 fprintf(stderr
, _("%s: too many command-line arguments (first is \"%s\")\n"),
335 progname
, argv
[optind
]);
336 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
341 /* Make sure the user hasn't specified a mix of globals-only options */
342 if (globals_only
&& roles_only
)
344 fprintf(stderr
, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"),
346 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
351 if (globals_only
&& tablespaces_only
)
353 fprintf(stderr
, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"),
355 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
360 if (roles_only
&& tablespaces_only
)
362 fprintf(stderr
, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"),
364 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
370 * If there was a database specified on the command line, use that,
371 * otherwise try to connect to database "postgres", and failing that
372 * "template1". "postgres" is the preferred choice for 8.1 and later
373 * servers, but it usually will not exist on older ones.
377 conn
= connectDatabase(pgdb
, pghost
, pgport
, pguser
,
378 prompt_password
, false);
382 fprintf(stderr
, _("%s: could not connect to database \"%s\"\n"),
389 conn
= connectDatabase("postgres", pghost
, pgport
, pguser
,
390 prompt_password
, false);
392 conn
= connectDatabase("template1", pghost
, pgport
, pguser
,
393 prompt_password
, true);
397 fprintf(stderr
, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
398 "Please specify an alternative database.\n"),
400 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
407 * Open the output file if required, otherwise use stdout
411 OPF
= fopen(filename
, PG_BINARY_W
);
414 fprintf(stderr
, _("%s: could not open the output file \"%s\": %s\n"),
415 progname
, filename
, strerror(errno
));
423 * Get the active encoding and the standard_conforming_strings setting, so
424 * we know how to escape strings.
426 encoding
= PQclientEncoding(conn
);
427 std_strings
= PQparameterStatus(conn
, "standard_conforming_strings");
431 /* Set the role if requested */
432 if (use_role
&& server_version
>= 80100)
434 PQExpBuffer query
= createPQExpBuffer();
436 appendPQExpBuffer(query
, "SET ROLE %s", fmtId(use_role
));
437 executeCommand(conn
, query
->data
);
438 destroyPQExpBuffer(query
);
441 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump\n--\n\n");
443 dumpTimestamp("Started on");
445 fprintf(OPF
, "\\connect postgres\n\n");
447 /* Replicate encoding and std_strings in output */
448 fprintf(OPF
, "SET client_encoding = '%s';\n",
449 pg_encoding_to_char(encoding
));
450 fprintf(OPF
, "SET standard_conforming_strings = %s;\n", std_strings
);
451 if (strcmp(std_strings
, "off") == 0)
452 fprintf(OPF
, "SET escape_string_warning = off;\n");
458 * If asked to --clean, do that first. We can avoid detailed
459 * dependency analysis because databases never depend on each other,
460 * and tablespaces never depend on each other. Roles could have
461 * grants to each other, but DROP ROLE will clean those up silently.
465 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
468 if (!roles_only
&& !no_tablespaces
)
470 if (server_version
>= 80000)
471 dropTablespaces(conn
);
474 if (!tablespaces_only
)
479 * Now create objects as requested. Be careful that option logic here
480 * is the same as for drops above.
482 if (!tablespaces_only
)
484 /* Dump roles (users) */
487 /* Dump role memberships --- need different method for pre-8.1 */
488 if (server_version
>= 80100)
489 dumpRoleMembership(conn
);
494 if (!roles_only
&& !no_tablespaces
)
496 /* Dump tablespaces */
497 if (server_version
>= 80000)
498 dumpTablespaces(conn
);
501 /* Dump CREATE DATABASE commands */
502 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
506 if (!globals_only
&& !roles_only
&& !tablespaces_only
)
512 dumpTimestamp("Completed on");
513 fprintf(OPF
, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
525 printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname
);
526 printf(_("Usage:\n"));
527 printf(_(" %s [OPTION]...\n"), progname
);
529 printf(_("\nGeneral options:\n"));
530 printf(_(" -f, --file=FILENAME output file name\n"));
531 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
532 printf(_(" --help show this help, then exit\n"));
533 printf(_(" --version output version information, then exit\n"));
534 printf(_("\nOptions controlling the output content:\n"));
535 printf(_(" -a, --data-only dump only the data, not the schema\n"));
536 printf(_(" -c, --clean clean (drop) databases before recreating\n"));
537 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
538 printf(_(" -o, --oids include OIDs in dump\n"));
539 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
540 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
541 printf(_(" -s, --schema-only dump only the schema, no data\n"));
542 printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
543 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
544 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
545 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
546 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
547 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
548 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
549 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
550 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
551 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
552 printf(_(" --use-set-session-authorization\n"
553 " use SET SESSION AUTHORIZATION commands instead of\n"
554 " ALTER OWNER commands to set ownership\n"));
556 printf(_("\nConnection options:\n"));
557 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
558 printf(_(" -l, --database=DBNAME alternative default database\n"));
559 printf(_(" -p, --port=PORT database server port number\n"));
560 printf(_(" -U, --username=NAME connect as specified database user\n"));
561 printf(_(" -w, --no-password never prompt for password\n"));
562 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
564 printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
566 printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
574 dropRoles(PGconn
*conn
)
580 if (server_version
>= 80100)
581 res
= executeQuery(conn
,
586 res
= executeQuery(conn
,
587 "SELECT usename as rolname "
590 "SELECT groname as rolname "
594 i_rolname
= PQfnumber(res
, "rolname");
596 if (PQntuples(res
) > 0)
597 fprintf(OPF
, "--\n-- Drop roles\n--\n\n");
599 for (i
= 0; i
< PQntuples(res
); i
++)
601 const char *rolename
;
603 rolename
= PQgetvalue(res
, i
, i_rolname
);
605 fprintf(OPF
, "DROP ROLE %s;\n", fmtId(rolename
));
610 fprintf(OPF
, "\n\n");
617 dumpRoles(PGconn
*conn
)
619 PQExpBuffer buf
= createPQExpBuffer();
634 /* note: rolconfig is dumped later */
635 if (server_version
>= 80200)
636 printfPQExpBuffer(buf
,
637 "SELECT rolname, rolsuper, rolinherit, "
638 "rolcreaterole, rolcreatedb, rolcatupdate, "
639 "rolcanlogin, rolconnlimit, rolpassword, "
641 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
644 else if (server_version
>= 80100)
645 printfPQExpBuffer(buf
,
646 "SELECT rolname, rolsuper, rolinherit, "
647 "rolcreaterole, rolcreatedb, rolcatupdate, "
648 "rolcanlogin, rolconnlimit, rolpassword, "
649 "rolvaliduntil, null as rolcomment "
653 printfPQExpBuffer(buf
,
654 "SELECT usename as rolname, "
655 "usesuper as rolsuper, "
656 "true as rolinherit, "
657 "usesuper as rolcreaterole, "
658 "usecreatedb as rolcreatedb, "
659 "usecatupd as rolcatupdate, "
660 "true as rolcanlogin, "
661 "-1 as rolconnlimit, "
662 "passwd as rolpassword, "
663 "valuntil as rolvaliduntil, "
664 "null as rolcomment "
667 "SELECT groname as rolname, "
668 "false as rolsuper, "
669 "true as rolinherit, "
670 "false as rolcreaterole, "
671 "false as rolcreatedb, "
672 "false as rolcatupdate, "
673 "false as rolcanlogin, "
674 "-1 as rolconnlimit, "
675 "null::text as rolpassword, "
676 "null::abstime as rolvaliduntil, "
677 "null as rolcomment "
679 "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
680 " WHERE usename = groname) "
683 res
= executeQuery(conn
, buf
->data
);
685 i_rolname
= PQfnumber(res
, "rolname");
686 i_rolsuper
= PQfnumber(res
, "rolsuper");
687 i_rolinherit
= PQfnumber(res
, "rolinherit");
688 i_rolcreaterole
= PQfnumber(res
, "rolcreaterole");
689 i_rolcreatedb
= PQfnumber(res
, "rolcreatedb");
690 i_rolcatupdate
= PQfnumber(res
, "rolcatupdate");
691 i_rolcanlogin
= PQfnumber(res
, "rolcanlogin");
692 i_rolconnlimit
= PQfnumber(res
, "rolconnlimit");
693 i_rolpassword
= PQfnumber(res
, "rolpassword");
694 i_rolvaliduntil
= PQfnumber(res
, "rolvaliduntil");
695 i_rolcomment
= PQfnumber(res
, "rolcomment");
697 if (PQntuples(res
) > 0)
698 fprintf(OPF
, "--\n-- Roles\n--\n\n");
700 for (i
= 0; i
< PQntuples(res
); i
++)
702 const char *rolename
;
704 rolename
= PQgetvalue(res
, i
, i_rolname
);
706 resetPQExpBuffer(buf
);
709 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
710 * will acquire the right properties even if it already exists (ie, it
711 * won't hurt for the CREATE to fail). This is particularly important
712 * for the role we are connected as, since even with --clean we will
713 * have failed to drop it.
715 appendPQExpBuffer(buf
, "CREATE ROLE %s;\n", fmtId(rolename
));
716 appendPQExpBuffer(buf
, "ALTER ROLE %s WITH", fmtId(rolename
));
718 if (strcmp(PQgetvalue(res
, i
, i_rolsuper
), "t") == 0)
719 appendPQExpBuffer(buf
, " SUPERUSER");
721 appendPQExpBuffer(buf
, " NOSUPERUSER");
723 if (strcmp(PQgetvalue(res
, i
, i_rolinherit
), "t") == 0)
724 appendPQExpBuffer(buf
, " INHERIT");
726 appendPQExpBuffer(buf
, " NOINHERIT");
728 if (strcmp(PQgetvalue(res
, i
, i_rolcreaterole
), "t") == 0)
729 appendPQExpBuffer(buf
, " CREATEROLE");
731 appendPQExpBuffer(buf
, " NOCREATEROLE");
733 if (strcmp(PQgetvalue(res
, i
, i_rolcreatedb
), "t") == 0)
734 appendPQExpBuffer(buf
, " CREATEDB");
736 appendPQExpBuffer(buf
, " NOCREATEDB");
738 if (strcmp(PQgetvalue(res
, i
, i_rolcanlogin
), "t") == 0)
739 appendPQExpBuffer(buf
, " LOGIN");
741 appendPQExpBuffer(buf
, " NOLOGIN");
743 if (strcmp(PQgetvalue(res
, i
, i_rolconnlimit
), "-1") != 0)
744 appendPQExpBuffer(buf
, " CONNECTION LIMIT %s",
745 PQgetvalue(res
, i
, i_rolconnlimit
));
747 if (!PQgetisnull(res
, i
, i_rolpassword
))
749 appendPQExpBuffer(buf
, " PASSWORD ");
750 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolpassword
), conn
);
753 if (!PQgetisnull(res
, i
, i_rolvaliduntil
))
754 appendPQExpBuffer(buf
, " VALID UNTIL '%s'",
755 PQgetvalue(res
, i
, i_rolvaliduntil
));
757 appendPQExpBuffer(buf
, ";\n");
759 if (!PQgetisnull(res
, i
, i_rolcomment
))
761 appendPQExpBuffer(buf
, "COMMENT ON ROLE %s IS ", fmtId(rolename
));
762 appendStringLiteralConn(buf
, PQgetvalue(res
, i
, i_rolcomment
), conn
);
763 appendPQExpBuffer(buf
, ";\n");
766 fprintf(OPF
, "%s", buf
->data
);
768 if (server_version
>= 70300)
769 dumpUserConfig(conn
, rolename
);
774 fprintf(OPF
, "\n\n");
776 destroyPQExpBuffer(buf
);
781 * Dump role memberships. This code is used for 8.1 and later servers.
783 * Note: we expect dumpRoles already created all the roles, but there is
787 dumpRoleMembership(PGconn
*conn
)
792 res
= executeQuery(conn
, "SELECT ur.rolname AS roleid, "
793 "um.rolname AS member, "
795 "ug.rolname AS grantor "
796 "FROM pg_auth_members a "
797 "LEFT JOIN pg_authid ur on ur.oid = a.roleid "
798 "LEFT JOIN pg_authid um on um.oid = a.member "
799 "LEFT JOIN pg_authid ug on ug.oid = a.grantor "
802 if (PQntuples(res
) > 0)
803 fprintf(OPF
, "--\n-- Role memberships\n--\n\n");
805 for (i
= 0; i
< PQntuples(res
); i
++)
807 char *roleid
= PQgetvalue(res
, i
, 0);
808 char *member
= PQgetvalue(res
, i
, 1);
809 char *option
= PQgetvalue(res
, i
, 2);
811 fprintf(OPF
, "GRANT %s", fmtId(roleid
));
812 fprintf(OPF
, " TO %s", fmtId(member
));
814 fprintf(OPF
, " WITH ADMIN OPTION");
817 * We don't track the grantor very carefully in the backend, so cope
818 * with the possibility that it has been dropped.
820 if (!PQgetisnull(res
, i
, 3))
822 char *grantor
= PQgetvalue(res
, i
, 3);
824 fprintf(OPF
, " GRANTED BY %s", fmtId(grantor
));
831 fprintf(OPF
, "\n\n");
835 * Dump group memberships from a pre-8.1 server. It's annoying that we
836 * can't share any useful amount of code with the post-8.1 case, but
837 * the catalog representations are too different.
839 * Note: we expect dumpRoles already created all the roles, but there is
843 dumpGroups(PGconn
*conn
)
845 PQExpBuffer buf
= createPQExpBuffer();
849 res
= executeQuery(conn
,
850 "SELECT groname, grolist FROM pg_group ORDER BY 1");
852 if (PQntuples(res
) > 0)
853 fprintf(OPF
, "--\n-- Role memberships\n--\n\n");
855 for (i
= 0; i
< PQntuples(res
); i
++)
857 char *groname
= PQgetvalue(res
, i
, 0);
858 char *grolist
= PQgetvalue(res
, i
, 1);
863 * Array representation is {1,2,3} ... convert to (1,2,3)
865 if (strlen(grolist
) < 3)
868 grolist
= strdup(grolist
);
870 grolist
[strlen(grolist
) - 1] = ')';
871 printfPQExpBuffer(buf
,
872 "SELECT usename FROM pg_shadow "
873 "WHERE usesysid IN %s ORDER BY 1",
877 res2
= executeQuery(conn
, buf
->data
);
879 for (j
= 0; j
< PQntuples(res2
); j
++)
881 char *usename
= PQgetvalue(res2
, j
, 0);
884 * Don't try to grant a role to itself; can happen if old
885 * installation has identically named user and group.
887 if (strcmp(groname
, usename
) == 0)
890 fprintf(OPF
, "GRANT %s", fmtId(groname
));
891 fprintf(OPF
, " TO %s;\n", fmtId(usename
));
898 destroyPQExpBuffer(buf
);
900 fprintf(OPF
, "\n\n");
908 dropTablespaces(PGconn
*conn
)
914 * Get all tablespaces except built-in ones (which we assume are named
917 res
= executeQuery(conn
, "SELECT spcname "
918 "FROM pg_catalog.pg_tablespace "
919 "WHERE spcname !~ '^pg_' "
922 if (PQntuples(res
) > 0)
923 fprintf(OPF
, "--\n-- Drop tablespaces\n--\n\n");
925 for (i
= 0; i
< PQntuples(res
); i
++)
927 char *spcname
= PQgetvalue(res
, i
, 0);
929 fprintf(OPF
, "DROP TABLESPACE %s;\n", fmtId(spcname
));
934 fprintf(OPF
, "\n\n");
941 dumpTablespaces(PGconn
*conn
)
947 * Get all tablespaces except built-in ones (which we assume are named
950 if (server_version
>= 80200)
951 res
= executeQuery(conn
, "SELECT spcname, "
952 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
953 "spclocation, spcacl, "
954 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
955 "FROM pg_catalog.pg_tablespace "
956 "WHERE spcname !~ '^pg_' "
959 res
= executeQuery(conn
, "SELECT spcname, "
960 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
961 "spclocation, spcacl, "
963 "FROM pg_catalog.pg_tablespace "
964 "WHERE spcname !~ '^pg_' "
967 if (PQntuples(res
) > 0)
968 fprintf(OPF
, "--\n-- Tablespaces\n--\n\n");
970 for (i
= 0; i
< PQntuples(res
); i
++)
972 PQExpBuffer buf
= createPQExpBuffer();
973 char *spcname
= PQgetvalue(res
, i
, 0);
974 char *spcowner
= PQgetvalue(res
, i
, 1);
975 char *spclocation
= PQgetvalue(res
, i
, 2);
976 char *spcacl
= PQgetvalue(res
, i
, 3);
977 char *spccomment
= PQgetvalue(res
, i
, 4);
980 /* needed for buildACLCommands() */
981 fspcname
= strdup(fmtId(spcname
));
983 appendPQExpBuffer(buf
, "CREATE TABLESPACE %s", fspcname
);
984 appendPQExpBuffer(buf
, " OWNER %s", fmtId(spcowner
));
986 appendPQExpBuffer(buf
, " LOCATION ");
987 appendStringLiteralConn(buf
, spclocation
, conn
);
988 appendPQExpBuffer(buf
, ";\n");
991 !buildACLCommands(fspcname
, NULL
, "TABLESPACE", spcacl
, spcowner
,
992 server_version
, buf
))
994 fprintf(stderr
, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"),
995 progname
, spcacl
, fspcname
);
1000 if (spccomment
&& strlen(spccomment
))
1002 appendPQExpBuffer(buf
, "COMMENT ON TABLESPACE %s IS ", fspcname
);
1003 appendStringLiteralConn(buf
, spccomment
, conn
);
1004 appendPQExpBuffer(buf
, ";\n");
1007 fprintf(OPF
, "%s", buf
->data
);
1010 destroyPQExpBuffer(buf
);
1014 fprintf(OPF
, "\n\n");
1019 * Dump commands to drop each database.
1021 * This should match the set of databases targeted by dumpCreateDB().
1024 dropDBs(PGconn
*conn
)
1029 if (server_version
>= 70100)
1030 res
= executeQuery(conn
,
1032 "FROM pg_database d "
1033 "WHERE datallowconn ORDER BY 1");
1035 res
= executeQuery(conn
,
1037 "FROM pg_database d "
1040 if (PQntuples(res
) > 0)
1041 fprintf(OPF
, "--\n-- Drop databases\n--\n\n");
1043 for (i
= 0; i
< PQntuples(res
); i
++)
1045 char *dbname
= PQgetvalue(res
, i
, 0);
1048 * Skip "template1" and "postgres"; the restore script is almost
1049 * certainly going to be run in one or the other, and we don't know
1050 * which. This must agree with dumpCreateDB's choices!
1052 if (strcmp(dbname
, "template1") != 0 &&
1053 strcmp(dbname
, "postgres") != 0)
1055 fprintf(OPF
, "DROP DATABASE %s;\n", fmtId(dbname
));
1061 fprintf(OPF
, "\n\n");
1065 * Dump commands to create each database.
1067 * To minimize the number of reconnections (and possibly ensuing
1068 * password prompts) required by the output script, we emit all CREATE
1069 * DATABASE commands during the initial phase of the script, and then
1070 * run pg_dump for each database to dump the contents of that
1071 * database. We skip databases marked not datallowconn, since we'd be
1072 * unable to connect to them anyway (and besides, we don't want to
1076 dumpCreateDB(PGconn
*conn
)
1078 PQExpBuffer buf
= createPQExpBuffer();
1079 char *default_encoding
= NULL
;
1080 char *default_collate
= NULL
;
1081 char *default_ctype
= NULL
;
1085 fprintf(OPF
, "--\n-- Database creation\n--\n\n");
1088 * First, get the installation's default encoding and locale information.
1089 * We will dump encoding and locale specifications in the CREATE DATABASE
1090 * commands for just those databases with values different from defaults.
1092 * We consider template0's encoding and locale (or, pre-7.1, template1's)
1093 * to define the installation default. Pre-8.4 installations do not have
1094 * per-database locale settings; for them, every database must necessarily
1095 * be using the installation default, so there's no need to do anything
1096 * (which is good, since in very old versions there is no good way to find
1097 * out what the installation locale is anyway...)
1099 if (server_version
>= 80400)
1100 res
= executeQuery(conn
,
1101 "SELECT pg_encoding_to_char(encoding), "
1102 "datcollate, datctype "
1104 "WHERE datname = 'template0'");
1105 else if (server_version
>= 70100)
1106 res
= executeQuery(conn
,
1107 "SELECT pg_encoding_to_char(encoding), "
1108 "null::text AS datcollate, null::text AS datctype "
1110 "WHERE datname = 'template0'");
1112 res
= executeQuery(conn
,
1113 "SELECT pg_encoding_to_char(encoding), "
1114 "null::text AS datcollate, null::text AS datctype "
1116 "WHERE datname = 'template1'");
1118 /* If for some reason the template DB isn't there, treat as unknown */
1119 if (PQntuples(res
) > 0)
1121 if (!PQgetisnull(res
, 0, 0))
1122 default_encoding
= strdup(PQgetvalue(res
, 0, 0));
1123 if (!PQgetisnull(res
, 0, 1))
1124 default_collate
= strdup(PQgetvalue(res
, 0, 1));
1125 if (!PQgetisnull(res
, 0, 2))
1126 default_ctype
= strdup(PQgetvalue(res
, 0, 2));
1131 /* Now collect all the information about databases to dump */
1132 if (server_version
>= 80400)
1133 res
= executeQuery(conn
,
1135 "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1136 "pg_encoding_to_char(d.encoding), "
1137 "datcollate, datctype, datfrozenxid, "
1138 "datistemplate, datacl, datconnlimit, "
1139 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1140 "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1141 "WHERE datallowconn ORDER BY 1");
1142 else if (server_version
>= 80100)
1143 res
= executeQuery(conn
,
1145 "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1146 "pg_encoding_to_char(d.encoding), "
1147 "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
1148 "datistemplate, datacl, datconnlimit, "
1149 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1150 "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1151 "WHERE datallowconn ORDER BY 1");
1152 else if (server_version
>= 80000)
1153 res
= executeQuery(conn
,
1155 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1156 "pg_encoding_to_char(d.encoding), "
1157 "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
1158 "datistemplate, datacl, -1 as datconnlimit, "
1159 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1160 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
1161 "WHERE datallowconn ORDER BY 1");
1162 else if (server_version
>= 70300)
1163 res
= executeQuery(conn
,
1165 "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1166 "pg_encoding_to_char(d.encoding), "
1167 "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
1168 "datistemplate, datacl, -1 as datconnlimit, "
1169 "'pg_default' AS dattablespace "
1170 "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
1171 "WHERE datallowconn ORDER BY 1");
1172 else if (server_version
>= 70100)
1173 res
= executeQuery(conn
,
1176 "(select usename from pg_shadow where usesysid=datdba), "
1177 "(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1178 "pg_encoding_to_char(d.encoding), "
1179 "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, "
1180 "datistemplate, '' as datacl, -1 as datconnlimit, "
1181 "'pg_default' AS dattablespace "
1182 "FROM pg_database d "
1183 "WHERE datallowconn ORDER BY 1");
1187 * Note: 7.0 fails to cope with sub-select in COALESCE, so just deal
1188 * with getting a NULL by not printing any OWNER clause.
1190 res
= executeQuery(conn
,
1192 "(select usename from pg_shadow where usesysid=datdba), "
1193 "pg_encoding_to_char(d.encoding), "
1194 "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, "
1195 "'f' as datistemplate, "
1196 "'' as datacl, -1 as datconnlimit, "
1197 "'pg_default' AS dattablespace "
1198 "FROM pg_database d "
1202 for (i
= 0; i
< PQntuples(res
); i
++)
1204 char *dbname
= PQgetvalue(res
, i
, 0);
1205 char *dbowner
= PQgetvalue(res
, i
, 1);
1206 char *dbencoding
= PQgetvalue(res
, i
, 2);
1207 char *dbcollate
= PQgetvalue(res
, i
, 3);
1208 char *dbctype
= PQgetvalue(res
, i
, 4);
1209 uint32 dbfrozenxid
= atooid(PQgetvalue(res
, i
, 5));
1210 char *dbistemplate
= PQgetvalue(res
, i
, 6);
1211 char *dbacl
= PQgetvalue(res
, i
, 7);
1212 char *dbconnlimit
= PQgetvalue(res
, i
, 8);
1213 char *dbtablespace
= PQgetvalue(res
, i
, 9);
1216 fdbname
= strdup(fmtId(dbname
));
1218 resetPQExpBuffer(buf
);
1221 * Skip the CREATE DATABASE commands for "template1" and "postgres",
1222 * since they are presumably already there in the destination cluster.
1223 * We do want to emit their ACLs and config options if any, however.
1225 if (strcmp(dbname
, "template1") != 0 &&
1226 strcmp(dbname
, "postgres") != 0)
1228 appendPQExpBuffer(buf
, "CREATE DATABASE %s", fdbname
);
1230 appendPQExpBuffer(buf
, " WITH TEMPLATE = template0");
1232 if (strlen(dbowner
) != 0)
1233 appendPQExpBuffer(buf
, " OWNER = %s", fmtId(dbowner
));
1235 if (default_encoding
&& strcmp(dbencoding
, default_encoding
) != 0)
1237 appendPQExpBuffer(buf
, " ENCODING = ");
1238 appendStringLiteralConn(buf
, dbencoding
, conn
);
1241 if (default_collate
&& strcmp(dbcollate
, default_collate
) != 0)
1243 appendPQExpBuffer(buf
, " LC_COLLATE = ");
1244 appendStringLiteralConn(buf
, dbcollate
, conn
);
1247 if (default_ctype
&& strcmp(dbctype
, default_ctype
) != 0)
1249 appendPQExpBuffer(buf
, " LC_CTYPE = ");
1250 appendStringLiteralConn(buf
, dbctype
, conn
);
1254 * Output tablespace if it isn't the default. For default, it
1255 * uses the default from the template database. If tablespace is
1256 * specified and tablespace creation failed earlier, (e.g. no such
1257 * directory), the database creation will fail too. One solution
1258 * would be to use 'SET default_tablespace' like we do in pg_dump
1259 * for setting non-default database locations.
1261 if (strcmp(dbtablespace
, "pg_default") != 0 && !no_tablespaces
)
1262 appendPQExpBuffer(buf
, " TABLESPACE = %s",
1263 fmtId(dbtablespace
));
1265 if (strcmp(dbconnlimit
, "-1") != 0)
1266 appendPQExpBuffer(buf
, " CONNECTION LIMIT = %s",
1269 appendPQExpBuffer(buf
, ";\n");
1271 if (strcmp(dbistemplate
, "t") == 0)
1273 appendPQExpBuffer(buf
, "UPDATE pg_catalog.pg_database SET datistemplate = 't' WHERE datname = ");
1274 appendStringLiteralConn(buf
, dbname
, conn
);
1275 appendPQExpBuffer(buf
, ";\n");
1280 appendPQExpBuffer(buf
, "-- For binary upgrade, set datfrozenxid.\n");
1281 appendPQExpBuffer(buf
, "UPDATE pg_catalog.pg_database "
1282 "SET datfrozenxid = '%u' "
1285 appendStringLiteralConn(buf
, dbname
, conn
);
1286 appendPQExpBuffer(buf
, ";\n");
1291 !buildACLCommands(fdbname
, NULL
, "DATABASE", dbacl
, dbowner
,
1292 server_version
, buf
))
1294 fprintf(stderr
, _("%s: could not parse ACL list (%s) for database \"%s\"\n"),
1295 progname
, dbacl
, fdbname
);
1300 fprintf(OPF
, "%s", buf
->data
);
1302 if (server_version
>= 70300)
1303 dumpDatabaseConfig(conn
, dbname
);
1309 destroyPQExpBuffer(buf
);
1311 fprintf(OPF
, "\n\n");
1316 * Dump database-specific configuration
1319 dumpDatabaseConfig(PGconn
*conn
, const char *dbname
)
1321 PQExpBuffer buf
= createPQExpBuffer();
1328 printfPQExpBuffer(buf
, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count
);
1329 appendStringLiteralConn(buf
, dbname
, conn
);
1330 appendPQExpBuffer(buf
, ";");
1332 res
= executeQuery(conn
, buf
->data
);
1333 if (!PQgetisnull(res
, 0, 0))
1335 makeAlterConfigCommand(conn
, PQgetvalue(res
, 0, 0),
1336 "DATABASE", dbname
);
1347 destroyPQExpBuffer(buf
);
1353 * Dump user-specific configuration
1356 dumpUserConfig(PGconn
*conn
, const char *username
)
1358 PQExpBuffer buf
= createPQExpBuffer();
1365 if (server_version
>= 80100)
1366 printfPQExpBuffer(buf
, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count
);
1368 printfPQExpBuffer(buf
, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count
);
1369 appendStringLiteralConn(buf
, username
, conn
);
1371 res
= executeQuery(conn
, buf
->data
);
1372 if (PQntuples(res
) == 1 &&
1373 !PQgetisnull(res
, 0, 0))
1375 makeAlterConfigCommand(conn
, PQgetvalue(res
, 0, 0),
1387 destroyPQExpBuffer(buf
);
1393 * Helper function for dumpXXXConfig().
1396 makeAlterConfigCommand(PGconn
*conn
, const char *arrayitem
,
1397 const char *type
, const char *name
)
1401 PQExpBuffer buf
= createPQExpBuffer();
1403 mine
= strdup(arrayitem
);
1404 pos
= strchr(mine
, '=');
1409 appendPQExpBuffer(buf
, "ALTER %s %s ", type
, fmtId(name
));
1410 appendPQExpBuffer(buf
, "SET %s TO ", fmtId(mine
));
1413 * Some GUC variable names are 'LIST' type and hence must not be quoted.
1415 if (pg_strcasecmp(mine
, "DateStyle") == 0
1416 || pg_strcasecmp(mine
, "search_path") == 0)
1417 appendPQExpBuffer(buf
, "%s", pos
+ 1);
1419 appendStringLiteralConn(buf
, pos
+ 1, conn
);
1420 appendPQExpBuffer(buf
, ";\n");
1422 fprintf(OPF
, "%s", buf
->data
);
1423 destroyPQExpBuffer(buf
);
1430 * Dump contents of databases.
1433 dumpDatabases(PGconn
*conn
)
1438 if (server_version
>= 70100)
1439 res
= executeQuery(conn
, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1");
1441 res
= executeQuery(conn
, "SELECT datname FROM pg_database ORDER BY 1");
1443 for (i
= 0; i
< PQntuples(res
); i
++)
1447 char *dbname
= PQgetvalue(res
, i
, 0);
1450 fprintf(stderr
, _("%s: dumping database \"%s\"...\n"), progname
, dbname
);
1452 fprintf(OPF
, "\\connect %s\n\n", fmtId(dbname
));
1457 ret
= runPgDump(dbname
);
1460 fprintf(stderr
, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname
, dbname
);
1466 OPF
= fopen(filename
, PG_BINARY_A
);
1469 fprintf(stderr
, _("%s: could not re-open the output file \"%s\": %s\n"),
1470 progname
, filename
, strerror(errno
));
1483 * Run pg_dump on dbname.
1486 runPgDump(const char *dbname
)
1488 PQExpBuffer cmd
= createPQExpBuffer();
1491 appendPQExpBuffer(cmd
, SYSTEMQUOTE
"\"%s\" %s", pg_dump_bin
,
1495 * If we have a filename, use the undocumented plain-append pg_dump
1499 appendPQExpBuffer(cmd
, " -Fa ");
1501 appendPQExpBuffer(cmd
, " -Fp ");
1503 doShellQuoting(cmd
, dbname
);
1505 appendPQExpBuffer(cmd
, "%s", SYSTEMQUOTE
);
1508 fprintf(stderr
, _("%s: running \"%s\"\n"), progname
, cmd
->data
);
1513 ret
= system(cmd
->data
);
1515 destroyPQExpBuffer(cmd
);
1522 * Make a database connection with the given parameters. An
1523 * interactive password prompt is automatically issued if required.
1525 * If fail_on_error is false, we return NULL without printing any message
1526 * on failure, but preserve any prompted password for the next try.
1529 connectDatabase(const char *dbname
, const char *pghost
, const char *pgport
,
1530 const char *pguser
, enum trivalue prompt_password
, bool fail_on_error
)
1534 const char *remoteversion_str
;
1536 static char *password
= NULL
;
1538 if (prompt_password
== TRI_YES
&& !password
)
1539 password
= simple_prompt("Password: ", 100, false);
1542 * Start the connection. Loop until we have a password if requested by
1548 conn
= PQsetdbLogin(pghost
, pgport
, NULL
, NULL
, dbname
, pguser
, password
);
1552 fprintf(stderr
, _("%s: could not connect to database \"%s\"\n"),
1557 if (PQstatus(conn
) == CONNECTION_BAD
&&
1558 PQconnectionNeedsPassword(conn
) &&
1560 prompt_password
!= TRI_NO
)
1563 password
= simple_prompt("Password: ", 100, false);
1568 /* check to see that the backend connection was successfully made */
1569 if (PQstatus(conn
) == CONNECTION_BAD
)
1574 _("%s: could not connect to database \"%s\": %s\n"),
1575 progname
, dbname
, PQerrorMessage(conn
));
1585 remoteversion_str
= PQparameterStatus(conn
, "server_version");
1586 if (!remoteversion_str
)
1588 fprintf(stderr
, _("%s: could not get server version\n"), progname
);
1591 server_version
= parse_version(remoteversion_str
);
1592 if (server_version
< 0)
1594 fprintf(stderr
, _("%s: could not parse server version \"%s\"\n"),
1595 progname
, remoteversion_str
);
1599 my_version
= parse_version(PG_VERSION
);
1602 fprintf(stderr
, _("%s: could not parse version \"%s\"\n"),
1603 progname
, PG_VERSION
);
1608 * We allow the server to be back to 7.0, and up to any minor release of
1609 * our own major version. (See also version check in pg_dump.c.)
1611 if (my_version
!= server_version
1612 && (server_version
< 70000 ||
1613 (server_version
/ 100) > (my_version
/ 100)))
1615 fprintf(stderr
, _("server version: %s; %s version: %s\n"),
1616 remoteversion_str
, progname
, PG_VERSION
);
1617 fprintf(stderr
, _("aborting because of server version mismatch\n"));
1622 * On 7.3 and later, make sure we are not fooled by non-system schemas in
1625 if (server_version
>= 70300)
1626 executeCommand(conn
, "SET search_path = pg_catalog");
1633 * Run a query, return the results, exit program on failure.
1636 executeQuery(PGconn
*conn
, const char *query
)
1641 fprintf(stderr
, _("%s: executing %s\n"), progname
, query
);
1643 res
= PQexec(conn
, query
);
1645 PQresultStatus(res
) != PGRES_TUPLES_OK
)
1647 fprintf(stderr
, _("%s: query failed: %s"),
1648 progname
, PQerrorMessage(conn
));
1649 fprintf(stderr
, _("%s: query was: %s\n"),
1659 * As above for a SQL command (which returns nothing).
1662 executeCommand(PGconn
*conn
, const char *query
)
1667 fprintf(stderr
, _("%s: executing %s\n"), progname
, query
);
1669 res
= PQexec(conn
, query
);
1671 PQresultStatus(res
) != PGRES_COMMAND_OK
)
1673 fprintf(stderr
, _("%s: query failed: %s"),
1674 progname
, PQerrorMessage(conn
));
1675 fprintf(stderr
, _("%s: query was: %s\n"),
1689 dumpTimestamp(char *msg
)
1692 time_t now
= time(NULL
);
1695 * We don't print the timezone on Win32, because the names are long and
1696 * localized, which means they may contain characters in various random
1697 * encodings; this has been seen to cause encoding errors when reading the
1700 if (strftime(buf
, sizeof(buf
),
1702 "%Y-%m-%d %H:%M:%S %Z",
1704 "%Y-%m-%d %H:%M:%S",
1706 localtime(&now
)) != 0)
1707 fprintf(OPF
, "-- %s %s\n\n", msg
, buf
);
1712 * Append the given string to the shell command being built in the buffer,
1713 * with suitable shell-style quoting.
1716 doShellQuoting(PQExpBuffer buf
, const char *str
)
1721 appendPQExpBufferChar(buf
, '\'');
1722 for (p
= str
; *p
; p
++)
1725 appendPQExpBuffer(buf
, "'\"'\"'");
1727 appendPQExpBufferChar(buf
, *p
);
1729 appendPQExpBufferChar(buf
, '\'');
1732 appendPQExpBufferChar(buf
, '"');
1733 for (p
= str
; *p
; p
++)
1736 appendPQExpBuffer(buf
, "\\\"");
1738 appendPQExpBufferChar(buf
, *p
);
1740 appendPQExpBufferChar(buf
, '"');