[PG19] pg_dump marks extended statistics of pre-v15 partitioned tables as non-inherited

From: Artem Gavrilov <artem(dot)gavrilov(at)percona(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: [PG19] pg_dump marks extended statistics of pre-v15 partitioned tables as non-inherited
Date: 2026-10-22 15:12:17
Message-ID: CAFPkQKxoB=kBdVsHXHvprV5j2OOBP5x5ea2yL9h0d3HtjuX+Sg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello hackers,

Since c32fb29e979, pg_dump --statistics dumps extended statistics
data. For servers older than v15, where pg_stats_ext has no inherited
column, the query hard-codes the flag to false. The commit message
says "In v14 and older versions, inherited extended statistics are not
supported". That is true for the catalog, but not for the data: since
20b9fa308eb, back-patched down to 10.20, 11.15, 12.10, 13.6 and 14.2,
these versions build inherited extended stats on partitioned tables.
The planner always searches for inherited extended statistics on
partitioned tables, so after restore, data dumped as non-inherited is
never used. pg_upgrade from v10-v14 is affected the same way, as it
transfers statistics by default.

Reproduction on 14.24:

CREATE TABLE p (k int, a int, b int) PARTITION BY RANGE (k);
CREATE TABLE p1 PARTITION OF p FOR VALUES FROM (0) TO (50000);
CREATE TABLE p2 PARTITION OF p FOR VALUES FROM (50000) TO (100000);
INSERT INTO p SELECT i, i % 100, i % 100 FROM generate_series(0, 99999) i;
CREATE STATISTICS p_ab (ndistinct) ON a, b FROM p;
ANALYZE p;

On 14 the GROUP BY estimate is 100 rows:

SET max_parallel_workers_per_gather = 0; -- keep plan shapes the same
EXPLAIN SELECT a, b FROM p GROUP BY a, b;
QUERY PLAN
------------------------------------------------------------------------
HashAggregate (cost=2542.00..2543.00 rows=100 width=8)
Group Key: p.a, p.b
-> Append (cost=0.00..2042.00 rows=100000 width=8)
-> Seq Scan on p1 p_1 (cost=0.00..771.00 rows=50000 width=8)
-> Seq Scan on p2 p_2 (cost=0.00..771.00 rows=50000 width=8)

After pg_dump --statistics and restoring into REL_19_STABLE the
planner falls back to the product of per-column n_distinct:

SET max_parallel_workers_per_gather = 0;
EXPLAIN SELECT a, b FROM p GROUP BY a, b;
QUERY PLAN
------------------------------------------------------------------------
HashAggregate (cost=2701.48..2801.48 rows=10000 width=8)
Group Key: p.a, p.b
-> Append (cost=0.00..2170.11 rows=106274 width=8)
-> Seq Scan on p1 p_1 (cost=0.00..819.37 rows=53137 width=8)
-> Seq Scan on p2 p_2 (cost=0.00..819.37 rows=53137 width=8)

SELECT statistics_name, inherited FROM pg_stats_ext;
statistics_name | inherited
-----------------+-----------
p_ab | f

The attached patch deduces the inherited flag from the relkind of the
table for pre-v15 servers, the same way 20b9fa308eb chooses which data
to build: true for partitioned tables, false for all other relations.
pg_dump already has the relkind in TableInfo, so I did it in C rather
than in the SQL query. The patch applies to master (5ffb8c74093) and
REL_19_STABLE (2dc899f780f).

--
Artem Gavrilov
Senior Software Engineer, Percona
artem(dot)gavrilov(at)percona(dot)com
percona.com

Attachment Content-Type Size
0001-pg_dump-Fix-inherited-flag-of-extended-stats-from-pr.patch application/octet-stream 3.6 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Manu 2026-10-22 15:13:58 Re: [PG19] Promotion hangs behind a backend blocked on a stuck client
Previous Message Nazneen Jafri 2026-10-22 15:02:02 Re: Fix rescan costing of single-batch hash joins