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

Commitb01828e

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 parent7013035 commitb01828e

File tree

2 files changed

+130
-40
lines changed

2 files changed

+130
-40
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 128 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
251251
constchar*objlabel);
252252
staticconstchar*getAttrName(intattrnum,TableInfo*tblInfo);
253253
staticconstchar*fmtCopyColumnList(constTableInfo*ti,PQExpBufferbuffer);
254+
staticboolnonemptyReloptions(constchar*reloptions);
255+
staticvoidfmtReloptionsArray(Archive*fout,PQExpBufferbuffer,
256+
constchar*reloptions,constchar*prefix);
254257
staticchar*get_synchronized_snapshot(Archive*fout);
255258
staticPGresult*ExecuteSqlQueryForSingleRow(Archive*fout,char*query);
256259
staticvoidsetupDumpWorker(Archive*AHX,DumpOptions*dopt,RestoreOptions*ropt);
@@ -4585,10 +4588,10 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
45854588
"d.refobjid AS owning_tab, "
45864589
"d.refobjsubid AS owning_col, "
45874590
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4588-
"array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ',') AS reloptions, "
4591+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
45894592
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
45904593
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
4591-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4594+
"tc.reloptions AS toast_reloptions "
45924595
"FROM pg_class c "
45934596
"LEFT JOIN pg_depend d ON "
45944597
"(c.relkind = '%c' AND "
@@ -4627,10 +4630,10 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
46274630
"d.refobjid AS owning_tab, "
46284631
"d.refobjsubid AS owning_col, "
46294632
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4630-
"array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ',') AS reloptions, "
4633+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
46314634
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
46324635
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
4633-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4636+
"tc.reloptions AS toast_reloptions "
46344637
"FROM pg_class c "
46354638
"LEFT JOIN pg_depend d ON "
46364639
"(c.relkind = '%c' AND "
@@ -4669,10 +4672,10 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
46694672
"d.refobjid AS owning_tab, "
46704673
"d.refobjsubid AS owning_col, "
46714674
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4672-
"array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ',') AS reloptions, "
4675+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
46734676
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
46744677
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
4675-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4678+
"tc.reloptions AS toast_reloptions "
46764679
"FROM pg_class c "
46774680
"LEFT JOIN pg_depend d ON "
46784681
"(c.relkind = '%c' AND "
@@ -4711,8 +4714,8 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
47114714
"d.refobjid AS owning_tab, "
47124715
"d.refobjsubid AS owning_col, "
47134716
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4714-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4715-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4717+
"c.reloptions AS reloptions, "
4718+
"tc.reloptions AS toast_reloptions "
47164719
"FROM pg_class c "
47174720
"LEFT JOIN pg_depend d ON "
47184721
"(c.relkind = '%c' AND "
@@ -4751,8 +4754,8 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
47514754
"d.refobjid AS owning_tab, "
47524755
"d.refobjsubid AS owning_col, "
47534756
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4754-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4755-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4757+
"c.reloptions AS reloptions, "
4758+
"tc.reloptions AS toast_reloptions "
47564759
"FROM pg_class c "
47574760
"LEFT JOIN pg_depend d ON "
47584761
"(c.relkind = '%c' AND "
@@ -4790,8 +4793,8 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
47904793
"d.refobjid AS owning_tab, "
47914794
"d.refobjsubid AS owning_col, "
47924795
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4793-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4794-
"array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
4796+
"c.reloptions AS reloptions, "
4797+
"tc.reloptions AS toast_reloptions "
47954798
"FROM pg_class c "
47964799
"LEFT JOIN pg_depend d ON "
47974800
"(c.relkind = '%c' AND "
@@ -4829,7 +4832,7 @@ getTables(Archive *fout, DumpOptions *dopt, int *numTables)
48294832
"d.refobjid AS owning_tab, "
48304833
"d.refobjsubid AS owning_col, "
48314834
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
4832-
"array_to_string(c.reloptions, ', ') AS reloptions, "
4835+
"c.reloptions AS reloptions, "
48334836
"NULL AS toast_reloptions "
48344837
"FROM pg_class c "
48354838
"LEFT JOIN pg_depend d ON "
@@ -5302,7 +5305,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
53025305
i_conoid,
53035306
i_condef,
53045307
i_tablespace,
5305-
i_options,
5308+
i_indreloptions,
53065309
i_relpages;
53075310
intntups;
53085311

@@ -5360,7 +5363,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
53605363
"c.oid AS conoid, "
53615364
"pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
53625365
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5363-
"array_to_string(t.reloptions, ', ')ASoptions "
5366+
"t.reloptionsASindreloptions "
53645367
"FROM pg_catalog.pg_index i "
53655368
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
53665369
"LEFT JOIN pg_catalog.pg_constraint c "
@@ -5391,7 +5394,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
53915394
"c.oid AS conoid, "
53925395
"pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
53935396
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5394-
"array_to_string(t.reloptions, ', ')ASoptions "
5397+
"t.reloptionsASindreloptions "
53955398
"FROM pg_catalog.pg_index i "
53965399
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
53975400
"LEFT JOIN pg_catalog.pg_constraint c "
@@ -5418,7 +5421,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
54185421
"c.oid AS conoid, "
54195422
"null AS condef, "
54205423
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5421-
"array_to_string(t.reloptions, ', ')ASoptions "
5424+
"t.reloptionsASindreloptions "
54225425
"FROM pg_catalog.pg_index i "
54235426
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
54245427
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5448,7 +5451,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
54485451
"c.oid AS conoid, "
54495452
"null AS condef, "
54505453
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
5451-
"null ASoptions "
5454+
"null ASindreloptions "
54525455
"FROM pg_catalog.pg_index i "
54535456
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
54545457
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5477,7 +5480,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
54775480
"c.oid AS conoid, "
54785481
"null AS condef, "
54795482
"NULL AS tablespace, "
5480-
"null ASoptions "
5483+
"null ASindreloptions "
54815484
"FROM pg_catalog.pg_index i "
54825485
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
54835486
"LEFT JOIN pg_catalog.pg_depend d "
@@ -5509,7 +5512,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
55095512
"t.oid AS conoid, "
55105513
"null AS condef, "
55115514
"NULL AS tablespace, "
5512-
"null ASoptions "
5515+
"null ASindreloptions "
55135516
"FROM pg_index i, pg_class t "
55145517
"WHERE t.oid = i.indexrelid "
55155518
"AND i.indrelid = '%u'::oid "
@@ -5536,7 +5539,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
55365539
"t.oid AS conoid, "
55375540
"null AS condef, "
55385541
"NULL AS tablespace, "
5539-
"null ASoptions "
5542+
"null ASindreloptions "
55405543
"FROM pg_index i, pg_class t "
55415544
"WHERE t.oid = i.indexrelid "
55425545
"AND i.indrelid = '%u'::oid "
@@ -5565,7 +5568,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
55655568
i_conoid=PQfnumber(res,"conoid");
55665569
i_condef=PQfnumber(res,"condef");
55675570
i_tablespace=PQfnumber(res,"tablespace");
5568-
i_options=PQfnumber(res,"options");
5571+
i_indreloptions=PQfnumber(res,"indreloptions");
55695572

55705573
indxinfo= (IndxInfo*)pg_malloc(ntups*sizeof(IndxInfo));
55715574
constrinfo= (ConstraintInfo*)pg_malloc(ntups*sizeof(ConstraintInfo));
@@ -5584,7 +5587,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
55845587
indxinfo[j].indexdef=pg_strdup(PQgetvalue(res,j,i_indexdef));
55855588
indxinfo[j].indnkeys=atoi(PQgetvalue(res,j,i_indnkeys));
55865589
indxinfo[j].tablespace=pg_strdup(PQgetvalue(res,j,i_tablespace));
5587-
indxinfo[j].options=pg_strdup(PQgetvalue(res,j,i_options));
5590+
indxinfo[j].indreloptions=pg_strdup(PQgetvalue(res,j,i_indreloptions));
55885591

