mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
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.
This commit is contained in:
@ -50,6 +50,7 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
|
|||||||
static void dumpDatabases(PGconn *conn);
|
static void dumpDatabases(PGconn *conn);
|
||||||
static void dumpTimestamp(char *msg);
|
static void dumpTimestamp(char *msg);
|
||||||
static void doShellQuoting(PQExpBuffer buf, const char *str);
|
static void doShellQuoting(PQExpBuffer buf, const char *str);
|
||||||
|
static void doConnStrQuoting(PQExpBuffer buf, const char *str);
|
||||||
|
|
||||||
static int runPgDump(const char *dbname);
|
static int runPgDump(const char *dbname);
|
||||||
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
||||||
@ -1583,6 +1584,7 @@ dumpDatabases(PGconn *conn)
|
|||||||
static int
|
static int
|
||||||
runPgDump(const char *dbname)
|
runPgDump(const char *dbname)
|
||||||
{
|
{
|
||||||
|
PQExpBuffer connstr = createPQExpBuffer();
|
||||||
PQExpBuffer cmd = createPQExpBuffer();
|
PQExpBuffer cmd = createPQExpBuffer();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1598,7 +1600,17 @@ runPgDump(const char *dbname)
|
|||||||
else
|
else
|
||||||
appendPQExpBuffer(cmd, " -Fp ");
|
appendPQExpBuffer(cmd, " -Fp ");
|
||||||
|
|
||||||
doShellQuoting(cmd, dbname);
|
/*
|
||||||
|
* Construct a connection string from the database name, like
|
||||||
|
* dbname='<database name>'. pg_dump would usually also accept the
|
||||||
|
* database name as is, but if it contains any = characters, it would
|
||||||
|
* incorrectly treat it as a connection string.
|
||||||
|
*/
|
||||||
|
appendPQExpBuffer(connstr, "dbname='");
|
||||||
|
doConnStrQuoting(connstr, dbname);
|
||||||
|
appendPQExpBuffer(connstr, "'");
|
||||||
|
|
||||||
|
doShellQuoting(cmd, connstr->data);
|
||||||
|
|
||||||
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
|
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
|
||||||
|
|
||||||
@ -1611,6 +1623,7 @@ runPgDump(const char *dbname)
|
|||||||
ret = system(cmd->data);
|
ret = system(cmd->data);
|
||||||
|
|
||||||
destroyPQExpBuffer(cmd);
|
destroyPQExpBuffer(cmd);
|
||||||
|
destroyPQExpBuffer(connstr);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1834,6 +1847,25 @@ dumpTimestamp(char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append the given string to the buffer, with suitable quoting for passing
|
||||||
|
* the string as a value, in a keyword/pair value in a libpq connection
|
||||||
|
* string
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
doConnStrQuoting(PQExpBuffer buf, const char *str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
/* ' and \ must be escaped by to \' and \\ */
|
||||||
|
if (*str == '\'' || *str == '\\')
|
||||||
|
appendPQExpBufferChar(buf, '\\');
|
||||||
|
|
||||||
|
appendPQExpBufferChar(buf, *str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append the given string to the shell command being built in the buffer,
|
* Append the given string to the shell command being built in the buffer,
|
||||||
* with suitable shell-style quoting.
|
* with suitable shell-style quoting.
|
||||||
|
Reference in New Issue
Block a user