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

Commitea608bf

Browse files
committed
pg_dump failed to handle backslashes embedded in function definitions
(and most other places where it needed to output a string literal, too,except for data INSERT statements). Per bug report from Easter, 12/1/00.
1 parent60500d5 commitea608bf

File tree

1 file changed

+105
-108
lines changed

1 file changed

+105
-108
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 105 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.183 2000/12/03 20:45:37 tgl Exp $
25+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.184 2001/01/04 01:23:47 tgl Exp $
2626
*
2727
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
2828
*
@@ -138,7 +138,7 @@ static void dumpTriggers(Archive *fout, const char *tablename,
138138
TableInfo*tblinfo,intnumTables);
139139
staticvoiddumpRules(Archive*fout,constchar*tablename,
140140
TableInfo*tblinfo,intnumTables);
141-
staticchar*checkForQuote(constchar*s);
141+
staticvoidformatStringLiteral(PQExpBufferbuf,constchar*str);
142142
staticvoidclearTableInfo(TableInfo*,int);
143143
staticvoiddumpOneFunc(Archive*fout,FuncInfo*finfo,inti,
144144
TypeInfo*tinfo,intnumTypes);
@@ -434,7 +434,6 @@ dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
434434
PQExpBufferq=createPQExpBuffer();
435435
inttuple;
436436
intfield;
437-
constchar*expsrc;
438437

439438
appendPQExpBuffer(q,"SELECT * FROM %s",fmtId(classname,force_quotes));
440439
res=PQexec(g_conn,q->data);
@@ -492,32 +491,10 @@ dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
492491
/*
493492
* All other types are printed as string literals,
494493
* with appropriate escaping of special characters.
495-
* Quote mark ' goes to '' per SQL standard, other
496-
* stuff goes to \ sequences.
497494
*/
498-
archputc('\'',fout);
499-
expsrc=PQgetvalue(res,tuple,field);
500-
while (*expsrc)
501-
{
502-
charch=*expsrc++;
503-
504-
if (ch=='\\'||ch=='\'')
505-
{
506-
archputc(ch,fout);/* double these */
507-
archputc(ch,fout);
508-
}
509-
elseif (ch<'\040')
510-
{
511-
/* generate octal escape for control chars */
512-
archputc('\\',fout);
513-
archputc(((ch >>6)&3)+'0',fout);
514-
archputc(((ch >>3)&7)+'0',fout);
515-
archputc((ch&7)+'0',fout);
516-
}
517-
else
518-
archputc(ch,fout);
519-
}
520-
archputc('\'',fout);
495+
resetPQExpBuffer(q);
496+
formatStringLiteral(q,PQgetvalue(res,tuple,field));
497+
archprintf(fout,"%s",q->data);
521498
break;
522499
}
523500
}
@@ -527,6 +504,41 @@ dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
527504
return1;
528505
}
529506

507+
/*
508+
* Convert a string value to an SQL string literal,
509+
* with appropriate escaping of special characters.
510+
* Quote mark ' goes to '' per SQL standard, other
511+
* stuff goes to \ sequences.
512+
* The literal is appended to the given PQExpBuffer.
513+
*/
514+
staticvoid
515+
formatStringLiteral(PQExpBufferbuf,constchar*str)
516+
{
517+
appendPQExpBufferChar(buf,'\'');
518+
while (*str)
519+
{
520+
charch=*str++;
521+
522+
if (ch=='\\'||ch=='\'')
523+
{
524+
appendPQExpBufferChar(buf,ch);/* double these */
525+
appendPQExpBufferChar(buf,ch);
526+
}
527+
elseif ((unsignedchar)ch< (unsignedchar)' '&&
528+
ch!='\n'&&ch!='\t')
529+
{
530+
/* generate octal escape for control chars other than whitespace */
531+
appendPQExpBufferChar(buf,'\\');
532+
appendPQExpBufferChar(buf, ((ch >>6)&3)+'0');
533+
appendPQExpBufferChar(buf, ((ch >>3)&7)+'0');
534+
appendPQExpBufferChar(buf, (ch&7)+'0');
535+
}
536+
else
537+
appendPQExpBufferChar(buf,ch);
538+
}
539+
appendPQExpBufferChar(buf,'\'');
540+
}
541+
530542
/*
531543
* DumpClasses -
532544
* dump the contents of all the classes.
@@ -1067,7 +1079,8 @@ dumpDatabase(Archive *AH)
10671079

10681080
/* Get the dba */
10691081
appendPQExpBuffer(dbQry,"select (select usename from pg_user where datdba = usesysid) as dba from pg_database"
1070-
" where datname = '%s'",PQdb(g_conn));
1082+
" where datname = ");
1083+
formatStringLiteral(dbQry,PQdb(g_conn));
10711084

10721085
res=PQexec(g_conn,dbQry->data);
10731086
if (!res||
@@ -1826,7 +1839,7 @@ getFuncs(int *numFuncs)
18261839
finfo[i].oid=strdup(PQgetvalue(res,i,i_oid));
18271840
finfo[i].proname=strdup(PQgetvalue(res,i,i_proname));
18281841

1829-
finfo[i].prosrc=checkForQuote(PQgetvalue(res,i,i_prosrc));
1842+
finfo[i].prosrc=strdup(PQgetvalue(res,i,i_prosrc));
18301843
finfo[i].probin=strdup(PQgetvalue(res,i,i_probin));
18311844

18321845
finfo[i].prorettype=strdup(PQgetvalue(res,i,i_prorettype));
@@ -1955,7 +1968,9 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
19551968
PGresult*res2;
19561969

19571970
resetPQExpBuffer(query);
1958-
appendPQExpBuffer(query,"SELECT pg_get_viewdef('%s') as viewdef ",tblinfo[i].relname);
1971+
appendPQExpBuffer(query,"SELECT pg_get_viewdef(");
1972+
formatStringLiteral(query,tblinfo[i].relname);
1973+
appendPQExpBuffer(query,") as viewdef");
19591974
res2=PQexec(g_conn,query->data);
19601975
if (!res2||PQresultStatus(res2)!=PGRES_TUPLES_OK)
19611976
{
@@ -2753,8 +2768,9 @@ dumpComment(Archive *fout, const char *target, const char *oid)
27532768
{
27542769
i_description=PQfnumber(res,"description");
27552770
resetPQExpBuffer(query);
2756-
appendPQExpBuffer(query,"COMMENT ON %s IS '%s';\n",
2757-
target,checkForQuote(PQgetvalue(res,0,i_description)));
2771+
appendPQExpBuffer(query,"COMMENT ON %s IS ",target);
2772+
formatStringLiteral(query,PQgetvalue(res,0,i_description));
2773+
appendPQExpBuffer(query,";\n");
27582774

27592775
ArchiveEntry(fout,oid,target,"COMMENT",NULL,query->data,""/*Del*/,
27602776
""/* Copy */,""/*Owner*/,NULL,NULL);
@@ -2788,8 +2804,8 @@ dumpDBComment(Archive *fout)
27882804
/*** Build query to find comment ***/
27892805

27902806
query=createPQExpBuffer();
2791-
appendPQExpBuffer(query,"SELECT oid FROM pg_database WHERE datname ='%s'",
2792-
PQdb(g_conn));
2807+
appendPQExpBuffer(query,"SELECT oid FROM pg_database WHERE datname =");
2808+
formatStringLiteral(query,PQdb(g_conn));
27932809

27942810
/*** Execute query ***/
27952811

@@ -2864,25 +2880,28 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
28642880
resetPQExpBuffer(q);
28652881
appendPQExpBuffer(q,
28662882
"CREATE TYPE %s "
2867-
"( internallength = %s, externallength = %s, input = %s, "
2868-
"output = %s, send = %s, receive = %s, default = '%s'",
2883+
"( internallength = %s, externallength = %s,",
28692884
fmtId(tinfo[i].typname,force_quotes),
28702885
tinfo[i].typlen,
2871-
tinfo[i].typprtlen,
2872-
tinfo[i].typinput,
2873-
tinfo[i].typoutput,
2874-
tinfo[i].typsend,
2875-
tinfo[i].typreceive,
2876-
tinfo[i].typdefault);
2886+
tinfo[i].typprtlen);
2887+
/* cannot combine these because fmtId uses static result area */
2888+
appendPQExpBuffer(q," input = %s,",
2889+
fmtId(tinfo[i].typinput,force_quotes));
2890+
appendPQExpBuffer(q," output = %s,",
2891+
fmtId(tinfo[i].typoutput,force_quotes));
2892+
appendPQExpBuffer(q," send = %s,",
2893+
fmtId(tinfo[i].typsend,force_quotes));
2894+
appendPQExpBuffer(q," receive = %s, default = ",
2895+
fmtId(tinfo[i].typreceive,force_quotes));
2896+
formatStringLiteral(q,tinfo[i].typdefault);
28772897

28782898
if (tinfo[i].isArray)
28792899
{
28802900
char*elemType;
28812901

28822902
elemType=findTypeByOid(tinfo,numTypes,tinfo[i].typelem,zeroAsOpaque);
2883-
2884-
appendPQExpBuffer(q,", element = %s, delimiter = '%s'",
2885-
elemType,tinfo[i].typdelim);
2903+
appendPQExpBuffer(q,", element = %s, delimiter = ",elemType);
2904+
formatStringLiteral(q,tinfo[i].typdelim);
28862905
}
28872906
if (tinfo[i].passedbyvalue)
28882907
appendPQExpBuffer(q,",passedbyvalue);\n");
@@ -2971,24 +2990,25 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
29712990

29722991
dumpOneFunc(fout,finfo,fidx,tinfo,numTypes);
29732992

2974-
lanname=checkForQuote(PQgetvalue(res,i,i_lanname));
2975-
lancompiler=checkForQuote(PQgetvalue(res,i,i_lancompiler));
2993+
lanname=PQgetvalue(res,i,i_lanname);
2994+
lancompiler=PQgetvalue(res,i,i_lancompiler);
29762995

2977-
appendPQExpBuffer(delqry,"DROP PROCEDURAL LANGUAGE '%s';\n",lanname);
2996+
appendPQExpBuffer(delqry,"DROP PROCEDURAL LANGUAGE ");
2997+
formatStringLiteral(delqry,lanname);
2998+
appendPQExpBuffer(delqry,";\n");
29782999

2979-
appendPQExpBuffer(defqry,"CREATE %sPROCEDURAL LANGUAGE '%s' "
2980-
"HANDLER %s LANCOMPILER '%s';\n",
2981-
(PQgetvalue(res,i,i_lanpltrusted)[0]=='t') ?"TRUSTED " :"",
2982-
lanname,
2983-
fmtId(finfo[fidx].proname,force_quotes),
2984-
lancompiler);
3000+
appendPQExpBuffer(defqry,"CREATE %sPROCEDURAL LANGUAGE ",
3001+
(PQgetvalue(res,i,i_lanpltrusted)[0]=='t') ?
3002+
"TRUSTED " :"");
3003+
formatStringLiteral(defqry,lanname);
3004+
appendPQExpBuffer(defqry," HANDLER %s LANCOMPILER ",
3005+
fmtId(finfo[fidx].proname,force_quotes));
3006+
formatStringLiteral(defqry,lancompiler);
3007+
appendPQExpBuffer(defqry,";\n");
29853008

29863009
ArchiveEntry(fout,PQgetvalue(res,i,i_oid),lanname,"PROCEDURAL LANGUAGE",
29873010
NULL,defqry->data,delqry->data,"","",NULL,NULL);
29883011

2989-
free(lanname);
2990-
free(lancompiler);
2991-
29923012
resetPQExpBuffer(defqry);
29933013
resetPQExpBuffer(delqry);
29943014
}
@@ -3071,15 +3091,21 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
30713091
*/
30723092
if (strcmp(finfo[i].probin,"-")!=0)
30733093
{
3094+
appendPQExpBuffer(asPart,"AS ");
3095+
formatStringLiteral(asPart,finfo[i].probin);
30743096
if (strcmp(finfo[i].prosrc,"-")!=0)
3075-
appendPQExpBuffer(asPart,"AS '%s', '%s'",finfo[i].probin,finfo[i].prosrc);
3076-
else
3077-
appendPQExpBuffer(asPart,"AS '%s'",finfo[i].probin);
3097+
{
3098+
appendPQExpBuffer(asPart,", ");
3099+
formatStringLiteral(asPart,finfo[i].prosrc);
3100+
}
30783101
}
30793102
else
30803103
{
30813104
if (strcmp(finfo[i].prosrc,"-")!=0)
3082-
appendPQExpBuffer(asPart,"AS '%s'",finfo[i].prosrc);
3105+
{
3106+
appendPQExpBuffer(asPart,"AS ");
3107+
formatStringLiteral(asPart,finfo[i].prosrc);
3108+
}
30833109
}
30843110

30853111
strcpy(func_lang,PQgetvalue(res,0,i_lanname));
@@ -3107,10 +3133,11 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
31073133

31083134
resetPQExpBuffer(q);
31093135
appendPQExpBuffer(q,"CREATE FUNCTION %s ",fn->data );
3110-
appendPQExpBuffer(q,"RETURNS %s%s %s LANGUAGE'%s'",
3111-
(finfo[i].retset) ?"SETOF " :"",
3136+
appendPQExpBuffer(q,"RETURNS %s%s %s LANGUAGE ",
3137+
(finfo[i].retset) ?"SETOF " :"",
31123138
findTypeByOid(tinfo,numTypes,finfo[i].prorettype,zeroAsOpaque),
3113-
asPart->data,func_lang);
3139+
asPart->data);
3140+
formatStringLiteral(q,func_lang);
31143141

31153142
if (finfo[i].iscachable||finfo[i].isstrict)/* OR in new attrs here */
31163143
{
@@ -3286,8 +3313,10 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
32863313
findTypeByOid(tinfo,numTypes,agginfo[i].aggtranstype,zeroAsOpaque+useBaseTypeName));
32873314

32883315
if (agginfo[i].agginitval)
3289-
appendPQExpBuffer(details,", INITCOND = '%s'",
3290-
agginfo[i].agginitval);
3316+
{
3317+
appendPQExpBuffer(details,", INITCOND = ");
3318+
formatStringLiteral(details,agginfo[i].agginitval);
3319+
}
32913320

32923321
if (!(strcmp(agginfo[i].aggfinalfn,"-")==0))
32933322
appendPQExpBuffer(details,", FINALFUNC = %s",
@@ -3970,7 +3999,8 @@ findLastBuiltinOid(const char* dbname)
39703999
PQExpBufferquery=createPQExpBuffer();
39714000

39724001
resetPQExpBuffer(query);
3973-
appendPQExpBuffer(query,"SELECT datlastsysoid from pg_database where datname = '%s'",dbname);
4002+
appendPQExpBuffer(query,"SELECT datlastsysoid from pg_database where datname = ");
4003+
formatStringLiteral(query,dbname);
39744004

39754005
res=PQexec(g_conn,query->data);
39764006
if (res==NULL||
@@ -3999,41 +4029,6 @@ findLastBuiltinOid(const char* dbname)
39994029
}
40004030

40014031

4002-
/*
4003-
* checkForQuote:
4004-
* checks a string for quote characters and quotes them
4005-
*/
4006-
staticchar*
4007-
checkForQuote(constchar*s)
4008-
{
4009-
char*r;
4010-
charc;
4011-
char*result;
4012-
4013-
intj=0;
4014-
4015-
r=malloc(strlen(s)*3+1);/* definitely long enough */
4016-
4017-
while ((c=*s)!='\0')
4018-
{
4019-
4020-
if (c=='\'')
4021-
{
4022-
r[j++]='\'';/* quote the single quotes */
4023-
}
4024-
r[j++]=c;
4025-
s++;
4026-
}
4027-
r[j]='\0';
4028-
4029-
result=strdup(r);
4030-
free(r);
4031-
4032-
returnresult;
4033-
4034-
}
4035-
4036-
40374032
staticvoid
40384033
dumpSequence(Archive*fout,TableInfotbinfo)
40394034
{
@@ -4113,8 +4108,9 @@ dumpSequence(Archive *fout, TableInfo tbinfo)
41134108

41144109

41154110
resetPQExpBuffer(query);
4116-
appendPQExpBuffer(query,"SELECT setval ('%s', %d, '%c');\n",
4117-
fmtId(tbinfo.relname,force_quotes),last,called);
4111+
appendPQExpBuffer(query,"SELECT setval (");
4112+
formatStringLiteral(query,fmtId(tbinfo.relname,force_quotes));
4113+
appendPQExpBuffer(query,", %d, '%c');\n",last,called);
41184114

41194115
ArchiveEntry(fout,tbinfo.oid,fmtId(tbinfo.relname,force_quotes),"SEQUENCE SET",NULL,
41204116
query->data,""/* Del */,"","",NULL,NULL);
@@ -4191,12 +4187,13 @@ dumpRules(Archive *fout, const char *tablename,
41914187
" (select usename from pg_user where pg_class.relowner = usesysid) AS viewowner, "
41924188
" pg_rewrite.oid, pg_rewrite.rulename "
41934189
"FROM pg_rewrite, pg_class, pg_rules "
4194-
"WHERE pg_class.relname = '%s' "
4190+
"WHERE pg_class.relname = ");
4191+
formatStringLiteral(query,tblinfo[t].relname);
4192+
appendPQExpBuffer(query,
41954193
" AND pg_rewrite.ev_class = pg_class.oid "
41964194
" AND pg_rules.tablename = pg_class.relname "
41974195
" AND pg_rules.rulename = pg_rewrite.rulename "
4198-
"ORDER BY pg_rewrite.oid",
4199-
tblinfo[t].relname);
4196+
"ORDER BY pg_rewrite.oid");
42004197
res=PQexec(g_conn,query->data);
42014198
if (!res||
42024199
PQresultStatus(res)!=PGRES_TUPLES_OK)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp