mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Fix pg_dump to do the right thing when escaping the contents of large objects.
The previous implementation got it right in most cases but failed in one: if you pg_dump into an archive with standard_conforming_strings enabled, then pg_restore to a script file (not directly to a database), the script will set standard_conforming_strings = on but then emit large object data as nonstandardly-escaped strings. At the moment the code is made to emit hex-format bytea strings when dumping to a script file. We might want to change to old-style escaping for backwards compatibility, but that would be slower and bulkier. If we do, it's just a matter of reimplementing appendByteaLiteral(). This has been broken for a long time, but given the lack of field complaints I'm not going to worry about back-patching.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.47 2009/07/14 20:24:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.48 2009/08/04 21:56:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -325,6 +325,55 @@ appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert a bytea value (presented as raw bytes) to an SQL string literal
|
||||
* and append it to the given buffer. We assume the specified
|
||||
* standard_conforming_strings setting.
|
||||
*
|
||||
* This is needed in situations where we do not have a PGconn available.
|
||||
* Where we do, PQescapeByteaConn is a better choice.
|
||||
*/
|
||||
void
|
||||
appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length,
|
||||
bool std_strings)
|
||||
{
|
||||
const unsigned char *source = str;
|
||||
char *target;
|
||||
|
||||
static const char hextbl[] = "0123456789abcdef";
|
||||
|
||||
/*
|
||||
* This implementation is hard-wired to produce hex-format output.
|
||||
* We do not know the server version the output will be loaded into,
|
||||
* so making an intelligent format choice is impossible. It might be
|
||||
* better to always use the old escaped format.
|
||||
*/
|
||||
if (!enlargePQExpBuffer(buf, 2 * length + 5))
|
||||
return;
|
||||
|
||||
target = buf->data + buf->len;
|
||||
*target++ = '\'';
|
||||
if (!std_strings)
|
||||
*target++ = '\\';
|
||||
*target++ = '\\';
|
||||
*target++ = 'x';
|
||||
|
||||
while (length-- > 0)
|
||||
{
|
||||
unsigned char c = *source++;
|
||||
|
||||
*target++ = hextbl[(c >> 4) & 0xF];
|
||||
*target++ = hextbl[c & 0xF];
|
||||
}
|
||||
|
||||
/* Write the terminating quote and NUL character. */
|
||||
*target++ = '\'';
|
||||
*target = '\0';
|
||||
|
||||
buf->len = target - buf->data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert backend's version string into a number.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user