diff options
author | Nathan Bossart <nathan@postgresql.org> | 2025-04-04 21:05:30 -0500 |
---|---|---|
committer | Nathan Bossart <nathan@postgresql.org> | 2025-04-04 21:05:30 -0500 |
commit | f0d0083f52f994989b1bb6723e7bd0fad9f586cd (patch) | |
tree | f4468bb077a027d73c87b898f8de29a7b5629822 | |
parent | 43b8e6c4abfb632bbff5b3a26dc39bf3f188afff (diff) | |
download | postgresql-f0d0083f52f994989b1bb6723e7bd0fad9f586cd.tar.gz postgresql-f0d0083f52f994989b1bb6723e7bd0fad9f586cd.zip |
pg_dump: Fix query for gathering attribute stats on older versions.
Commit 9c02e3a986 taught pg_dump to retrieve attribute statistics
for 64 relations at a time. pg_dump supports dumping from v9.2 and
newer versions, but our query for retrieving statistics for
multiple relations uses WITH ORDINALITY and multi-argument
UNNEST(), both of which were introduced in v9.4. To fix, we resort
to gathering statistics for a single relation at a time on versions
older than v9.4.
Per buildfarm member crake.
Author: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/Z_BcWVMvlUIJ_iuZ%40nathan
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 0e915432e77..8e6364d32d7 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -10571,6 +10571,16 @@ fetchAttributeStats(Archive *fout) PGresult *res = NULL; static TocEntry *te; static bool restarted; + int max_rels = MAX_ATTR_STATS_RELS; + + /* + * Our query for retrieving statistics for multiple relations uses WITH + * ORDINALITY and multi-argument UNNEST(), both of which were introduced + * in v9.4. For older versions, we resort to gathering statistics for a + * single relation at a time. + */ + if (fout->remoteVersion < 90400) + max_rels = 1; /* If we're just starting, set our TOC pointer. */ if (!te) @@ -10596,7 +10606,7 @@ fetchAttributeStats(Archive *fout) * This is perhaps not the sturdiest assumption, so we verify it matches * reality in dumpRelationStats_dumper(). */ - for (; te != AH->toc && count < MAX_ATTR_STATS_RELS; te = te->next) + for (; te != AH->toc && count < max_rels; te = te->next) { if ((te->reqs & REQ_STATS) != 0 && strcmp(te->desc, "STATISTICS DATA") == 0) @@ -10709,14 +10719,26 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * This may not work for all versions. + * + * Our query for retrieving statistics for multiple relations uses + * WITH ORDINALITY and multi-argument UNNEST(), both of which were + * introduced in v9.4. For older versions, we resort to gathering + * statistics for a single relation at a time. */ - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " - "ON s.schemaname = u.schemaname " - "AND s.tablename = u.tablename " - "WHERE s.tablename = ANY($2) " - "ORDER BY u.ord, s.attname, s.inherited"); + if (fout->remoteVersion >= 90400) + appendPQExpBufferStr(query, + "FROM pg_catalog.pg_stats s " + "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " + "ON s.schemaname = u.schemaname " + "AND s.tablename = u.tablename " + "WHERE s.tablename = ANY($2) " + "ORDER BY u.ord, s.attname, s.inherited"); + else + appendPQExpBufferStr(query, + "FROM pg_catalog.pg_stats s " + "WHERE s.schemaname = $1[1] " + "AND s.tablename = $2[1] " + "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); |