55895592
/*
55905593
* In pre-7.4 releases, indkeys may contain more entries than
@@ -13810,8 +13813,12 @@ dumpTableSchema(Archive *fout, DumpOptions *dopt, TableInfo *tbinfo)
1381013813
tbinfo->dobj.catId.oid, false);
1381113814

1381213815
appendPQExpBuffer(q,"CREATE VIEW %s",fmtId(tbinfo->dobj.name));
13813-
if (tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)
13814-
appendPQExpBuffer(q," WITH (%s)",tbinfo->reloptions);
13816+
if (nonemptyReloptions(tbinfo->reloptions))
13817+
{
13818+
appendPQExpBufferStr(q," WITH (");
13819+
fmtReloptionsArray(fout,q,tbinfo->reloptions,"");
13820+
appendPQExpBufferChar(q,')');
13821+
}
1381513822
result=createViewAsClause(fout,tbinfo);
1381613823
appendPQExpBuffer(q," AS\n%s",result->data);
1381713824
destroyPQExpBuffer(result);
@@ -14055,21 +14062,22 @@ dumpTableSchema(Archive *fout, DumpOptions *dopt, TableInfo *tbinfo)
1405514062
appendPQExpBuffer(q,"\nSERVER %s",fmtId(srvname));
1405614063
}
1405714064

14058-
if ((tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)||
14059-
(tbinfo->toast_reloptions&&strlen(tbinfo->toast_reloptions)>0))
14065+
if (nonemptyReloptions(tbinfo->reloptions)||
14066+
nonemptyReloptions(tbinfo->toast_reloptions))
1406014067
{
1406114068
booladdcomma= false;
1406214069

1406314070
appendPQExpBufferStr(q,"\nWITH (");
14064-
if (tbinfo->reloptions&&strlen(tbinfo->reloptions)>0)
14071+
if (nonemptyReloptions(tbinfo->reloptions))
1406514072
{
1406614073
addcomma= true;
14067-
appendPQExpBufferStr(q,tbinfo->reloptions);
14074+
fmtReloptionsArray(fout,q,tbinfo->reloptions,"");
1406814075
}
14069-
if (tbinfo->toast_reloptions&&strlen(tbinfo->toast_reloptions)>0)
14076+
if (nonemptyReloptions(tbinfo->toast_reloptions))
1407014077
{
14071-
appendPQExpBuffer(q,"%s%s",addcomma ?", " :"",
14072-
tbinfo->toast_reloptions);
14078+
if (addcomma)
14079+
appendPQExpBufferStr(q,", ");
14080+
fmtReloptionsArray(fout,q,tbinfo->toast_reloptions,"toast.");
1407314081
}
1407414082
appendPQExpBufferChar(q,')');
1407514083
}
@@ -14651,8 +14659,12 @@ dumpConstraint(Archive *fout, DumpOptions *dopt, ConstraintInfo *coninfo)
1465114659

1465214660
appendPQExpBufferChar(q,')');
1465314661

14654-
if (indxinfo->options&&strlen(indxinfo->options)>0)
14655-
appendPQExpBuffer(q," WITH (%s)",indxinfo->options);
14662+
if (nonemptyReloptions(indxinfo->indreloptions))
14663+
{
14664+
appendPQExpBufferStr(q," WITH (");
14665+
fmtReloptionsArray(fout,q,indxinfo->indreloptions,"");
14666+
appendPQExpBufferChar(q,')');
14667+
}
1465614668

1465714669
if (coninfo->condeferrable)
1465814670
{
@@ -15512,11 +15524,12 @@ dumpRule(Archive *fout, DumpOptions *dopt, RuleInfo *rinfo)
1551215524
/*
1551315525
* Apply view's reloptions when its ON SELECT rule is separate.
1551415526
*/
15515-
if (rinfo->reloptions&&strlen(rinfo->reloptions)>0)
15527+
if (nonemptyReloptions(rinfo->reloptions))
1551615528
{
15517-
appendPQExpBuffer(cmd,"ALTER VIEW %s SET (%s);\n",
15518-
fmtId(tbinfo->dobj.name),
15519-
rinfo->reloptions);
15529+
appendPQExpBuffer(cmd,"ALTER VIEW %s SET (",
15530+
fmtId(tbinfo->dobj.name));
15531+
fmtReloptionsArray(fout,cmd,rinfo->reloptions,"");
15532+
appendPQExpBufferStr(cmd,");\n");
1552015533
}
1552115534

