Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit134b463

Browse files
committed
Fix up pg_dump to do string escaping fully correctly for client encoding
and standard_conforming_strings; likewise for the other client programsthat need it. As per previous discussion, a pg_dump dump now conformsto the standard_conforming_strings setting of the source database.We don't use E'' syntax in the dump, thereby improving portability ofthe SQL. I added a SET escape_strings_warning = off command to keepthe dumps from getting a lot of back-chatter from that.
1 parent117d73a commit134b463

File tree

15 files changed

+378
-304
lines changed

15 files changed

+378
-304
lines changed

‎src/backend/utils/adt/quote.c

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

1616
#include"utils/builtins.h"
17-
#include"parser/gramparse.h"
1817

1918

2019
/*
@@ -49,6 +48,12 @@ quote_ident(PG_FUNCTION_ARGS)
4948
/*
5049
* quote_literal -
5150
* returns a properly quoted literal
51+
*
52+
* NOTE: think not to make this function's behavior change with
53+
* standard_conforming_strings. We don't know where the result
54+
* literal will be used, and so we must generate a result that
55+
* will work with either setting. Take a look at what dblink
56+
* uses this for before thinking you know better.
5257
*/
5358
Datum
5459
quote_literal(PG_FUNCTION_ARGS)
@@ -66,20 +71,22 @@ quote_literal(PG_FUNCTION_ARGS)
6671
cp1=VARDATA(t);
6772
cp2=VARDATA(result);
6873

69-
if (!standard_conforming_strings)
70-
for (;len-->0;cp1++)
71-
if (*cp1=='\\')
72-
{
73-
*cp2++=ESCAPE_STRING_SYNTAX;
74-
break;
75-
}
74+
for (;len-->0;cp1++)
75+
{
76+
if (*cp1=='\\')
77+
{
78+
*cp2++=ESCAPE_STRING_SYNTAX;
79+
break;
80+
}
81+
}
7682

7783
len=VARSIZE(t)-VARHDRSZ;
7884
cp1=VARDATA(t);
85+
7986
*cp2++='\'';
8087
while (len-->0)
8188
{
82-
if (SQL_STR_DOUBLE(*cp1,!standard_conforming_strings))
89+
if (SQL_STR_DOUBLE(*cp1,true))
8390
*cp2++=*cp1;
8491
*cp2++=*cp1++;
8592
}

‎src/backend/utils/adt/ruleutils.c

Lines changed: 19 additions & 29 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.222 2006/05/26 23:48:54 momjian Exp $
5+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.223 2006/05/28 21:13:53 tgl Exp $
66
**********************************************************************/
77

88
#include"postgres.h"
@@ -534,18 +534,23 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
534534
{
535535
if (i>0)
536536
appendStringInfo(&buf,", ");
537-
if (!standard_conforming_strings&&strchr(p,'\\')!=NULL)
538-
appendStringInfoChar(&buf,ESCAPE_STRING_SYNTAX);
537+
/*
538+
* We form the string literal according to the prevailing setting
539+
* of standard_conforming_strings; we never use E''.
540+
* User is responsible for making sure result is used correctly.
541+
*/
539542
appendStringInfoChar(&buf,'\'');
540-
541543
while (*p)
542544
{
543-
if (SQL_STR_DOUBLE(*p, !standard_conforming_strings))
544-
appendStringInfoChar(&buf,*p);
545-
appendStringInfoChar(&buf,*p++);
545+
charch=*p++;
546+
547+
if (SQL_STR_DOUBLE(ch, !standard_conforming_strings))
548+
appendStringInfoChar(&buf,ch);
549+
appendStringInfoChar(&buf,ch);
546550
}
547-
p++;
548551
appendStringInfoChar(&buf,'\'');
552+
/* advance p to next string embedded in tgargs */
553+
p++;
549554
}
550555
}
551556

@@ -3883,8 +3888,7 @@ get_const_expr(Const *constval, deparse_context *context)
38833888
char*valptr;
38843889
boolisfloat= false;
38853890
boolneedlabel;
3886-
boolis_e_string= false;
3887-
3891+
38883892
if (constval->constisnull)
38893893
{
38903894
/*
@@ -3946,32 +3950,18 @@ get_const_expr(Const *constval, deparse_context *context)
39463950
default:
39473951

39483952
/*
3949-
* We must quote any funny characters in the constant's
3950-
* representation. XXX Any MULTIBYTE considerations here?
3953+
* We form the string literal according to the prevailing setting
3954+
* of standard_conforming_strings; we never use E''.
3955+
* User is responsible for making sure result is used correctly.
39513956
*/
3952-
for (valptr=extval;*valptr;valptr++)
3953-
if ((!standard_conforming_strings&&*valptr=='\\')||
3954-
(unsignedchar)*valptr< (unsignedchar)' ')
3955-
{
3956-
appendStringInfoChar(buf,ESCAPE_STRING_SYNTAX);
3957-
is_e_string= true;
3958-
break;
3959-
}
3960-
39613957
appendStringInfoChar(buf,'\'');
39623958
for (valptr=extval;*valptr;valptr++)
39633959
{
39643960
charch=*valptr;
39653961

3966-
if (SQL_STR_DOUBLE(ch,is_e_string))
3967-
{
3968-
appendStringInfoChar(buf,ch);
3969-
appendStringInfoChar(buf,ch);
3970-
}
3971-
elseif ((unsignedchar)ch< (unsignedchar)' ')
3972-
appendStringInfo(buf,"\\%03o", (int)ch);
3973-
else
3962+
if (SQL_STR_DOUBLE(ch, !standard_conforming_strings))
39743963
appendStringInfoChar(buf,ch);
3964+
appendStringInfoChar(buf,ch);
39753965
}
39763966
appendStringInfoChar(buf,'\'');
39773967
break;

‎src/bin/pg_dump/dumputils.c

Lines changed: 84 additions & 59 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.28 2006/05/26 23:48:54momjian Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.29 2006/05/28 21:13:54tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -100,63 +100,102 @@ fmtId(const char *rawid)
100100

101101
/*
102102
* Convert a string value to an SQL string literal and append it to
103-
* the given buffer.
103+
* the given buffer. We assume the specified client_encoding and
104+
* standard_conforming_strings settings.
104105
*
105-
* Special characters are escaped. Quote mark ' goes to '' per SQL
106-
* standard, other stuff goes to \ sequences. If escapeAll is false,
107-
* whitespace characters are not escaped (tabs, newlines, etc.). This
108-
* is appropriate for dump file output. Using E'' strings for
109-
* backslashes is always safe for standard_conforming_strings on or off.
106+
* This is essentially equivalent to libpq's PQescapeStringInternal,
107+
* except for the output buffer structure. We need it in situations
108+
* where we do not have a PGconn available. Where we do,
109+
* appendStringLiteralConn is a better choice.
110110
*/
111111
void
112-
appendStringLiteral(PQExpBufferbuf,constchar*str,boolescapeAll,
113-
boole_string_for_backslash)
112+
appendStringLiteral(PQExpBufferbuf,constchar*str,
113+
intencoding,boolstd_strings)
114114
{
115-
charch;
116-
constchar*p;
117-
boolis_e_string= false;
115+
size_tlength=strlen(str);
116+
constchar*source=str;
117+
char*target;
118118

119-
for (p=str;*p;p++)
119+
if (!enlargePQExpBuffer(buf,2*length+2))
120+
return;
121+
122+
target=buf->data+buf->len;
123+
*target++='\'';
124+
125+
while (*source!='\0')
120126
{
121-
ch=*p;
127+
charc=*source;
128+
intlen;
129+
inti;
122130

123-
if ((e_string_for_backslash&&ch=='\\')||
124-
((unsignedchar)ch< (unsignedchar)' '&&
125-
(escapeAll||
126-
(ch!='\t'&&ch!='\n'&&ch!='\v'&&
127-
ch!='\f'&&ch!='\r'))))
131+
/* Fast path for plain ASCII */
132+
if (!IS_HIGHBIT_SET(c))
128133
{
129-
appendPQExpBufferChar(buf,ESCAPE_STRING_SYNTAX);
130-
is_e_string= true;
131-
break;
134+
/* Apply quoting if needed */
135+
if (SQL_STR_DOUBLE(c, !std_strings))
136+
*target++=c;
137+
/* Copy the character */
138+
*target++=c;
139+
source++;
140+
continue;
132141
}
133-
}
134142

135-
appendPQExpBufferChar(buf,'\'');
136-
for (p=str;*p;p++)
137-
{
138-
ch=*p;
139-
if (SQL_STR_DOUBLE(ch,is_e_string))
143+
/* Slow path for possible multibyte characters */
144+
len=PQmblen(source,encoding);
145+
146+
/* Copy the character */
147+
for (i=0;i<len;i++)
140148
{
141-
appendPQExpBufferChar(buf,ch);
142-
appendPQExpBufferChar(buf,ch);
149+
if (*source=='\0')
150+
break;
151+
*target++=*source++;
143152
}
144-
elseif ((unsignedchar)ch< (unsignedchar)' '&&
145-
(escapeAll||
146-
(ch!='\t'&&ch!='\n'&&ch!='\v'&&
147-
ch!='\f'&&ch!='\r')))
153+
154+
/*
155+
* If we hit premature end of string (ie, incomplete multibyte
156+
* character), try to pad out to the correct length with spaces.
157+
* We may not be able to pad completely, but we will always be able
158+
* to insert at least one pad space (since we'd not have quoted a
159+
* multibyte character). This should be enough to make a string that
160+
* the server will error out on.
161+
*/
162+
if (i<len)
148163
{
149-
/*
150-
* generate octal escape for control chars other than whitespace
151-
*/
152-
appendPQExpBufferChar(buf,'\\');
153-
appendPQExpBufferChar(buf, ((ch >>6)&3)+'0');
154-
appendPQExpBufferChar(buf, ((ch >>3)&7)+'0');
155-
appendPQExpBufferChar(buf, (ch&7)+'0');
164+
char*stop=buf->data+buf->maxlen-2;
165+
166+
for (;i<len;i++)
167+
{
168+
if (target >=stop)
169+
break;
170+
*target++=' ';
171+
}
172+
break;
156173
}
157-
else
158-
appendPQExpBufferChar(buf,ch);
159174
}
175+
176+
/* Write the terminating quote and NUL character. */
177+
*target++='\'';
178+
*target='\0';
179+
180+
buf->len=target-buf->data;
181+
}
182+
183+
184+
/*
185+
* Convert a string value to an SQL string literal and append it to
186+
* the given buffer. Encoding and string syntax rules are as indicated
187+
* by current settings of the PGconn.
188+
*/
189+
void
190+
appendStringLiteralConn(PQExpBufferbuf,constchar*str,PGconn*conn)
191+
{
192+
size_tlength=strlen(str);
193+
194+
if (!enlargePQExpBuffer(buf,2*length+2))
195+
return;
196+
appendPQExpBufferChar(buf,'\'');
197+
buf->len+=PQescapeStringConn(conn,buf->data+buf->len,
198+
str,length,NULL);
160199
appendPQExpBufferChar(buf,'\'');
161200
}
162201

@@ -167,7 +206,8 @@ appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll,
167206
* dollar quote delimiter will begin with that (after the opening $).
168207
*
169208
* No escaping is done at all on str, in compliance with the rules
170-
* for parsing dollar quoted strings.
209+
* for parsing dollar quoted strings. Also, we need not worry about
210+
* encoding issues.
171211
*/
172212
void
173213
appendStringLiteralDQ(PQExpBufferbuf,constchar*str,constchar*dqprefix)
@@ -204,21 +244,6 @@ appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
204244
}
205245

206246

207-
/*
208-
* Use dollar quoting if the string to be quoted contains ' or \,
209-
* otherwise use standard quoting.
210-
*/
211-
void
212-
appendStringLiteralDQOpt(PQExpBufferbuf,constchar*str,
213-
boolescapeAll,constchar*dqprefix)
214-
{
215-
if (strchr(str,'\'')==NULL&&strchr(str,'\\')==NULL)
216-
appendStringLiteral(buf,str,escapeAll, true);
217-
else
218-
appendStringLiteralDQ(buf,str,dqprefix);
219-
}
220-
221-
222247
/*
223248
* Convert backend's version string into a number.
224249
*/

‎src/bin/pg_dump/dumputils.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,24 @@
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.16 2006/05/26 23:48:54momjian Exp $
10+
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.17 2006/05/28 21:13:54tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
1414

1515
#ifndefDUMPUTILS_H
1616
#defineDUMPUTILS_H
1717

18+
#include"libpq-fe.h"
1819
#include"pqexpbuffer.h"
1920

2021
externconstchar*fmtId(constchar*identifier);
2122
externvoidappendStringLiteral(PQExpBufferbuf,constchar*str,
22-
boolescapeAll,boole_string_for_backslash);
23+
intencoding,boolstd_strings);
24+
externvoidappendStringLiteralConn(PQExpBufferbuf,constchar*str,
25+
PGconn*conn);
2326
externvoidappendStringLiteralDQ(PQExpBufferbuf,constchar*str,
2427
constchar*dqprefix);
25-
externvoidappendStringLiteralDQOpt(PQExpBufferbuf,constchar*str,
26-
boolescapeAll,constchar*dqprefix);
2728
externintparse_version(constchar*versionString);
2829
externboolparsePGArray(constchar*atext,char***itemarray,int*nitems);
2930
externboolbuildACLCommands(constchar*name,constchar*type,

‎src/bin/pg_dump/pg_backup.h

Lines changed: 8 additions & 1 deletion
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.h,v 1.38 2006/02/12 04:04:32 momjian Exp $
18+
*$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup.h,v 1.39 2006/05/28 21:13:54 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -60,6 +60,10 @@ typedef struct _Archive
6060
intminRemoteVersion;/* allowable range */
6161
intmaxRemoteVersion;
6262

63+
/* info needed for string escaping */
64+
intencoding;/* libpq code for client_encoding */
65+
boolstd_strings;/* standard_conforming_strings */
66+
6367
/* error handling */
6468
boolexit_on_error;/* whether to exit on SQL errors... */
6569
intn_errors;/* number of errors (if no die) */
@@ -182,4 +186,7 @@ archprintf(Archive *AH, const char *fmt,...)
182186
/* This extension allows gcc to check the format string */
183187
__attribute__((format(printf,2,3)));
184188

189+
#defineappendStringLiteralAH(buf,str,AH) \
190+
appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings)
191+
185192
#endif/* PG_BACKUP_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp