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

Commitaab4b73

Browse files
committed
Teach pg_dump to quote reloption values safely.
Commitc7e27be fixed this on the backend side, but we neglectedthe fact that several code paths in pg_dump were printing reloptionsvalues that had not gotten massaged by ruleutils. Apply essentially thesame quoting logic in those places, too.
1 parent1cd3840 commitaab4b73

File tree

2 files changed

+128
-38
lines changed

2 files changed

+128
-38
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 126 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
263263
constchar*objlabel);
264264
staticconstchar*getAttrName(intattrnum,TableInfo*tblInfo);
265265
staticconstchar*fmtCopyColumnList(constTableInfo*ti,PQExpBufferbuffer);
266+
staticboolnonemptyReloptions(constchar*reloptions);
267+
staticvoidfmtReloptionsArray(Archive*fout,PQExpBufferbuffer,
268+
constchar*reloptions,constchar*prefix);
266269
staticchar*get_synchronized_snapshot(Archive*fout);
267270
staticPGresult*ExecuteSqlQueryForSingleRow(Archive*fout,char*query);
268271
staticvoidsetupDumpWorker(Archive*AHX,RestoreOptions*ropt);
@@ -4336,10 +4339,10 @@ getTables(Archive *fout, int *numTables)
43364339
"d.refobjid AS owning_tab, "
43374340
"d.refobjsubid AS owning_col, "
43384341
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4339-
"array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ',') AS reloptions, "
4342+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
43404343
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
43414344
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
4342-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4345+
"tc.reloptions AS toast_reloptions "
43434346
"FROM pg_class c "
43444347
"LEFT JOIN pg_depend d ON "
43454348
"(c.relkind = '%c' AND "
@@ -4376,10 +4379,10 @@ getTables(Archive *fout, int *numTables)
43764379
"d.refobjid AS owning_tab, "
43774380
"d.refobjsubid AS owning_col, "
43784381
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4379-
"array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ',') AS reloptions, "
4382+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
43804383
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
43814384
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
4382-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4385+
"tc.reloptions AS toast_reloptions "
43834386
"FROM pg_class c "
43844387
"LEFT JOIN pg_depend d ON "
43854388
"(c.relkind = '%c' AND "
@@ -4416,8 +4419,8 @@ getTables(Archive *fout, int *numTables)
44164419
"d.refobjid AS owning_tab, "
44174420
"d.refobjsubid AS owning_col, "
44184421
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4419-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4420-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4422+
"c.reloptions AS reloptions, "
4423+
"tc.reloptions AS toast_reloptions "
44214424
"FROM pg_class c "
44224425
"LEFT JOIN pg_depend d ON "
44234426
"(c.relkind = '%c' AND "
@@ -4454,8 +4457,8 @@ getTables(Archive *fout, int *numTables)
44544457
"d.refobjid AS owning_tab, "
44554458
"d.refobjsubid AS owning_col, "
44564459
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4457-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4458-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4460+
"c.reloptions AS reloptions, "
4461+
"tc.reloptions AS toast_reloptions "
44594462
"FROM pg_class c "
44604463
"LEFT JOIN pg_depend d ON "
44614464
"(c.relkind = '%c' AND "
@@ -4491,8 +4494,8 @@ getTables(Archive *fout, int *numTables)
44914494
"d.refobjid AS owning_tab, "
44924495
"d.refobjsubid AS owning_col, "
44934496
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4494-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4495-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4497+
"c.reloptions AS reloptions, "
4498+
"tc.reloptions AS toast_reloptions "
44964499
"FROM pg_class c "
44974500
"LEFT JOIN pg_depend d ON "
44984501
"(c.relkind = '%c' AND "
@@ -4528,7 +4531,7 @@ getTables(Archive *fout, int *numTables)
45284531
"d.refobjid AS owning_tab, "
45294532
"d.refobjsubid AS owning_col, "
45304533
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4531-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4534+
"c.reloptions AS reloptions, "
45324535
"NULL AS toast_reloptions "
45334536
"FROM pg_class c "
45344537
"LEFT JOIN pg_depend d ON "
@@ -4987,7 +4990,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
49874990
i_conoid,
49884991
i_condef,
49894992
i_tablespace,
4990-
i_options,
4993+
i_indreloptions,
49914994
i_relpages;
49924995
intntups;
49934996

@@ -5044,7 +5047,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
50445047
"c.oid AS conoid, "
50455048
"pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
50465049
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5047-
"array_to_string(t.reloptions, ', ')ASoptions "
5050+
"t.reloptionsASindreloptions "
50485051
"FROM pg_catalog.pg_index i "
50495052
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
50505053
"LEFT JOIN pg_catalog.pg_constraint c "
@@ -5075,7 +5078,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
50755078
"c.oid AS conoid, "
50765079
"pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
50775080
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5078-
"array_to_string(t.reloptions, ', ')ASoptions "
5081+
"t.reloptionsASindreloptions "
50795082
"FROM pg_catalog.pg_index i "
50805083
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
50815084
"LEFT JOIN pg_catalog.pg_constraint c "
@@ -5102,7 +5105,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
51025105
"c.oid AS conoid, "
51035106
"null AS condef, "
51045107
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5105-
"array_to_string(t.reloptions, ', ')ASoptions "
5108+
"t.reloptionsASindreloptions "
51065109
"FROM pg_catalog.pg_index i "
51075110
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
51085111
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5132,7 +5135,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
51325135
"c.oid AS conoid, "
51335136
"null AS condef, "
51345137
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5135-
"null ASoptions "
5138+
"null ASindreloptions "
51365139
"FROM pg_catalog.pg_index i "
51375140
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
51385141
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5161,7 +5164,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
51615164
"c.oid AS conoid, "
51625165
"null AS condef, "
51635166
"NULL AS tablespace, "
5164-
"null ASoptions "
5167+
"null ASindreloptions "
51655168
"FROM pg_catalog.pg_index i "
51665169
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
51675170
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5193,7 +5196,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
51935196
"t.oid AS conoid, "
51945197
"null AS condef, "
51955198
"NULL AS tablespace, "
5196-
"null ASoptions "
5199+
"null ASindreloptions "
51975200
"FROM pg_index i, pg_class t "
51985201
"WHERE t.oid = i.indexrelid "
51995202
"AND i.indrelid = '%u'::oid "
@@ -5220,7 +5223,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
52205223
"t.oid AS conoid, "
52215224
"null AS condef, "
52225225
"NULL AS tablespace, "
5223-
"null ASoptions "
5226+
"null ASindreloptions "
52245227
"FROM pg_index i, pg_class t "
52255228
"WHERE t.oid = i.indexrelid "
52265229
"AND i.indrelid = '%u'::oid "
@@ -5249,7 +5252,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
52495252
i_conoid=PQfnumber(res,"conoid");
52505253
i_condef=PQfnumber(res,"condef");
52515254
i_tablespace=PQfnumber(res,"tablespace");
5252-
i_options=PQfnumber(res,"options");
5255+
i_indreloptions=PQfnumber(res,"indreloptions");
52535256

52545257
indxinfo= (IndxInfo*)pg_malloc(ntups*sizeof(IndxInfo));
52555258
constrinfo= (ConstraintInfo*)pg_malloc(ntups*sizeof(ConstraintInfo));
@@ -5268,7 +5271,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
52685271
indxinfo[j].indexdef=pg_strdup(PQgetvalue(res,j,i_indexdef));
52695272
indxinfo[j].indnkeys=atoi(PQgetvalue(res,j,i_indnkeys));
52705273
indxinfo[j].tablespace=pg_strdup(PQgetvalue(res,j,i_tablespace));
5271-
indxinfo[j].options=pg_strdup(PQgetvalue(res,j,i_options));
5274+
indxinfo[j].indreloptions=pg_strdup(PQgetvalue(res,j,i_indreloptions));
52725275

