v1-0001-Fall-back-to-single-attribute-stat-fetching-for-v.patch
text/x-patch
Filename: v1-0001-Fall-back-to-single-attribute-stat-fetching-for-v.patch
Type: text/x-patch
Part: 0
Message:
Re: Statistics Import and Export
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Fall back to single attribute stat fetching for versions < 9.4
| File | + | − |
|---|---|---|
| src/bin/pg_dump/pg_dump.c | 27 | 8 |
From fe551ab55622f95d84ac4c4d79fba898c6b60057 Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@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