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++; }