diff options
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r-- | src/bin/pg_dump/dumputils.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index e50e3e87fe2..345d6cf3c88 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -324,6 +324,84 @@ 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 *vp; + unsigned char *rp; + size_t i; + size_t len; + size_t bslash_len = (std_strings ? 1 : 2); + + len = 2; /* for the quote marks */ + vp = str; + for (i = length; i > 0; i--, vp++) + { + if (*vp < 0x20 || *vp > 0x7e) + len += bslash_len + 3; + else if (*vp == '\'') + len += 2; + else if (*vp == '\\') + len += bslash_len + bslash_len; + else + len++; + } + + if (!enlargePQExpBuffer(buf, len)) + return; + + rp = (unsigned char *) (buf->data + buf->len); + *rp++ = '\''; + + vp = str; + for (i = length; i > 0; i--, vp++) + { + if (*vp < 0x20 || *vp > 0x7e) + { + int val = *vp; + + if (!std_strings) + *rp++ = '\\'; + *rp++ = '\\'; + *rp++ = (val >> 6) + '0'; + *rp++ = ((val >> 3) & 07) + '0'; + *rp++ = (val & 07) + '0'; + } + else if (*vp == '\'') + { + *rp++ = '\''; + *rp++ = '\''; + } + else if (*vp == '\\') + { + if (!std_strings) + { + *rp++ = '\\'; + *rp++ = '\\'; + } + *rp++ = '\\'; + *rp++ = '\\'; + } + else + *rp++ = *vp; + } + + *rp++ = '\''; + *rp = '\0'; + + buf->len = ((char *) rp) - buf->data; +} + + +/* * Convert backend's version string into a number. */ int |