Skip to content

Commit f435cd1

Browse files
committed
Fix pg_dumpall with database names containing =
If a database name contained a '=' character, pg_dumpall failed. The problem was in the way pg_dumpall passes the database name to pg_dump on the command line. If it contained a '=' character, pg_dump would interpret it as a libpq connection string instead of a plain database name. To fix, pass the database name to pg_dump as a connection string, "dbname=foo", with the database name escaped if necessary. Back-patch to all supported branches.
1 parent 2930c05 commit f435cd1

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/bin/pg_dump/pg_dumpall.c

+33-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
5050
static void dumpDatabases(PGconn *conn);
5151
static void dumpTimestamp(char *msg);
5252
static void doShellQuoting(PQExpBuffer buf, const char *str);
53+
static void doConnStrQuoting(PQExpBuffer buf, const char *str);
5354

5455
static int runPgDump(const char *dbname);
5556
static void buildShSecLabels(PGconn *conn, const char *catalog_name,
@@ -1629,6 +1630,7 @@ dumpDatabases(PGconn *conn)
16291630
static int
16301631
runPgDump(const char *dbname)
16311632
{
1633+
PQExpBuffer connstr = createPQExpBuffer();
16321634
PQExpBuffer cmd = createPQExpBuffer();
16331635
int ret;
16341636

@@ -1644,7 +1646,17 @@ runPgDump(const char *dbname)
16441646
else
16451647
appendPQExpBuffer(cmd, " -Fp ");
16461648

1647-
doShellQuoting(cmd, dbname);
1649+
/*
1650+
* Construct a connection string from the database name, like
1651+
* dbname='<database name>'. pg_dump would usually also accept the
1652+
* database name as is, but if it contains any = characters, it would
1653+
* incorrectly treat it as a connection string.
1654+
*/
1655+
appendPQExpBuffer(connstr, "dbname='");
1656+
doConnStrQuoting(connstr, dbname);
1657+
appendPQExpBuffer(connstr, "'");
1658+
1659+
doShellQuoting(cmd, connstr->data);
16481660

16491661
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
16501662

@@ -1657,6 +1669,7 @@ runPgDump(const char *dbname)
16571669
ret = system(cmd->data);
16581670

16591671
destroyPQExpBuffer(cmd);
1672+
destroyPQExpBuffer(connstr);
16601673

16611674
return ret;
16621675
}
@@ -1896,6 +1909,25 @@ dumpTimestamp(char *msg)
18961909
}
18971910

18981911

1912+
/*
1913+
* Append the given string to the buffer, with suitable quoting for passing
1914+
* the string as a value, in a keyword/pair value in a libpq connection
1915+
* string
1916+
*/
1917+
static void
1918+
doConnStrQuoting(PQExpBuffer buf, const char *str)
1919+
{
1920+
while (*str)
1921+
{
1922+
/* ' and \ must be escaped by to \' and \\ */
1923+
if (*str == '\'' || *str == '\\')
1924+
appendPQExpBufferChar(buf, '\\');
1925+
1926+
appendPQExpBufferChar(buf, *str);
1927+
str++;
1928+
}
1929+
}
1930+
18991931
/*
19001932
* Append the given string to the shell command being built in the buffer,
19011933
* with suitable shell-style quoting.

0 commit comments

Comments
 (0)