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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy