Dump Statistic Issue with Index on Expressions — May 2026 Summary
Overview
A reported bug in pg_dump --statistics-only (new in PostgreSQL 18) involving cross-index attribute name leakage was investigated and ultimately determined to be not reproducible on vanilla PostgreSQL. The issue is specific to forks that generate pg_statistic records for non-expression indexes.
The Bug
When a table has both an expression index and a subsequent plain index, pg_dump --statistics-only could fail with:
pg_dump: error: could not find index attname "source_system"
The root cause: indAttNames/nindAttNames fields are only populated for expression indexes during the index iteration in the stats-dumping path. If a plain index is processed afterward, it inherits stale pointers from the prior expression index, causing attribute name lookup failures.
Key Finding
Alexander Korotkov could not reproduce the error and identified why: in vanilla PostgreSQL, dumpRelationStats_dumper() only iterates indexes that have pg_statistic entries, which are exclusively expression indexes (controlled by the if (indexInfo->ii_Expressions != NIL && va_cols == NIL) check in do_analyze_rel()). Plain indexes never reach the code that reads the stale fields.
Maksim Melnikov confirmed this after investigation — the bug manifests only in Postgres Pro's fork, which generates statistics for additional index types beyond expression indexes.
Current Status
The thread concluded in a "nice-to-have defensive fix" state. The code pattern (conditionally populating per-iteration fields without clearing them) is acknowledged as latent-buggy and "prone to bugs," but since it cannot be triggered in vanilla PostgreSQL, there is no regression urgency. Whether to commit the defensive cleanup remains a code-quality judgment call.
Gap Identified
The statistics-dump feature lacks regression test coverage for the combination of expression indexes and plain indexes on the same table — a gap that could mask future issues if the iteration logic changes.