Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7a846ec

Browse files
committed
Use E'' strings internally only when standard_conforming_strings =
'off'. This allows 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 value to pg_dump. I also added standard backslash handling for plpgsql.
1 parent 4d63e26 commit 7a846ec

File tree

15 files changed

+174
-89
lines changed

15 files changed

+174
-89
lines changed

src/backend/utils/adt/quote.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.18 2006/03/05 15:58:43 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.19 2006/05/26 23:48:54 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
1414
#include "postgres.h"
1515

1616
#include "utils/builtins.h"
17+
#include "parser/gramparse.h"
1718

1819

1920
/*
@@ -65,19 +66,20 @@ quote_literal(PG_FUNCTION_ARGS)
6566
cp1 = VARDATA(t);
6667
cp2 = VARDATA(result);
6768

68-
for (; len-- > 0; cp1++)
69-
if (*cp1 == '\\')
70-
{
71-
*cp2++ = ESCAPE_STRING_SYNTAX;
72-
break;
73-
}
69+
if (!standard_conforming_strings)
70+
for (; len-- > 0; cp1++)
71+
if (*cp1 == '\\')
72+
{
73+
*cp2++ = ESCAPE_STRING_SYNTAX;
74+
break;
75+
}
7476

7577
len = VARSIZE(t) - VARHDRSZ;
7678
cp1 = VARDATA(t);
7779
*cp2++ = '\'';
7880
while (len-- > 0)
7981
{
80-
if (SQL_STR_DOUBLE(*cp1))
82+
if (SQL_STR_DOUBLE(*cp1, !standard_conforming_strings))
8183
*cp2++ = *cp1;
8284
*cp2++ = *cp1++;
8385
}

src/backend/utils/adt/ruleutils.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* ruleutils.c - Functions to convert stored expressions/querytrees
33
* back to source text
44
*
5-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.221 2006/04/30 18:30:40 tgl Exp $
5+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.222 2006/05/26 23:48:54 momjian Exp $
66
**********************************************************************/
77

88
#include "postgres.h"
@@ -31,6 +31,7 @@
3131
#include "nodes/makefuncs.h"
3232
#include "optimizer/clauses.h"
3333
#include "optimizer/tlist.h"
34+
#include "parser/gramparse.h"
3435
#include "parser/keywords.h"
3536
#include "parser/parse_expr.h"
3637
#include "parser/parse_func.h"
@@ -533,13 +534,13 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
533534
{
534535
if (i > 0)
535536
appendStringInfo(&buf, ", ");
536-
if (strchr(p, '\\') != NULL)
537+
if (!standard_conforming_strings && strchr(p, '\\') != NULL)
537538
appendStringInfoChar(&buf, ESCAPE_STRING_SYNTAX);
538539
appendStringInfoChar(&buf, '\'');
539540

540541
while (*p)
541542
{
542-
if (SQL_STR_DOUBLE(*p))
543+
if (SQL_STR_DOUBLE(*p, !standard_conforming_strings))
543544
appendStringInfoChar(&buf, *p);
544545
appendStringInfoChar(&buf, *p++);
545546
}
@@ -3882,7 +3883,8 @@ get_const_expr(Const *constval, deparse_context *context)
38823883
char *valptr;
38833884
bool isfloat = false;
38843885
bool needlabel;
3885-
3886+
bool is_e_string = false;
3887+
38863888
if (constval->constisnull)
38873889
{
38883890
/*
@@ -3948,10 +3950,11 @@ get_const_expr(Const *constval, deparse_context *context)
39483950
* representation. XXX Any MULTIBYTE considerations here?
39493951
*/
39503952
for (valptr = extval; *valptr; valptr++)
3951-
if (*valptr == '\\' ||
3953+
if ((!standard_conforming_strings && *valptr == '\\') ||
39523954
(unsigned char) *valptr < (unsigned char) ' ')
39533955
{
39543956
appendStringInfoChar(buf, ESCAPE_STRING_SYNTAX);
3957+
is_e_string = true;
39553958
break;
39563959
}
39573960

@@ -3960,7 +3963,7 @@ get_const_expr(Const *constval, deparse_context *context)
39603963
{
39613964
char ch = *valptr;
39623965

3963-
if (SQL_STR_DOUBLE(ch))
3966+
if (SQL_STR_DOUBLE(ch, is_e_string))
39643967
{
39653968
appendStringInfoChar(buf, ch);
39663969
appendStringInfoChar(buf, ch);

src/bin/initdb/initdb.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
* Portions taken from FreeBSD.
4444
*
45-
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.114 2006/03/21 17:54:28 alvherre Exp $
45+
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.115 2006/05/26 23:48:54 momjian Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -2103,7 +2103,8 @@ check_ok(void)
21032103
}
21042104

21052105
/*
2106-
* Escape any single quotes or backslashes in given string
2106+
* Escape any single quotes or backslashes in given string;
2107+
* postgresql.conf always enables backslash escapes
21072108
*/
21082109
static char *
21092110
escape_quotes(const char *src)
@@ -2115,7 +2116,7 @@ escape_quotes(const char *src)
21152116

21162117
for (i = 0, j = 0; i < len; i++)
21172118
{
2118-
if (SQL_STR_DOUBLE(src[i]))
2119+
if (SQL_STR_DOUBLE(src[i], true))
21192120
result[j++] = src[i];
21202121
result[j++] = src[i];
21212122
}

src/bin/pg_dump/dumputils.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.27 2006/04/30 21:15:33 tgl Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.28 2006/05/26 23:48:54 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -105,24 +105,29 @@ fmtId(const char *rawid)
105105
* Special characters are escaped. Quote mark ' goes to '' per SQL
106106
* standard, other stuff goes to \ sequences. If escapeAll is false,
107107
* whitespace characters are not escaped (tabs, newlines, etc.). This
108-
* is appropriate for dump file output.
108+
* is appropriate for dump file output. Using E'' strings for
109+
* backslashes is always safe for standard_conforming_strings on or off.
109110
*/
110111
void
111-
appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
112+
appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll,
113+
bool e_string_for_backslash)
112114
{
113115
char ch;
114116
const char *p;
117+
bool is_e_string = false;
115118

116119
for (p = str; *p; p++)
117120
{
118121
ch = *p;
119-
if (ch == '\\' ||
122+
123+
if ((e_string_for_backslash && ch == '\\') ||
120124
((unsigned char) ch < (unsigned char) ' ' &&
121125
(escapeAll ||
122126
(ch != '\t' && ch != '\n' && ch != '\v' &&
123127
ch != '\f' && ch != '\r'))))
124128
{
125129
appendPQExpBufferChar(buf, ESCAPE_STRING_SYNTAX);
130+
is_e_string = true;
126131
break;
127132
}
128133
}
@@ -131,7 +136,7 @@ appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
131136
for (p = str; *p; p++)
132137
{
133138
ch = *p;
134-
if (SQL_STR_DOUBLE(ch))
139+
if (SQL_STR_DOUBLE(ch, is_e_string))
135140
{
136141
appendPQExpBufferChar(buf, ch);
137142
appendPQExpBufferChar(buf, ch);
@@ -208,7 +213,7 @@ appendStringLiteralDQOpt(PQExpBuffer buf, const char *str,
208213
bool escapeAll, const char *dqprefix)
209214
{
210215
if (strchr(str, '\'') == NULL && strchr(str, '\\') == NULL)
211-
appendStringLiteral(buf, str, escapeAll);
216+
appendStringLiteral(buf, str, escapeAll, true);
212217
else
213218
appendStringLiteralDQ(buf, str, dqprefix);
214219
}

src/bin/pg_dump/dumputils.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.15 2006/03/05 15:58:50 momjian Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.16 2006/05/26 23:48:54 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,10 +17,9 @@
1717

1818
#include "pqexpbuffer.h"
1919

20-
2120
extern const char *fmtId(const char *identifier);
2221
extern void appendStringLiteral(PQExpBuffer buf, const char *str,
23-
bool escapeAll);
22+
bool escapeAll, bool e_string_for_backslash);
2423
extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str,
2524
const char *dqprefix);
2625
extern void appendStringLiteralDQOpt(PQExpBuffer buf, const char *str,

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.129 2006/05/24 21:20:11 tgl Exp $
18+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.130 2006/05/26 23:48:54 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1900,9 +1900,11 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
19001900
{
19011901
teReqs res = REQ_ALL;
19021902

1903-
/* ENCODING objects are dumped specially, so always reject here */
1903+
/* ENCODING and STDSTRINGS objects are dumped specially, so always reject */
19041904
if (strcmp(te->desc, "ENCODING") == 0)
19051905
return 0;
1906+
if (strcmp(te->desc, "STDSTRINGS") == 0)
1907+
return 0;
19061908

19071909
/* If it's an ACL, maybe ignore it */
19081910
if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0)
@@ -2005,15 +2007,14 @@ _doSetFixedOutputState(ArchiveHandle *AH)
20052007
{
20062008
TocEntry *te;
20072009

2008-
/* If we have an encoding setting, emit that */
2010+
/* If we have an encoding or std_strings setting, emit that */
20092011
te = AH->toc->next;
20102012
while (te != AH->toc)
20112013
{
20122014
if (strcmp(te->desc, "ENCODING") == 0)
2013-
{
20142015
ahprintf(AH, "%s", te->defn);
2015-
break;
2016-
}
2016+
if (strcmp(te->desc, "STDSTRINGS") == 0)
2017+
ahprintf(AH, "%s", te->defn);
20172018
te = te->next;
20182019
}
20192020

@@ -2042,7 +2043,7 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user)
20422043
* SQL requires a string literal here. Might as well be correct.
20432044
*/
20442045
if (user && *user)
2045-
appendStringLiteral(cmd, user, false);
2046+
appendStringLiteral(cmd, user, false, true);
20462047
else
20472048
appendPQExpBuffer(cmd, "DEFAULT");
20482049
appendPQExpBuffer(cmd, ";");

0 commit comments

Comments
 (0)