52735276
/*
52745277
* In pre-7.4 releases, indkeys may contain more entries than
@@ -13201,8 +13204,12 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1320113204
tbinfo->dobj.catId.oid, false);
1320213205

1320313206
appendPQExpBuffer(q,"CREATE VIEW %s",fmtId(tbinfo->dobj.name));
13204-
if (tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)
13205-
appendPQExpBuffer(q," WITH (%s)",tbinfo->reloptions);
13207+
if (nonemptyReloptions(tbinfo->reloptions))
13208+
{
13209+
appendPQExpBufferStr(q," WITH (");
13210+
fmtReloptionsArray(fout,q,tbinfo->reloptions,"");
13211+
appendPQExpBufferChar(q,')');
13212+
}
1320613213
result=createViewAsClause(fout,tbinfo);
1320713214
appendPQExpBuffer(q," AS\n%s",result->data);
1320813215
destroyPQExpBuffer(result);
@@ -13446,21 +13453,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1344613453
appendPQExpBuffer(q,"\nSERVER %s",fmtId(srvname));
1344713454
}
1344813455

13449-
if ((tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)||
13450-
(tbinfo->toast_reloptions&&strlen(tbinfo->toast_reloptions)>0))
13456+
if (nonemptyReloptions(tbinfo->reloptions)||
13457+
nonemptyReloptions(tbinfo->toast_reloptions))
1345113458
{
1345213459
booladdcomma= false;
1345313460

1345413461
appendPQExpBufferStr(q,"\nWITH (");
13455-
if (tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)
13462+
if (nonemptyReloptions(tbinfo->reloptions))
1345613463
{
1345713464
addcomma= true;
13458-
appendPQExpBufferStr(q,tbinfo->reloptions);
13465+
fmtReloptionsArray(fout,q,tbinfo->reloptions,"");
1345913466
}
13460-
if (tbinfo->toast_reloptions&&strlen(tbinfo->toast_reloptions)>0)
13467+
if (nonemptyReloptions(tbinfo->toast_reloptions))
1346113468
{
13462-
appendPQExpBuffer(q,"%s%s",addcomma ?", " :"",
13463-
tbinfo->toast_reloptions);
13469+
if (addcomma)
13470+
appendPQExpBufferStr(q,", ");
13471+
fmtReloptionsArray(fout,q,tbinfo->toast_reloptions,"toast.");
1346413472
}
1346513473
appendPQExpBufferChar(q,')');
1346613474
}
@@ -14034,8 +14042,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
1403414042

1403514043
appendPQExpBufferChar(q,')');
1403614044

14037-
if (indxinfo->options&&strlen(indxinfo->options)>0)
14038-
appendPQExpBuffer(q," WITH (%s)",indxinfo->options);
14045+
if (nonemptyReloptions(indxinfo->indreloptions))
14046+
{
14047+
appendPQExpBufferStr(q," WITH (");
14048+
fmtReloptionsArray(fout,q,indxinfo->indreloptions,"");
14049+
appendPQExpBufferChar(q,')');
14050+
}
1403914051

1404014052
if (coninfo->condeferrable)
1404114053
{
@@ -14895,11 +14907,12 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
1489514907
/*
1489614908
* Apply view's reloptions when its ON SELECT rule is separate.
1489714909
*/
14898-
if (rinfo->reloptions&&strlen(rinfo->reloptions)>0)
14910+
if (nonemptyReloptions(rinfo->reloptions))
1489914911
{
14900-
appendPQExpBuffer(cmd,"ALTER VIEW %s SET (%s);\n",
14901-
fmtId(tbinfo->dobj.name),
14902-
rinfo->reloptions);
14912+
appendPQExpBuffer(cmd,"ALTER VIEW %s SET (",
14913+
fmtId(tbinfo->dobj.name));
14914+
fmtReloptionsArray(fout,cmd,rinfo->reloptions,"");
14915+
appendPQExpBufferStr(cmd,");\n");
1490314916
}
1490414917

