On Fri, Apr 4, 2025 at 6:25 PM Nathan Bossart <nathandboss...@gmail.com> wrote:
> On Fri, Apr 04, 2025 at 03:58:53PM -0500, Nathan Bossart wrote: > > I pushed commit 8ec0aae to fix this. > > And now I'm seeing cross-version test failures due to our use of WITH > ORDINALITY, which wasn't added until v9.4. Looking into it... > > > This patch shrinks the array size to 1 for versions < 9.4, which keeps the modern code fairly elegant.
From fe551ab55622f95d84ac4c4d79fba898c6b60057 Mon Sep 17 00:00:00 2001 From: Corey Huinker <corey.huin...@gmail.com> Date: Fri, 4 Apr 2025 19:30:00 -0400 Subject: [PATCH v1] Fall back to single attribute stat fetching for versions < 9.4 Existing attribute statistics batch fetching query relies on the existence of WITH ORDINALTIY, as well as multi-parameter unnest() calls. Without those, we have no choice but to fall back to single relation fetching. Preserve the existing array building infrastructure, and drop the array size to 1 for older versions. --- src/bin/pg_dump/pg_dump.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 0e915432e77..b88188448b0 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -10571,6 +10571,14 @@ fetchAttributeStats(Archive *fout) PGresult *res = NULL; static TocEntry *te; static bool restarted; + int max_rels = MAX_ATTR_STATS_RELS; + + /* + * Versions prior to 9.4 lack the unnest() WITH ORDINALITY feature + * that we need to keep the relation batches in order. + */ + if (fout->remoteVersion < 90400) + max_rels = 1; /* If we're just starting, set our TOC pointer. */ if (!te) @@ -10596,7 +10604,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 +10717,25 @@ 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. + * + * WITH ORDINALITY was introduced in 9.4, and multi-argument unnest() + * was introduced in 9.3. Rather than create a bunch of corner-cases, + * we simply fall back to fetching a single relation per call. */ - 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::text[])[1] " + "AND s.tablename = ($2::text[])[1] " + "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); base-commit: 0f43083d16f4be7c01efa80d05d0eef5e5ff69d3 -- 2.49.0