Re: Cleanup for new escape handling

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: PostgreSQL-patches <pgsql-patches(at)postgresql(dot)org>
Subject: Re: Cleanup for new escape handling
Date: 2006-05-26 23:48:47
Message-ID: 200605262348.k4QNmmZ28474@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


Patch applied.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> This patch cleans up the use of E'' strings in 8.2. 8.2 is the first
> release where standard_conforming_strings can be 'on', and when 'on',
> escape_string_warning is disabled.
>
> In 8.1, the behavior was to use E'' strings for any case where
> backslashes exist. For 8.2, per suggestion from Tom, we should use E''
> strings only for standard_conforming_strings = 'off'. This would allow
> pg_dump output with standard_conforming_strings = 'on' to generate
> proper strings that can be loaded into other databases without the
> backslash doubling we typically do. I have added the dumping of the
> standard_conforming_strings to pg_dump, like we do now for
> client_encoding. The only risk of the patch is that someone will use
> one of the adt/ruleutils.c functions like pg_get_constraintdef() with
> one setting of standard_conforming_strings and then try to load it into
> a database with a different standard_conforming_strings setting.
>
> I also added standard backslash handling for plpgsql.
>
> I also checked ecpg and that uses E'' for all strings that have \
> because it doesn't know if the target database is going to have
> standard_conforming_strings on or off. That seems best, and no one
> expects the _output_ of ecpg to be portable.
>
> The macros we use for escape processing really makes these changes easy.
>
> --
> Bruce Momjian http://candle.pha.pa.us
> EnterpriseDB http://www.enterprisedb.com
>
> + If your life is a hard drive, Christ can be your backup. +

> Index: src/backend/utils/adt/quote.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/utils/adt/quote.c,v
> retrieving revision 1.18
> diff -c -c -r1.18 quote.c
> *** src/backend/utils/adt/quote.c 5 Mar 2006 15:58:43 -0000 1.18
> --- src/backend/utils/adt/quote.c 25 May 2006 22:15:36 -0000
> ***************
> *** 14,19 ****
> --- 14,20 ----
> #include "postgres.h"
>
> #include "utils/builtins.h"
> + #include "parser/gramparse.h"
>
>
> /*
> ***************
> *** 65,83 ****
> cp1 = VARDATA(t);
> cp2 = VARDATA(result);
>
> ! for (; len-- > 0; cp1++)
> ! if (*cp1 == '\\')
> ! {
> ! *cp2++ = ESCAPE_STRING_SYNTAX;
> ! break;
> ! }
>
> len = VARSIZE(t) - VARHDRSZ;
> cp1 = VARDATA(t);
> *cp2++ = '\'';
> while (len-- > 0)
> {
> ! if (SQL_STR_DOUBLE(*cp1))
> *cp2++ = *cp1;
> *cp2++ = *cp1++;
> }
> --- 66,85 ----
> cp1 = VARDATA(t);
> cp2 = VARDATA(result);
>
> ! if (!standard_conforming_strings)
> ! for (; len-- > 0; cp1++)
> ! if (*cp1 == '\\')
> ! {
> ! *cp2++ = ESCAPE_STRING_SYNTAX;
> ! break;
> ! }
>
> len = VARSIZE(t) - VARHDRSZ;
> cp1 = VARDATA(t);
> *cp2++ = '\'';
> while (len-- > 0)
> {
> ! if (SQL_STR_DOUBLE(*cp1, !standard_conforming_strings))
> *cp2++ = *cp1;
> *cp2++ = *cp1++;
> }
> Index: src/backend/utils/adt/ruleutils.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v
> retrieving revision 1.221
> diff -c -c -r1.221 ruleutils.c
> *** src/backend/utils/adt/ruleutils.c 30 Apr 2006 18:30:40 -0000 1.221
> --- src/backend/utils/adt/ruleutils.c 25 May 2006 22:15:41 -0000
> ***************
> *** 31,36 ****
> --- 31,37 ----
> #include "nodes/makefuncs.h"
> #include "optimizer/clauses.h"
> #include "optimizer/tlist.h"
> + #include "parser/gramparse.h"
> #include "parser/keywords.h"
> #include "parser/parse_expr.h"
> #include "parser/parse_func.h"
> ***************
> *** 533,545 ****
> {
> if (i > 0)
> appendStringInfo(&buf, ", ");
> ! if (strchr(p, '\\') != NULL)
> appendStringInfoChar(&buf, ESCAPE_STRING_SYNTAX);
> appendStringInfoChar(&buf, '\'');
>
> while (*p)
> {
> ! if (SQL_STR_DOUBLE(*p))
> appendStringInfoChar(&buf, *p);
> appendStringInfoChar(&buf, *p++);
> }
> --- 534,546 ----
> {
> if (i > 0)
> appendStringInfo(&buf, ", ");
> ! if (!standard_conforming_strings && strchr(p, '\\') != NULL)
> appendStringInfoChar(&buf, ESCAPE_STRING_SYNTAX);
> appendStringInfoChar(&buf, '\'');
>
> while (*p)
> {
> ! if (SQL_STR_DOUBLE(*p, !standard_conforming_strings))
> appendStringInfoChar(&buf, *p);
> appendStringInfoChar(&buf, *p++);
> }
> ***************
> *** 3882,3888 ****
> char *valptr;
> bool isfloat = false;
> bool needlabel;
> !
> if (constval->constisnull)
> {
> /*
> --- 3883,3890 ----
> char *valptr;
> bool isfloat = false;
> bool needlabel;
> ! bool is_e_string = false;
> !
> if (constval->constisnull)
> {
> /*
> ***************
> *** 3948,3957 ****
> * representation. XXX Any MULTIBYTE considerations here?
> */
> for (valptr = extval; *valptr; valptr++)
> ! if (*valptr == '\\' ||
> (unsigned char) *valptr < (unsigned char) ' ')
> {
> appendStringInfoChar(buf, ESCAPE_STRING_SYNTAX);
> break;
> }
>
> --- 3950,3960 ----
> * representation. XXX Any MULTIBYTE considerations here?
> */
> for (valptr = extval; *valptr; valptr++)
> ! if ((!standard_conforming_strings && *valptr == '\\') ||
> (unsigned char) *valptr < (unsigned char) ' ')
> {
> appendStringInfoChar(buf, ESCAPE_STRING_SYNTAX);
> + is_e_string = true;
> break;
> }
>
> ***************
> *** 3960,3966 ****
> {
> char ch = *valptr;
>
> ! if (SQL_STR_DOUBLE(ch))
> {
> appendStringInfoChar(buf, ch);
> appendStringInfoChar(buf, ch);
> --- 3963,3969 ----
> {
> char ch = *valptr;
>
> ! if (SQL_STR_DOUBLE(ch, is_e_string))
> {
> appendStringInfoChar(buf, ch);
> appendStringInfoChar(buf, ch);
> Index: src/bin/initdb/initdb.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/initdb/initdb.c,v
> retrieving revision 1.114
> diff -c -c -r1.114 initdb.c
> *** src/bin/initdb/initdb.c 21 Mar 2006 17:54:28 -0000 1.114
> --- src/bin/initdb/initdb.c 25 May 2006 22:15:48 -0000
> ***************
> *** 2103,2109 ****
> }
>
> /*
> ! * Escape any single quotes or backslashes in given string
> */
> static char *
> escape_quotes(const char *src)
> --- 2103,2110 ----
> }
>
> /*
> ! * Escape any single quotes or backslashes in given string;
> ! * postgresql.conf always enables backslash escapes
> */
> static char *
> escape_quotes(const char *src)
> ***************
> *** 2115,2121 ****
>
> for (i = 0, j = 0; i < len; i++)
> {
> ! if (SQL_STR_DOUBLE(src[i]))
> result[j++] = src[i];
> result[j++] = src[i];
> }
> --- 2116,2122 ----
>
> for (i = 0, j = 0; i < len; i++)
> {
> ! if (SQL_STR_DOUBLE(src[i], true))
> result[j++] = src[i];
> result[j++] = src[i];
> }
> Index: src/bin/pg_dump/dumputils.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v
> retrieving revision 1.27
> diff -c -c -r1.27 dumputils.c
> *** src/bin/pg_dump/dumputils.c 30 Apr 2006 21:15:33 -0000 1.27
> --- src/bin/pg_dump/dumputils.c 25 May 2006 22:15:49 -0000
> ***************
> *** 105,128 ****
> * Special characters are escaped. Quote mark ' goes to '' per SQL
> * standard, other stuff goes to \ sequences. If escapeAll is false,
> * whitespace characters are not escaped (tabs, newlines, etc.). This
> ! * is appropriate for dump file output.
> */
> void
> ! appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
> {
> char ch;
> const char *p;
>
> for (p = str; *p; p++)
> {
> ch = *p;
> ! if (ch == '\\' ||
> ((unsigned char) ch < (unsigned char) ' ' &&
> (escapeAll ||
> (ch != '\t' && ch != '\n' && ch != '\v' &&
> ch != '\f' && ch != '\r'))))
> {
> appendPQExpBufferChar(buf, ESCAPE_STRING_SYNTAX);
> break;
> }
> }
> --- 105,133 ----
> * Special characters are escaped. Quote mark ' goes to '' per SQL
> * standard, other stuff goes to \ sequences. If escapeAll is false,
> * whitespace characters are not escaped (tabs, newlines, etc.). This
> ! * is appropriate for dump file output. Using E'' strings for
> ! * backslashes is always safe for standard_conforming_strings on or off.
> */
> void
> ! appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll,
> ! bool e_string_for_backslash)
> {
> char ch;
> const char *p;
> + bool is_e_string = false;
>
> for (p = str; *p; p++)
> {
> ch = *p;
> !
> ! if ((e_string_for_backslash && ch == '\\') ||
> ((unsigned char) ch < (unsigned char) ' ' &&
> (escapeAll ||
> (ch != '\t' && ch != '\n' && ch != '\v' &&
> ch != '\f' && ch != '\r'))))
> {
> appendPQExpBufferChar(buf, ESCAPE_STRING_SYNTAX);
> + is_e_string = true;
> break;
> }
> }
> ***************
> *** 131,137 ****
> for (p = str; *p; p++)
> {
> ch = *p;
> ! if (SQL_STR_DOUBLE(ch))
> {
> appendPQExpBufferChar(buf, ch);
> appendPQExpBufferChar(buf, ch);
> --- 136,142 ----
> for (p = str; *p; p++)
> {
> ch = *p;
> ! if (SQL_STR_DOUBLE(ch, is_e_string))
> {
> appendPQExpBufferChar(buf, ch);
> appendPQExpBufferChar(buf, ch);
> ***************
> *** 208,214 ****
> bool escapeAll, const char *dqprefix)
> {
> if (strchr(str, '\'') == NULL && strchr(str, '\\') == NULL)
> ! appendStringLiteral(buf, str, escapeAll);
> else
> appendStringLiteralDQ(buf, str, dqprefix);
> }
> --- 213,219 ----
> bool escapeAll, const char *dqprefix)
> {
> if (strchr(str, '\'') == NULL && strchr(str, '\\') == NULL)
> ! appendStringLiteral(buf, str, escapeAll, true);
> else
> appendStringLiteralDQ(buf, str, dqprefix);
> }
> Index: src/bin/pg_dump/dumputils.h
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/pg_dump/dumputils.h,v
> retrieving revision 1.15
> diff -c -c -r1.15 dumputils.h
> *** src/bin/pg_dump/dumputils.h 5 Mar 2006 15:58:50 -0000 1.15
> --- src/bin/pg_dump/dumputils.h 25 May 2006 22:15:49 -0000
> ***************
> *** 17,26 ****
>
> #include "pqexpbuffer.h"
>
> -
> extern const char *fmtId(const char *identifier);
> extern void appendStringLiteral(PQExpBuffer buf, const char *str,
> ! bool escapeAll);
> extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str,
> const char *dqprefix);
> extern void appendStringLiteralDQOpt(PQExpBuffer buf, const char *str,
> --- 17,25 ----
>
> #include "pqexpbuffer.h"
>
> extern const char *fmtId(const char *identifier);
> extern void appendStringLiteral(PQExpBuffer buf, const char *str,
> ! bool escapeAll, bool e_string_for_backslash);
> extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str,
> const char *dqprefix);
> extern void appendStringLiteralDQOpt(PQExpBuffer buf, const char *str,
> Index: src/bin/pg_dump/pg_backup_archiver.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v
> retrieving revision 1.129
> diff -c -c -r1.129 pg_backup_archiver.c
> *** src/bin/pg_dump/pg_backup_archiver.c 24 May 2006 21:20:11 -0000 1.129
> --- src/bin/pg_dump/pg_backup_archiver.c 25 May 2006 22:15:50 -0000
> ***************
> *** 1900,1908 ****
> {
> teReqs res = REQ_ALL;
>
> ! /* ENCODING objects are dumped specially, so always reject here */
> if (strcmp(te->desc, "ENCODING") == 0)
> return 0;
>
> /* If it's an ACL, maybe ignore it */
> if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0)
> --- 1900,1910 ----
> {
> teReqs res = REQ_ALL;
>
> ! /* ENCODING and STDSTRINGS objects are dumped specially, so always reject */
> if (strcmp(te->desc, "ENCODING") == 0)
> return 0;
> + if (strcmp(te->desc, "STDSTRINGS") == 0)
> + return 0;
>
> /* If it's an ACL, maybe ignore it */
> if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0)
> ***************
> *** 2005,2019 ****
> {
> TocEntry *te;
>
> ! /* If we have an encoding setting, emit that */
> te = AH->toc->next;
> while (te != AH->toc)
> {
> if (strcmp(te->desc, "ENCODING") == 0)
> - {
> ahprintf(AH, "%s", te->defn);
> ! break;
> ! }
> te = te->next;
> }
>
> --- 2007,2020 ----
> {
> TocEntry *te;
>
> ! /* If we have an encoding or std_strings setting, emit that */
> te = AH->toc->next;
> while (te != AH->toc)
> {
> if (strcmp(te->desc, "ENCODING") == 0)
> ahprintf(AH, "%s", te->defn);
> ! if (strcmp(te->desc, "STDSTRINGS") == 0)
> ! ahprintf(AH, "%s", te->defn);
> te = te->next;
> }
>
> ***************
> *** 2042,2048 ****
> * SQL requires a string literal here. Might as well be correct.
> */
> if (user && *user)
> ! appendStringLiteral(cmd, user, false);
> else
> appendPQExpBuffer(cmd, "DEFAULT");
> appendPQExpBuffer(cmd, ";");
> --- 2043,2049 ----
> * SQL requires a string literal here. Might as well be correct.
> */
> if (user && *user)
> ! appendStringLiteral(cmd, user, false, true);
> else
> appendPQExpBuffer(cmd, "DEFAULT");
> appendPQExpBuffer(cmd, ";");
> Index: src/bin/pg_dump/pg_dump.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
> retrieving revision 1.433
> diff -c -c -r1.433 pg_dump.c
> *** src/bin/pg_dump/pg_dump.c 5 Mar 2006 15:58:50 -0000 1.433
> --- src/bin/pg_dump/pg_dump.c 25 May 2006 22:15:57 -0000
> ***************
> *** 82,87 ****
> --- 82,88 ----
> * activities. */
> Archive *g_fout; /* the script file */
> PGconn *g_conn; /* the database connection */
> + bool std_strings = false; /* GUC variable */
>
> /* various user-settable parameters */
> bool dumpInserts; /* dump data using proper insert strings */
> ***************
> *** 174,179 ****
> --- 175,181 ----
> static int dumpBlobComments(Archive *AH, void *arg);
> static void dumpDatabase(Archive *AH);
> static void dumpEncoding(Archive *AH);
> + static void dumpStdStrings(Archive *AH);
> static const char *getAttrName(int attrnum, TableInfo *tblInfo);
> static const char *fmtCopyColumnList(const TableInfo *ti);
> static void do_sql_command(PGconn *conn, const char *query);
> ***************
> *** 619,624 ****
> --- 621,628 ----
> /* First the special encoding entry. */
> dumpEncoding(g_fout);
>
> + dumpStdStrings(g_fout);
> +
> /* The database item is always second, unless we don't want it at all */
> if (!dataOnly && selectTableName == NULL && selectSchemaName == NULL)
> dumpDatabase(g_fout);
> ***************
> *** 1084,1090 ****
> default:
> /* All other types are printed as string literals. */
> resetPQExpBuffer(q);
> ! appendStringLiteral(q, PQgetvalue(res, tuple, field), false);
> archputs(q->data, fout);
> break;
> }
> --- 1088,1094 ----
> default:
> /* All other types are printed as string literals. */
> resetPQExpBuffer(q);
> ! appendStringLiteral(q, PQgetvalue(res, tuple, field), false, !std_strings);
> archputs(q->data, fout);
> break;
> }
> ***************
> *** 1236,1242 ****
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true);
> }
> else if (g_fout->remoteVersion >= 80000)
> {
> --- 1240,1246 ----
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true, !std_strings);
> }
> else if (g_fout->remoteVersion >= 80000)
> {
> ***************
> *** 1247,1253 ****
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true);
> }
> else if (g_fout->remoteVersion >= 70100)
> {
> --- 1251,1257 ----
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true, !std_strings);
> }
> else if (g_fout->remoteVersion >= 70100)
> {
> ***************
> *** 1258,1264 ****
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true);
> }
> else
> {
> --- 1262,1268 ----
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true, !std_strings);
> }
> else
> {
> ***************
> *** 1271,1277 ****
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true);
> }
>
> res = PQexec(g_conn, dbQry->data);
> --- 1275,1281 ----
> "FROM pg_database "
> "WHERE datname = ",
> username_subquery);
> ! appendStringLiteral(dbQry, datname, true, !std_strings);
> }
>
> res = PQexec(g_conn, dbQry->data);
> ***************
> *** 1310,1316 ****
> if (strlen(encoding) > 0)
> {
> appendPQExpBuffer(creaQry, " ENCODING = ");
> ! appendStringLiteral(creaQry, encoding, true);
> }
> if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
> appendPQExpBuffer(creaQry, " TABLESPACE = %s",
> --- 1314,1320 ----
> if (strlen(encoding) > 0)
> {
> appendPQExpBuffer(creaQry, " ENCODING = ");
> ! appendStringLiteral(creaQry, encoding, true, !std_strings);
> }
> if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
> appendPQExpBuffer(creaQry, " TABLESPACE = %s",
> ***************
> *** 1349,1355 ****
> if (comment && strlen(comment)) {
> resetPQExpBuffer(dbQry);
> appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
> ! appendStringLiteral(dbQry, comment, false);
> appendPQExpBuffer(dbQry, ";\n");
>
> ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
> --- 1353,1359 ----
> if (comment && strlen(comment)) {
> resetPQExpBuffer(dbQry);
> appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
> ! appendStringLiteral(dbQry, comment, false, !std_strings);
> appendPQExpBuffer(dbQry, ";\n");
>
> ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
> ***************
> *** 1398,1404 ****
> resetPQExpBuffer(qry);
>
> appendPQExpBuffer(qry, "SET client_encoding = ");
> ! appendStringLiteral(qry, PQgetvalue(res, 0, 0), true);
> appendPQExpBuffer(qry, ";\n");
>
> ArchiveEntry(AH, nilCatalogId, createDumpId(),
> --- 1402,1408 ----
> resetPQExpBuffer(qry);
>
> appendPQExpBuffer(qry, "SET client_encoding = ");
> ! appendStringLiteral(qry, PQgetvalue(res, 0, 0), true, !std_strings);
> appendPQExpBuffer(qry, ";\n");
>
> ArchiveEntry(AH, nilCatalogId, createDumpId(),
> ***************
> *** 1414,1419 ****
> --- 1418,1473 ----
>
>
> /*
> + * dumpStdStrings: put the correct escape string behavior into the archive
> + */
> + static void
> + dumpStdStrings(Archive *AH)
> + {
> + PQExpBuffer qry;
> + PGresult *res;
> +
> + if (g_verbose)
> + write_msg(NULL, "saving standard_conforming_strings setting\n");
> +
> + qry = createPQExpBuffer();
> +
> + /* standard_conforming_strings not used in pre-8.2 servers */
> + if (AH->remoteVersion < 80200)
> + {
> + appendPQExpBuffer(qry, "SET standard_conforming_strings = 'off';\n");
> + std_strings = false;
> + }
> + else
> + {
> + appendPQExpBuffer(qry, "SHOW standard_conforming_strings");
> +
> + res = PQexec(g_conn, qry->data);
> +
> + check_sql_result(res, g_conn, qry->data, PGRES_TUPLES_OK);
> +
> + PQclear(res);
> +
> + resetPQExpBuffer(qry);
> +
> + std_strings = (strcmp(PQgetvalue(res, 0, 0), "on") == 0);
> + appendPQExpBuffer(qry, "SET standard_conforming_strings = ");
> + appendStringLiteral(qry, PQgetvalue(res, 0, 0), true, !std_strings);
> + appendPQExpBuffer(qry, ";\n");
> + puts(PQgetvalue(res, 0, 0));
> +
> + }
> +
> + ArchiveEntry(AH, nilCatalogId, createDumpId(),
> + "STDSTRINGS", NULL, NULL, "",
> + false, "STDSTRINGS", qry->data, "", NULL,
> + NULL, 0,
> + NULL, NULL);
> +
> + destroyPQExpBuffer(qry);
> + }
> +
> +
> + /*
> * hasBlobs:
> * Test whether database contains any large objects
> */
> ***************
> *** 1586,1592 ****
>
> printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
> blobOid);
> ! appendStringLiteral(commentcmd, comment, false);
> appendPQExpBuffer(commentcmd, ";\n");
>
> archputs(commentcmd->data, AH);
> --- 1640,1646 ----
>
> printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
> blobOid);
> ! appendStringLiteral(commentcmd, comment, false, !std_strings);
> appendPQExpBuffer(commentcmd, ";\n");
>
> archputs(commentcmd->data, AH);
> ***************
> *** 4340,4346 ****
> PQExpBuffer query = createPQExpBuffer();
>
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
> ! appendStringLiteral(query, comments->descr, false);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> --- 4394,4400 ----
> PQExpBuffer query = createPQExpBuffer();
>
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
> ! appendStringLiteral(query, comments->descr, false, !std_strings);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> ***************
> *** 4398,4404 ****
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
> ! appendStringLiteral(query, descr, false);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> --- 4452,4458 ----
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
> ! appendStringLiteral(query, descr, false, !std_strings);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> ***************
> *** 4420,4426 ****
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
> ! appendStringLiteral(query, descr, false);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> --- 4474,4480 ----
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
> ! appendStringLiteral(query, descr, false, !std_strings);
> appendPQExpBuffer(query, ";\n");
>
> ArchiveEntry(fout, nilCatalogId, createDumpId(),
> ***************
> *** 4986,4992 ****
> {
> appendPQExpBuffer(q, ",\n DEFAULT = ");
> if (typdefault_is_literal)
> ! appendStringLiteral(q, typdefault, true);
> else
> appendPQExpBufferStr(q, typdefault);
> }
> --- 5040,5046 ----
> {
> appendPQExpBuffer(q, ",\n DEFAULT = ");
> if (typdefault_is_literal)
> ! appendStringLiteral(q, typdefault, true, !std_strings);
> else
> appendPQExpBufferStr(q, typdefault);
> }
> ***************
> *** 5005,5011 ****
> if (typdelim && strcmp(typdelim, ",") != 0)
> {
> appendPQExpBuffer(q, ",\n DELIMITER = ");
> ! appendStringLiteral(q, typdelim, true);
> }
>
> if (strcmp(typalign, "c") == 0)
> --- 5059,5065 ----
> if (typdelim && strcmp(typdelim, ",") != 0)
> {
> appendPQExpBuffer(q, ",\n DELIMITER = ");
> ! appendStringLiteral(q, typdelim, true, !std_strings);
> }
>
> if (strcmp(typalign, "c") == 0)
> ***************
> *** 5120,5126 ****
> {
> appendPQExpBuffer(q, " DEFAULT ");
> if (typdefault_is_literal)
> ! appendStringLiteral(q, typdefault, true);
> else
> appendPQExpBufferStr(q, typdefault);
> }
> --- 5174,5180 ----
> {
> appendPQExpBuffer(q, " DEFAULT ");
> if (typdefault_is_literal)
> ! appendStringLiteral(q, typdefault, true, !std_strings);
> else
> appendPQExpBufferStr(q, typdefault);
> }
> ***************
> *** 5690,5696 ****
> if (strcmp(probin, "-") != 0)
> {
> appendPQExpBuffer(asPart, "AS ");
> ! appendStringLiteral(asPart, probin, true);
> if (strcmp(prosrc, "-") != 0)
> {
> appendPQExpBuffer(asPart, ", ");
> --- 5744,5750 ----
> if (strcmp(probin, "-") != 0)
> {
> appendPQExpBuffer(asPart, "AS ");
> ! appendStringLiteral(asPart, probin, true, !std_strings);
> if (strcmp(prosrc, "-") != 0)
> {
> appendPQExpBuffer(asPart, ", ");
> ***************
> *** 5700,5706 ****
> * contains quote or backslash; else use regular quoting.
> */
> if (disable_dollar_quoting)
> ! appendStringLiteral(asPart, prosrc, false);
> else
> appendStringLiteralDQOpt(asPart, prosrc, false, NULL);
> }
> --- 5754,5760 ----
> * contains quote or backslash; else use regular quoting.
> */
> if (disable_dollar_quoting)
> ! appendStringLiteral(asPart, prosrc, false, !std_strings);
> else
> appendStringLiteralDQOpt(asPart, prosrc, false, NULL);
> }
> ***************
> *** 5712,5718 ****
> appendPQExpBuffer(asPart, "AS ");
> /* with no bin, dollar quote src unconditionally if allowed */
> if (disable_dollar_quoting)
> ! appendStringLiteral(asPart, prosrc, false);
> else
> appendStringLiteralDQ(asPart, prosrc, NULL);
> }
> --- 5766,5772 ----
> appendPQExpBuffer(asPart, "AS ");
> /* with no bin, dollar quote src unconditionally if allowed */
> if (disable_dollar_quoting)
> ! appendStringLiteral(asPart, prosrc, false, !std_strings);
> else
> appendStringLiteralDQ(asPart, prosrc, NULL);
> }
> ***************
> *** 6628,6636 ****
> appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
> (condefault) ? "DEFAULT " : "",
> fmtId(convinfo->dobj.name));
> ! appendStringLiteral(q, conforencoding, true);
> appendPQExpBuffer(q, " TO ");
> ! appendStringLiteral(q, contoencoding, true);
> /* regproc is automatically quoted in 7.3 and above */
> appendPQExpBuffer(q, " FROM %s;\n", conproc);
>
> --- 6682,6690 ----
> appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
> (condefault) ? "DEFAULT " : "",
> fmtId(convinfo->dobj.name));
> ! appendStringLiteral(q, conforencoding, true, !std_strings);
> appendPQExpBuffer(q, " TO ");
> ! appendStringLiteral(q, contoencoding, true, !std_strings);
> /* regproc is automatically quoted in 7.3 and above */
> appendPQExpBuffer(q, " FROM %s;\n", conproc);
>
> ***************
> *** 6871,6877 ****
> if (!PQgetisnull(res, 0, i_agginitval))
> {
> appendPQExpBuffer(details, ",\n INITCOND = ");
> ! appendStringLiteral(details, agginitval, true);
> }
>
> if (strcmp(aggfinalfn, "-") != 0)
> --- 6925,6931 ----
> if (!PQgetisnull(res, 0, i_agginitval))
> {
> appendPQExpBuffer(details, ",\n INITCOND = ");
> ! appendStringLiteral(details, agginitval, true, !std_strings);
> }
>
> if (strcmp(aggfinalfn, "-") != 0)
> ***************
> *** 7058,7064 ****
> {
> appendPQExpBuffer(query, "SELECT definition as viewdef "
> " from pg_views where viewname = ");
> ! appendStringLiteral(query, tbinfo->dobj.name, true);
> appendPQExpBuffer(query, ";");
> }
>
> --- 7112,7118 ----
> {
> appendPQExpBuffer(query, "SELECT definition as viewdef "
> " from pg_views where viewname = ");
> ! appendStringLiteral(query, tbinfo->dobj.name, true, !std_strings);
> appendPQExpBuffer(query, ";");
> }
>
> ***************
> *** 7707,7713 ****
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
> ! appendStringLiteral(query, dbname, true);
>
> res = PQexec(g_conn, query->data);
> check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
> --- 7761,7767 ----
>
> resetPQExpBuffer(query);
> appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
> ! appendStringLiteral(query, dbname, true, !std_strings);
>
> res = PQexec(g_conn, query->data);
> check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
> ***************
> *** 7908,7920 ****
> (owning_tab = findTableByOid(tbinfo->owning_tab)) != NULL)
> {
> appendPQExpBuffer(query, "pg_catalog.pg_get_serial_sequence(");
> ! appendStringLiteral(query, fmtId(owning_tab->dobj.name), true);
> appendPQExpBuffer(query, ", ");
> ! appendStringLiteral(query, owning_tab->attnames[tbinfo->owning_col - 1], true);
> appendPQExpBuffer(query, ")");
> }
> else
> ! appendStringLiteral(query, fmtId(tbinfo->dobj.name), true);
> appendPQExpBuffer(query, ", %s, %s);\n",
> last, (called ? "true" : "false"));
>
> --- 7962,7974 ----
> (owning_tab = findTableByOid(tbinfo->owning_tab)) != NULL)
> {
> appendPQExpBuffer(query, "pg_catalog.pg_get_serial_sequence(");
> ! appendStringLiteral(query, fmtId(owning_tab->dobj.name), true, !std_strings);
> appendPQExpBuffer(query, ", ");
> ! appendStringLiteral(query, owning_tab->attnames[tbinfo->owning_col - 1], true, !std_strings);
> appendPQExpBuffer(query, ")");
> }
> else
> ! appendStringLiteral(query, fmtId(tbinfo->dobj.name), true, !std_strings);
> appendPQExpBuffer(query, ", %s, %s);\n",
> last, (called ? "true" : "false"));
>
> ***************
> *** 8083,8090 ****
> appendPQExpBufferChar(query, '\'');
> while (s < p)
> {
> ! if (*s == '\'') /* bytea already doubles backslashes */
> appendPQExpBufferChar(query, '\'');
> appendPQExpBufferChar(query, *s++);
> }
> appendPQExpBufferChar(query, '\'');
> --- 8137,8150 ----
> appendPQExpBufferChar(query, '\'');
> while (s < p)
> {
> ! if (*s == '\'')
> appendPQExpBufferChar(query, '\'');
> + /*
> + * bytea unconditionally doubles backslashes, so we suppress
> + * the doubling for standard_conforming_strings.
> + */
> + if (std_strings && *s == '\\')
> + s++;
> appendPQExpBufferChar(query, *s++);
> }
> appendPQExpBufferChar(query, '\'');
> Index: src/bin/pg_dump/pg_dumpall.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v
> retrieving revision 1.75
> diff -c -c -r1.75 pg_dumpall.c
> *** src/bin/pg_dump/pg_dumpall.c 22 May 2006 11:21:54 -0000 1.75
> --- src/bin/pg_dump/pg_dumpall.c 25 May 2006 22:15:58 -0000
> ***************
> *** 535,541 ****
> if (!PQgetisnull(res, i, i_rolpassword))
> {
> appendPQExpBuffer(buf, " PASSWORD ");
> ! appendStringLiteral(buf, PQgetvalue(res, i, i_rolpassword), true);
> }
>
> if (!PQgetisnull(res, i, i_rolvaliduntil))
> --- 535,541 ----
> if (!PQgetisnull(res, i, i_rolpassword))
> {
> appendPQExpBuffer(buf, " PASSWORD ");
> ! appendStringLiteral(buf, PQgetvalue(res, i, i_rolpassword), true, true);
> }
>
> if (!PQgetisnull(res, i, i_rolvaliduntil))
> ***************
> *** 546,552 ****
>
> if (!PQgetisnull(res, i, i_rolcomment)) {
> appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
> ! appendStringLiteral(buf, PQgetvalue(res, i, i_rolcomment), true);
> appendPQExpBuffer(buf, ";\n");
> }
>
> --- 546,552 ----
>
> if (!PQgetisnull(res, i, i_rolcomment)) {
> appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
> ! appendStringLiteral(buf, PQgetvalue(res, i, i_rolcomment), true, true);
> appendPQExpBuffer(buf, ";\n");
> }
>
> ***************
> *** 730,736 ****
> appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
>
> appendPQExpBuffer(buf, " LOCATION ");
> ! appendStringLiteral(buf, spclocation, true);
> appendPQExpBuffer(buf, ";\n");
>
> if (!skip_acls &&
> --- 730,736 ----
> appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
>
> appendPQExpBuffer(buf, " LOCATION ");
> ! appendStringLiteral(buf, spclocation, true, true);
> appendPQExpBuffer(buf, ";\n");
>
> if (!skip_acls &&
> ***************
> *** 745,751 ****
>
> if (spccomment && strlen(spccomment)) {
> appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
> ! appendStringLiteral(buf, spccomment, true);
> appendPQExpBuffer(buf, ";\n");
> }
>
> --- 745,751 ----
>
> if (spccomment && strlen(spccomment)) {
> appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
> ! appendStringLiteral(buf, spccomment, true, true);
> appendPQExpBuffer(buf, ";\n");
> }
>
> ***************
> *** 868,874 ****
> appendPQExpBuffer(buf, " OWNER = %s", fmtId(dbowner));
>
> appendPQExpBuffer(buf, " ENCODING = ");
> ! appendStringLiteral(buf, dbencoding, true);
>
> /* Output tablespace if it isn't default */
> if (strcmp(dbtablespace, "pg_default") != 0)
> --- 868,874 ----
> appendPQExpBuffer(buf, " OWNER = %s", fmtId(dbowner));
>
> appendPQExpBuffer(buf, " ENCODING = ");
> ! appendStringLiteral(buf, dbencoding, true, true);
>
> /* Output tablespace if it isn't default */
> if (strcmp(dbtablespace, "pg_default") != 0)
> ***************
> *** 884,890 ****
> if (strcmp(dbistemplate, "t") == 0)
> {
> appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 't' WHERE datname = ");
> ! appendStringLiteral(buf, dbname, true);
> appendPQExpBuffer(buf, ";\n");
> }
> }
> --- 884,890 ----
> if (strcmp(dbistemplate, "t") == 0)
> {
> appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 't' WHERE datname = ");
> ! appendStringLiteral(buf, dbname, true, true);
> appendPQExpBuffer(buf, ";\n");
> }
> }
> ***************
> *** 929,935 ****
> PGresult *res;
>
> printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
> ! appendStringLiteral(buf, dbname, true);
> appendPQExpBuffer(buf, ";");
>
> res = executeQuery(conn, buf->data);
> --- 929,935 ----
> PGresult *res;
>
> printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
> ! appendStringLiteral(buf, dbname, true, true);
> appendPQExpBuffer(buf, ";");
>
> res = executeQuery(conn, buf->data);
> ***************
> *** 968,974 ****
> printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count);
> else
> printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
> ! appendStringLiteral(buf, username, true);
>
> res = executeQuery(conn, buf->data);
> if (PQntuples(res) == 1 &&
> --- 968,974 ----
> printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM pg_authid WHERE rolname = ", count);
> else
> printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
> ! appendStringLiteral(buf, username, true, true);
>
> res = executeQuery(conn, buf->data);
> if (PQntuples(res) == 1 &&
> ***************
> *** 1016,1022 ****
> || pg_strcasecmp(mine, "search_path") == 0)
> appendPQExpBuffer(buf, "%s", pos + 1);
> else
> ! appendStringLiteral(buf, pos + 1, false);
> appendPQExpBuffer(buf, ";\n");
>
> printf("%s", buf->data);
> --- 1016,1022 ----
> || pg_strcasecmp(mine, "search_path") == 0)
> appendPQExpBuffer(buf, "%s", pos + 1);
> else
> ! appendStringLiteral(buf, pos + 1, false, true);
> appendPQExpBuffer(buf, ";\n");
>
> printf("%s", buf->data);
> Index: src/bin/psql/describe.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/psql/describe.c,v
> retrieving revision 1.134
> diff -c -c -r1.134 describe.c
> *** src/bin/psql/describe.c 26 Apr 2006 23:15:45 -0000 1.134
> --- src/bin/psql/describe.c 25 May 2006 22:15:59 -0000
> ***************
> *** 1867,1873 ****
> appendPQExpBuffer(&namebuf, "\\\\");
>
> /* Ensure chars special to string literals are passed properly */
> ! if (SQL_STR_DOUBLE(*cp))
> appendPQExpBufferChar(&namebuf, *cp);
>
> i = PQmblen(cp, pset.encoding);
> --- 1867,1873 ----
> appendPQExpBuffer(&namebuf, "\\\\");
>
> /* Ensure chars special to string literals are passed properly */
> ! if (SQL_STR_DOUBLE(*cp, true))
> appendPQExpBufferChar(&namebuf, *cp);
>
> i = PQmblen(cp, pset.encoding);
> Index: src/bin/psql/large_obj.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/psql/large_obj.c,v
> retrieving revision 1.41
> diff -c -c -r1.41 large_obj.c
> *** src/bin/psql/large_obj.c 5 Mar 2006 15:58:51 -0000 1.41
> --- src/bin/psql/large_obj.c 25 May 2006 22:15:59 -0000
> ***************
> *** 178,187 ****
>
> if (strchr(comment_arg, '\\') != NULL)
> *bufptr++ = ESCAPE_STRING_SYNTAX;
> *bufptr++ = '\'';
> for (i = 0; i < slen; i++)
> {
> ! if (SQL_STR_DOUBLE(comment_arg[i]))
> *bufptr++ = comment_arg[i];
> *bufptr++ = comment_arg[i];
> }
> --- 178,188 ----
>
> if (strchr(comment_arg, '\\') != NULL)
> *bufptr++ = ESCAPE_STRING_SYNTAX;
> +
> *bufptr++ = '\'';
> for (i = 0; i < slen; i++)
> {
> ! if (SQL_STR_DOUBLE(comment_arg[i], true))
> *bufptr++ = comment_arg[i];
> *bufptr++ = comment_arg[i];
> }
> Index: src/bin/scripts/createdb.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/scripts/createdb.c,v
> retrieving revision 1.16
> diff -c -c -r1.16 createdb.c
> *** src/bin/scripts/createdb.c 5 Mar 2006 15:58:52 -0000 1.16
> --- src/bin/scripts/createdb.c 25 May 2006 22:15:59 -0000
> ***************
> *** 184,190 ****
> if (comment)
> {
> printfPQExpBuffer(&sql, "COMMENT ON DATABASE %s IS ", fmtId(dbname));
> ! appendStringLiteral(&sql, comment, false);
> appendPQExpBuffer(&sql, ";\n");
>
> conn = connectDatabase(dbname, host, port, username, password, progname);
> --- 184,190 ----
> if (comment)
> {
> printfPQExpBuffer(&sql, "COMMENT ON DATABASE %s IS ", fmtId(dbname));
> ! appendStringLiteral(&sql, comment, false, true);
> appendPQExpBuffer(&sql, ";\n");
>
> conn = connectDatabase(dbname, host, port, username, password, progname);
> Index: src/bin/scripts/createuser.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/scripts/createuser.c,v
> retrieving revision 1.27
> diff -c -c -r1.27 createuser.c
> *** src/bin/scripts/createuser.c 5 Mar 2006 15:58:52 -0000 1.27
> --- src/bin/scripts/createuser.c 25 May 2006 22:15:59 -0000
> ***************
> *** 258,268 ****
> fprintf(stderr, _("Password encryption failed.\n"));
> exit(1);
> }
> ! appendStringLiteral(&sql, encrypted_password, false);
> PQfreemem(encrypted_password);
> }
> else
> ! appendStringLiteral(&sql, newpassword, false);
> }
> if (superuser == TRI_YES)
> appendPQExpBuffer(&sql, " SUPERUSER");
> --- 258,268 ----
> fprintf(stderr, _("Password encryption failed.\n"));
> exit(1);
> }
> ! appendStringLiteral(&sql, encrypted_password, false, true);
> PQfreemem(encrypted_password);
> }
> else
> ! appendStringLiteral(&sql, newpassword, false, true);
> }
> if (superuser == TRI_YES)
> appendPQExpBuffer(&sql, " SUPERUSER");
> Index: src/include/c.h
> ===================================================================
> RCS file: /cvsroot/pgsql/src/include/c.h,v
> retrieving revision 1.200
> diff -c -c -r1.200 c.h
> *** src/include/c.h 14 Apr 2006 03:38:56 -0000 1.200
> --- src/include/c.h 25 May 2006 22:15:59 -0000
> ***************
> *** 472,478 ****
>
> #define NameStr(name) ((name).data)
>
> ! #define SQL_STR_DOUBLE(ch) ((ch) == '\'' || (ch) == '\\')
> #define ESCAPE_STRING_SYNTAX 'E'
>
> /* ----------------------------------------------------------------
> --- 472,485 ----
>
> #define NameStr(name) ((name).data)
>
> ! /*
> ! * In 8.2, we are warning for \ in a non-E string if std_strings are off.
> ! * For this reason, we use E for \ strings, unless standard_conforming_strings
> ! * is on.
> ! */
> ! #define SQL_STR_DOUBLE(ch, escape_backslash) \
> ! ((ch) == '\'' || ((escape_backslash) && (ch) == '\\'))
> !
> #define ESCAPE_STRING_SYNTAX 'E'
>
> /* ----------------------------------------------------------------
> Index: src/interfaces/ecpg/ecpglib/execute.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v
> retrieving revision 1.45
> diff -c -c -r1.45 execute.c
> *** src/interfaces/ecpg/ecpglib/execute.c 24 Apr 2006 09:45:22 -0000 1.45
> --- src/interfaces/ecpg/ecpglib/execute.c 25 May 2006 22:16:02 -0000
> ***************
> *** 32,39 ****
> #include "pgtypes_timestamp.h"
> #include "pgtypes_interval.h"
>
> ! /* This function returns a newly malloced string that has the \
> ! in the argument quoted with \ and the ' quoted with ' as SQL92 says.
> */
> static char *
> quote_postgres(char *arg, int lineno)
> --- 32,40 ----
> #include "pgtypes_timestamp.h"
> #include "pgtypes_interval.h"
>
> ! /*
> ! * This function returns a newly malloced string that has ' and \
> ! * escaped.
> */
> static char *
> quote_postgres(char *arg, int lineno)
> ***************
> *** 45,57 ****
> if (!res)
> return (res);
>
> if (strchr(arg, '\\') != NULL)
> res[ri++] = ESCAPE_STRING_SYNTAX;
> res[ri++] = '\'';
>
> for (i = 0; arg[i]; i++, ri++)
> {
> ! if (SQL_STR_DOUBLE(arg[i]))
> res[ri++] = arg[i];
> res[ri] = arg[i];
> }
> --- 46,62 ----
> if (!res)
> return (res);
>
> + /*
> + * We don't know if the target database is using
> + * standard_conforming_strings, so we always use E'' strings.
> + */
> if (strchr(arg, '\\') != NULL)
> res[ri++] = ESCAPE_STRING_SYNTAX;
> res[ri++] = '\'';
>
> for (i = 0; arg[i]; i++, ri++)
> {
> ! if (SQL_STR_DOUBLE(arg[i], true))
> res[ri++] = arg[i];
> res[ri] = arg[i];
> }
> Index: src/pl/plpgsql/src/gram.y
> ===================================================================
> RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v
> retrieving revision 1.88
> diff -c -c -r1.88 gram.y
> *** src/pl/plpgsql/src/gram.y 23 Mar 2006 04:22:36 -0000 1.88
> --- src/pl/plpgsql/src/gram.y 25 May 2006 22:16:05 -0000
> ***************
> *** 17,22 ****
> --- 17,23 ----
> #include "plpgsql.h"
>
> #include "parser/parser.h"
> + #include "parser/gramparse.h"
>
> static PLpgSQL_expr *read_sql_construct(int until,
> int until2,
> ***************
> *** 376,387 ****
> strcpy(buf, "SELECT ");
> cp1 = new->refname;
> cp2 = buf + strlen(buf);
> ! if (strchr(cp1, '\\') != NULL)
> *cp2++ = ESCAPE_STRING_SYNTAX;
> *cp2++ = '\'';
> while (*cp1)
> {
> ! if (SQL_STR_DOUBLE(*cp1))
> *cp2++ = *cp1;
> *cp2++ = *cp1++;
> }
> --- 377,388 ----
> strcpy(buf, "SELECT ");
> cp1 = new->refname;
> cp2 = buf + strlen(buf);
> ! if (!standard_conforming_strings && strchr(cp1, '\\') != NULL)
> *cp2++ = ESCAPE_STRING_SYNTAX;
> *cp2++ = '\'';
> while (*cp1)
> {
> ! if (SQL_STR_DOUBLE(*cp1, !standard_conforming_strings))
> *cp2++ = *cp1;
> *cp2++ = *cp1++;
> }

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend

--
Bruce Momjian http://candle.pha.pa.us
EnterpriseDB http://www.enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

In response to

Browse pgsql-patches by date

  From Date Subject
Next Message Andrew Dunstan 2006-05-27 22:23:40 tg_table_name and tg_table_schema for plpgsql
Previous Message Tom Lane 2006-05-26 19:51:51 Re: Binary COPY for psql