From 6178762fcf02f5f07099ff2277f8cdd82151cd0e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 1 Jun 2006 00:15:36 +0000 Subject: [PATCH] Fix up hack to suppress escape_string_warning so that it actually works and there's only one place that's a kluge, ie, appendStringLiteralConn. Note that pg_dump itself doesn't use appendStringLiteralConn, so its behavior is not affected; only the other utility programs care. --- src/bin/pg_dump/dumputils.c | 17 +++++++++- src/bin/psql/command.c | 8 ++--- src/bin/psql/common.h | 8 +---- src/bin/psql/copy.c | 64 +++++++++++++++++++++--------------- src/bin/psql/describe.c | 6 +--- src/bin/scripts/createdb.c | 4 +-- src/bin/scripts/createuser.c | 4 +-- 7 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index bad85e2bda..8648c2f559 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.29 2006/05/28 21:13:54 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.30 2006/06/01 00:15:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -191,6 +191,21 @@ appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn) { size_t length = strlen(str); + /* + * XXX This is a kluge to silence escape_string_warning in our utility + * programs. It should go away someday. + */ + if (strchr(str, '\\') != NULL && PQserverVersion(conn) >= 80100) + { + /* ensure we are not adjacent to an identifier */ + if (buf->len > 0 && buf->data[buf->len-1] != ' ') + appendPQExpBufferChar(buf, ' '); + appendPQExpBufferChar(buf, ESCAPE_STRING_SYNTAX); + appendStringLiteral(buf, str, PQclientEncoding(conn), false); + return; + } + /* XXX end kluge */ + if (!enlargePQExpBuffer(buf, 2 * length + 2)) return; appendPQExpBufferChar(buf, '\''); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index a060e00abc..63161edd45 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.167 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.168 2006/06/01 00:15:36 tgl Exp $ */ #include "postgres_fe.h" #include "command.h" @@ -681,9 +681,9 @@ exec_command(const char *cmd, PGresult *res; initPQExpBuffer(&buf); - printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD %c'%s';", - fmtId(user), NEED_E_STR(encrypted_password), - encrypted_password); + printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ", + fmtId(user)); + appendStringLiteralConn(&buf, encrypted_password, pset.db); res = PSQLexec(buf.data, false); termPQExpBuffer(&buf); if (!res) diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 0d0f7ad5ed..4cf5da0bf3 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.48 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.49 2006/06/01 00:15:36 tgl Exp $ */ #ifndef COMMON_H #define COMMON_H @@ -22,12 +22,6 @@ #define atooid(x) ((Oid) strtoul((x), NULL, 10)) -/* - * We use this to prefix strings with E'' that we know are already safe, - * so we don't get an escape_string_warning. - */ -#define NEED_E_STR(str) ((strchr(str, '\\') && !standard_strings()) ? ESCAPE_STRING_SYNTAX : ' ') - /* * Safer versions of some standard C library functions. If an * out-of-memory condition occurs, these functions will bail out diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 15a3883cdd..ae4ad629e9 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.62 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.63 2006/06/01 00:15:36 tgl Exp $ */ #include "postgres_fe.h" #include "copy.h" @@ -19,6 +19,7 @@ #include "libpq-fe.h" #include "pqexpbuffer.h" #include "pqsignal.h" +#include "dumputils.h" #include "settings.h" #include "common.h" @@ -113,6 +114,7 @@ parse_slash_copy(const char *args) char *line; char *token; const char *whitespace = " \t\n\r"; + char nonstd_backslash = standard_strings() ? 0 : '\\'; if (args) line = pg_strdup(args); @@ -216,7 +218,7 @@ parse_slash_copy(const char *args) goto error; token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', true, pset.encoding); + nonstd_backslash, true, pset.encoding); if (!token) goto error; @@ -255,7 +257,7 @@ parse_slash_copy(const char *args) if (token && pg_strcasecmp(token, "delimiters") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (!token) goto error; result->delim = pg_strdup(token); @@ -290,10 +292,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "delimiter") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token) result->delim = pg_strdup(token); else @@ -302,10 +304,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "null") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token) result->null = pg_strdup(token); else @@ -314,10 +316,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "quote") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token) result->quote = pg_strdup(token); else @@ -326,10 +328,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "escape") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - standard_strings() ? 0 : '\\', false, pset.encoding); + nonstd_backslash, false, pset.encoding); if (token) result->escape = pg_strdup(token); else @@ -461,23 +463,27 @@ do_copy(const char *args) /* Uses old COPY syntax for backward compatibility 2002-06-19 */ if (options->delim) { + /* if user gave a quoted string, use it as-is */ if (options->delim[0] == '\'') - appendPQExpBuffer(&query, " USING DELIMITERS %c%s", - NEED_E_STR(options->delim), options->delim); + appendPQExpBuffer(&query, " USING DELIMITERS %s", options->delim); else - appendPQExpBuffer(&query, " USING DELIMITERS %c'%s'", - NEED_E_STR(options->delim), options->delim); + { + appendPQExpBuffer(&query, " USING DELIMITERS "); + appendStringLiteralConn(&query, options->delim, pset.db); + } } /* There is no backward-compatible CSV syntax */ if (options->null) { + /* if user gave a quoted string, use it as-is */ if (options->null[0] == '\'') - appendPQExpBuffer(&query, " WITH NULL AS %c%s", - NEED_E_STR(options->null), options->null); + appendPQExpBuffer(&query, " WITH NULL AS %s", options->null); else - appendPQExpBuffer(&query, " WITH NULL AS %c'%s'", - NEED_E_STR(options->null), options->null); + { + appendPQExpBuffer(&query, " WITH NULL AS "); + appendStringLiteralConn(&query, options->null, pset.db); + } } if (options->csv_mode) @@ -488,22 +494,26 @@ do_copy(const char *args) if (options->quote) { + /* if user gave a quoted string, use it as-is */ if (options->quote[0] == '\'') - appendPQExpBuffer(&query, " QUOTE AS %c%s", - NEED_E_STR(options->quote), options->quote); + appendPQExpBuffer(&query, " QUOTE AS %s", options->quote); else - appendPQExpBuffer(&query, " QUOTE AS %c'%s'", - NEED_E_STR(options->quote), options->quote); + { + appendPQExpBuffer(&query, " QUOTE AS "); + appendStringLiteralConn(&query, options->quote, pset.db); + } } if (options->escape) { + /* if user gave a quoted string, use it as-is */ if (options->escape[0] == '\'') - appendPQExpBuffer(&query, " ESCAPE AS %c%s", - NEED_E_STR(options->escape), options->escape); + appendPQExpBuffer(&query, " ESCAPE AS %s", options->escape); else - appendPQExpBuffer(&query, " ESCAPE AS %c'%s'", - NEED_E_STR(options->escape), options->escape); + { + appendPQExpBuffer(&query, " ESCAPE AS "); + appendStringLiteralConn(&query, options->escape, pset.db); + } } if (options->force_quote_list) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index b6a462c3c9..9c9f609407 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.138 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.139 2006/06/01 00:15:36 tgl Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -1907,17 +1907,14 @@ processNamePattern(PQExpBuffer buf, const char *pattern, if (altnamevar) { appendPQExpBuffer(buf, "(%s ~ ", namevar); - appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBuffer(buf, "\n OR %s ~ ", altnamevar); - appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBuffer(buf, ")\n"); } else { appendPQExpBuffer(buf, "%s ~ ", namevar); - appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBufferChar(buf, '\n'); } @@ -1941,7 +1938,6 @@ processNamePattern(PQExpBuffer buf, const char *pattern, { WHEREAND(); appendPQExpBuffer(buf, "%s ~ ", schemavar); - appendPQExpBufferChar(buf, NEED_E_STR(schemabuf.data)); appendStringLiteralConn(buf, schemabuf.data, pset.db); appendPQExpBufferChar(buf, '\n'); } diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c index c023a12bd9..4998c798de 100644 --- a/src/bin/scripts/createdb.c +++ b/src/bin/scripts/createdb.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.20 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.21 2006/06/01 00:15:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -185,8 +185,6 @@ main(int argc, char *argv[]) { conn = connectDatabase(dbname, host, port, username, password, progname); - executeCommand(conn, "SET escape_string_warning TO 'off'", progname, false); - printfPQExpBuffer(&sql, "COMMENT ON DATABASE %s IS ", fmtId(dbname)); appendStringLiteralConn(&sql, comment, conn); appendPQExpBuffer(&sql, ";\n"); diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index 17b3407a3a..e671298fda 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.31 2006/05/31 11:02:42 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.32 2006/06/01 00:15:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -243,8 +243,6 @@ main(int argc, char *argv[]) printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser)); if (newpassword) { - executeCommand(conn, "SET escape_string_warning TO 'off'", progname, false); - if (encrypted == TRI_YES) appendPQExpBuffer(&sql, " ENCRYPTED"); if (encrypted == TRI_NO)