aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/dumputils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r--src/bin/pg_dump/dumputils.c78
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