Skip to content

Commit a6060f1

Browse files
pg_dump: Fix array literals in fetchAttributeStats().
Presently, fetchAttributeStats() builds array literals by treating the elements as SQL identifiers. This is incorrect for a couple of reasons: * Array literal content must match the external text representation of the array, i.e., what array_out() would return. One notable problem is that double quotes are escaped with "" in identifiers but with \" in array literals. To fix, build the array content using the pre-existing appendPGArray() function. * Array literals must be written as string constants. A notable problem here is that single quotes are escaped via '' in strings but are not escaped in the text representation of an array. To fix, append the aforementioned array literal content to the query with appendStringLiteralAH(). While at it, modify a test case to use an identifier that would cause the test to fail without this change. Oversight in commit 9c02e3a. Reported-by: Philippe Beaudoin <pbh.emaj@free.fr> Author: Jian He <jian.universality@gmail.com> Co-authored-by: Nathan Bossart <nathandbossart@gmail.com> Co-authored-by: Stepan Neretin <slpmcf@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Bug: #18923 Discussion: https://postgr.es/m/18923-e79273f87c6bed69%40postgresql.org
1 parent cbf53e2 commit a6060f1

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10765,6 +10765,9 @@ fetchAttributeStats(Archive *fout)
1076510765
restarted = true;
1076610766
}
1076710767

10768+
appendPQExpBufferChar(nspnames, '{');
10769+
appendPQExpBufferChar(relnames, '{');
10770+
1076810771
/*
1076910772
* Scan the TOC for the next set of relevant stats entries. We assume
1077010773
* that statistics are dumped in the order they are listed in the TOC.
@@ -10776,23 +10779,25 @@ fetchAttributeStats(Archive *fout)
1077610779
if ((te->reqs & REQ_STATS) != 0 &&
1077710780
strcmp(te->desc, "STATISTICS DATA") == 0)
1077810781
{
10779-
appendPQExpBuffer(nspnames, "%s%s", count ? "," : "",
10780-
fmtId(te->namespace));
10781-
appendPQExpBuffer(relnames, "%s%s", count ? "," : "",
10782-
fmtId(te->tag));
10782+
appendPGArray(nspnames, te->namespace);
10783+
appendPGArray(relnames, te->tag);
1078310784
count++;
1078410785
}
1078510786
}
1078610787

10788+
appendPQExpBufferChar(nspnames, '}');
10789+
appendPQExpBufferChar(relnames, '}');
10790+
1078710791
/* Execute the query for the next batch of relations. */
1078810792
if (count > 0)
1078910793
{
1079010794
PQExpBuffer query = createPQExpBuffer();
1079110795

10792-
appendPQExpBuffer(query, "EXECUTE getAttributeStats("
10793-
"'{%s}'::pg_catalog.name[],"
10794-
"'{%s}'::pg_catalog.name[])",
10795-
nspnames->data, relnames->data);
10796+
appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
10797+
appendStringLiteralAH(query, nspnames->data, fout);
10798+
appendPQExpBufferStr(query, "::pg_catalog.name[],");
10799+
appendStringLiteralAH(query, relnames->data, fout);
10800+
appendPQExpBufferStr(query, "::pg_catalog.name[])");
1079610801
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1079710802
destroyPQExpBuffer(query);
1079810803
}

src/bin/pg_dump/t/002_pg_dump.pl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,13 +4834,13 @@
48344834
CREATE TABLE dump_test.has_stats
48354835
AS SELECT g.g AS x, g.g / 2 AS y FROM generate_series(1,100) AS g(g);
48364836
CREATE MATERIALIZED VIEW dump_test.has_stats_mv AS SELECT * FROM dump_test.has_stats;
4837-
CREATE INDEX dup_test_post_data_ix ON dump_test.has_stats(x, (x - 1));
4837+
CREATE INDEX """dump_test""\'s post-data index" ON dump_test.has_stats(x, (x - 1));
48384838
ANALYZE dump_test.has_stats, dump_test.has_stats_mv;',
48394839
regexp => qr/^
48404840
\QSELECT * FROM pg_catalog.pg_restore_relation_stats(\E\s+
48414841
'version',\s'\d+'::integer,\s+
48424842
'schemaname',\s'dump_test',\s+
4843-
'relname',\s'dup_test_post_data_ix',\s+
4843+
'relname',\s'"dump_test"''s\ post-data\ index',\s+
48444844
'relpages',\s'\d+'::integer,\s+
48454845
'reltuples',\s'\d+'::real,\s+
48464846
'relallvisible',\s'\d+'::integer,\s+
@@ -4849,7 +4849,7 @@
48494849
\QSELECT * FROM pg_catalog.pg_restore_attribute_stats(\E\s+
48504850
'version',\s'\d+'::integer,\s+
48514851
'schemaname',\s'dump_test',\s+
4852-
'relname',\s'dup_test_post_data_ix',\s+
4852+
'relname',\s'"dump_test"''s\ post-data\ index',\s+
48534853
'attnum',\s'2'::smallint,\s+
48544854
'inherited',\s'f'::boolean,\s+
48554855
'null_frac',\s'0'::real,\s+

0 commit comments

Comments
 (0)