1490514918
/*
@@ -15769,6 +15782,83 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
1576915782
returnbuffer->data;
1577015783
}
1577115784

15785+
/*
15786+
* Check if a reloptions array is nonempty.
15787+
*/
15788+
staticbool
15789+
nonemptyReloptions(constchar*reloptions)
15790+
{
15791+
/* Don't want to print it if it's just "{}" */
15792+
return (reloptions!=NULL&&strlen(reloptions)>2);
15793+
}
15794+
15795+
/*
15796+
* Format a reloptions array and append it to the given buffer.
15797+
*
15798+
* "prefix" is prepended to the option names; typically it's "" or "toast.".
15799+
*
15800+
* Note: this logic should generally match the backend's flatten_reloptions()
15801+
* (in adt/ruleutils.c).
15802+
*/
15803+
staticvoid
15804+
fmtReloptionsArray(Archive*fout,PQExpBufferbuffer,constchar*reloptions,
15805+
constchar*prefix)
15806+
{
15807+
char**options;
15808+
intnoptions;
15809+
inti;
15810+
15811+
if (!parsePGArray(reloptions,&options,&noptions))
15812+
{
15813+
write_msg(NULL,"WARNING: could not parse reloptions array\n");
15814+
if (options)
15815+
free(options);
15816+
return;
15817+
}
15818+
15819+
for (i=0;i<noptions;i++)
15820+
{
15821+
char*option=options[i];
15822+
char*name;
15823+
char*separator;
15824+
char*value;
15825+
15826+
/*
15827+
* Each array element should have the form name=value. If the "=" is
15828+
* missing for some reason, treat it like an empty value.
15829+
*/
15830+
name=option;
15831+
separator=strchr(option,'=');
15832+
if (separator)
15833+
{
15834+
*separator='\0';
15835+
value=separator+1;
15836+
}
15837+
else
15838+
value="";
15839+
15840+
if (i>0)
15841+
appendPQExpBufferStr(buffer,", ");
15842+
appendPQExpBuffer(buffer,"%s%s=",prefix,fmtId(name));
15843+
15844+
/*
15845+
* In general we need to quote the value; but to avoid unnecessary
15846+
* clutter, do not quote if it is an identifier that would not need
15847+
* quoting. (We could also allow numbers, but that is a bit trickier
15848+
* than it looks --- for example, are leading zeroes significant? We
15849+
* don't want to assume very much here about what custom reloptions
15850+
* might mean.)
15851+
*/
15852+
if (strcmp(fmtId(value),value)==0)
15853+
appendPQExpBufferStr(buffer,value);
15854+
else
15855+
appendStringLiteralAH(buffer,value,fout);
15856+
}
15857+
15858+
if (options)
15859+
free(options);
15860+
}
15861+
1577215862
/*
1577315863
* Execute an SQL query and verify that we got exactly one row back.
1577415864
*/

‎src/bin/pg_dump/pg_dump.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ typedef struct _tableInfo
239239
charrelreplident;/* replica identifier */
240240
char*reltablespace;/* relation tablespace */
241241
char*reloptions;/* options specified by WITH (...) */
242-
char*checkoption;/* WITH CHECK OPTION */
242+
char*checkoption;/* WITH CHECK OPTION, if any */
243243
char*toast_reloptions;/* WITH options for the TOAST table */
244244
boolhasindex;/* does it have any indexes? */
245245
boolhasrules;/* does it have any rules? */
@@ -314,7 +314,7 @@ typedef struct _indxInfo
314314
TableInfo*indextable;/* link to table the index is for */
315315
char*indexdef;
316316
char*tablespace;/* tablespace in which index is stored */
317-
char*options;/* options specified by WITH (...) */
317+
char*indreloptions;/* options specified by WITH (...) */
318318
intindnkeys;
319319
Oid*indkeys;
320320
boolindisclustered;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp