aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/pg_dump/dumputils.c51
-rw-r--r--src/bin/pg_dump/dumputils.h5
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c17
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.h5
-rw-r--r--src/bin/pg_dump/pg_backup_null.c17
5 files changed, 75 insertions, 20 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 404e1d3ed3e..8037c1d7e16 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -326,6 +326,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.
*/
int
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index 952c8b3653e..3c56c3f9a4d 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -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.h,v 1.24 2009/03/11 03:33:29 adunstan Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.25 2009/08/04 21:56:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,9 @@ extern void appendStringLiteralConn(PQExpBuffer buf, const char *str,
PGconn *conn);
extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str,
const char *dqprefix);
+extern void appendByteaLiteral(PQExpBuffer buf,
+ const unsigned char *str, size_t length,
+ bool std_strings);
extern int parse_version(const char *versionString);
extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems);
extern bool buildACLCommands(const char *name, const char *subname,
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index c5a75d34888..2ff282faa8c 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.173 2009/07/21 21:46:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.174 2009/08/04 21:56:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1249,20 +1249,19 @@ dump_lo_buf(ArchiveHandle *AH)
}
else
{
- unsigned char *str;
- size_t len;
+ PQExpBuffer buf = createPQExpBuffer();
- str = PQescapeBytea((const unsigned char *) AH->lo_buf,
- AH->lo_buf_used, &len);
- if (!str)
- die_horribly(AH, modulename, "out of memory\n");
+ appendByteaLiteralAHX(buf,
+ (const unsigned char *) AH->lo_buf,
+ AH->lo_buf_used,
+ AH);
/* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
AH->writingBlob = 0;
- ahprintf(AH, "SELECT pg_catalog.lowrite(0, '%s');\n", str);
+ ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
AH->writingBlob = 1;
- free(str);
+ destroyPQExpBuffer(buf);
}
AH->lo_buf_used = 0;
}
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 4f7884862d8..710dec019ad 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -17,7 +17,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.80 2009/07/21 21:46:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.81 2009/08/04 21:56:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -342,6 +342,9 @@ extern bool checkSeek(FILE *fp);
#define appendStringLiteralAHX(buf,str,AH) \
appendStringLiteral(buf, str, (AH)->public.encoding, (AH)->public.std_strings)
+#define appendByteaLiteralAHX(buf,str,len,AH) \
+ appendByteaLiteral(buf, str, len, (AH)->public.std_strings)
+
/*
* Mandatory routines for each supported format
*/
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
index a89b012e6c0..d9cb02446b3 100644
--- a/src/bin/pg_dump/pg_backup_null.c
+++ b/src/bin/pg_dump/pg_backup_null.c
@@ -17,12 +17,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.21 2009/07/21 21:46:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.22 2009/08/04 21:56:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "pg_backup_archiver.h"
+#include "dumputils.h"
#include <unistd.h> /* for dup */
@@ -101,16 +102,16 @@ _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
{
if (dLen > 0)
{
- unsigned char *str;
- size_t len;
+ PQExpBuffer buf = createPQExpBuffer();
- str = PQescapeBytea((const unsigned char *) data, dLen, &len);
- if (!str)
- die_horribly(AH, NULL, "out of memory\n");
+ appendByteaLiteralAHX(buf,
+ (const unsigned char *) data,
+ dLen,
+ AH);
- ahprintf(AH, "SELECT pg_catalog.lowrite(0, '%s');\n", str);
+ ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
- free(str);
+ destroyPQExpBuffer(buf);
}
return dLen;
}