1552215535
/*
@@ -16389,6 +16402,83 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
1638916402
returnbuffer->data;
1639016403
}
1639116404

16405+
/*
16406+
* Check if a reloptions array is nonempty.
16407+
*/
16408+
staticbool
16409+
nonemptyReloptions(constchar*reloptions)
16410+
{
16411+
/* Don't want to print it if it's just "{}" */
16412+
return (reloptions!=NULL&&strlen(reloptions)>2);
16413+
}
16414+
16415+
/*
16416+
* Format a reloptions array and append it to the given buffer.
16417+
*
16418+
* "prefix" is prepended to the option names; typically it's "" or "toast.".
16419+
*
16420+
* Note: this logic should generally match the backend's flatten_reloptions()
16421+
* (in adt/ruleutils.c).
16422+
*/
16423+
staticvoid
16424+
fmtReloptionsArray(Archive*fout,PQExpBufferbuffer,constchar*reloptions,
16425+
constchar*prefix)
16426+
{
16427+
char**options;
16428+
intnoptions;
16429+
inti;
16430+
16431+
if (!parsePGArray(reloptions,&options,&noptions))
16432+
{
16433+
write_msg(NULL,"WARNING: could not parse reloptions array\n");
16434+
if (options)
16435+
free(options);
16436+
return;
16437+
}
16438+
16439+
for (i=0;i<noptions;i++)
16440+
{
16441+
char*option=options[i];
16442+
char*name;
16443+
char*separator;
16444+
char*value;
16445+
16446+
/*
16447+
* Each array element should have the form name=value. If the "=" is
16448+
* missing for some reason, treat it like an empty value.
16449+
*/
16450+
name=option;
16451+
separator=strchr(option,'=');
16452+
if (separator)
16453+
{
16454+
*separator='\0';
16455+
value=separator+1;
16456+
}
16457+
else
16458+
value="";
16459+
16460+
if (i>0)
16461+
appendPQExpBufferStr(buffer,", ");
16462+
appendPQExpBuffer(buffer,"%s%s=",prefix,fmtId(name));
16463+
16464+
/*
16465+
* In general we need to quote the value; but to avoid unnecessary
16466+
* clutter, do not quote if it is an identifier that would not need
16467+
* quoting. (We could also allow numbers, but that is a bit trickier
16468+
* than it looks --- for example, are leading zeroes significant? We
16469+
* don't want to assume very much here about what custom reloptions
16470+
* might mean.)
16471+
*/
16472+
if (strcmp(fmtId(value),value)==0)
16473+
appendPQExpBufferStr(buffer,value);
16474+
else
16475+
appendStringLiteralAH(buffer,value,fout);
16476+
}
16477+
16478+
if (options)
16479+
free(options);
16480+
}
16481+
1639216482
/*
1639316483
* Execute an SQL query and verify that we got exactly one row back.
1639416484
*/

‎src/bin/pg_dump/pg_dump.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ typedef struct _tableInfo
205205
charrelreplident;/* replica identifier */
206206
char*reltablespace;/* relation tablespace */
207207
char*reloptions;/* options specified by WITH (...) */
208-
char*checkoption;/* WITH CHECK OPTION */
208+
char*checkoption;/* WITH CHECK OPTION, if any */
209209
char*toast_reloptions;/* WITH options for the TOAST table */
210210
boolhasindex;/* does it have any indexes? */
211211
boolhasrules;/* does it have any rules? */
@@ -282,7 +282,7 @@ typedef struct _indxInfo
282282
TableInfo*indextable;/* link to table the index is for */
283283
char*indexdef;
284284
char*tablespace;/* tablespace in which index is stored */
285-
char*options;/* options specified by WITH (...) */
285+
char*indreloptions;/* options specified by WITH (...) */
286286
intindnkeys;
287287
Oid*indkeys;
288288
boolindisclustered;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp