public inbox for [email protected]  
help / color / mirror / Atom feed
Add starelid, attnum to pg_stats and leverage this in pg_dump
36+ messages / 5 participants
[nested] [flat]

* Add starelid, attnum to pg_stats and leverage this in pg_dump
@ 2026-02-25 21:22 Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-02-26 20:36 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Tom Lane <[email protected]>
  0 siblings, 2 replies; 36+ messages in thread

From: Corey Huinker @ 2026-02-25 21:22 UTC (permalink / raw)
  To: [email protected]; [email protected]

Per side conversation in [1], this patch exposes pg_statistic.starelid in
the pg_stats view (0001) and then changes pg_dump to use the starelid in
the queries on pg_stats rather than the combination of schemaname+relname,
which gets a bit clumsy in bulk array fetching, and also leads to bad query
plans against pg_stats because the security barrier is also an optimization
barrier, which means that queries often try to hash join, which causes the
very large table pg_statistic to be sequentially scanned, and that's a bad
time. Currently we get around this by adding a redundant qual to the query
which gooses the plan towards an index, and that works fine for now, but
there's no guarantee that it will continue to work in the future, so this
change brings some plan safety as well.

0001 also exposes pg_statistic.attnum. This is no direct application of
this in 0002, but people have often expressed surprise that pg_dump orders
the pg_restore_attribute_stats() calls by attname rather than attnum, and
if we wanted to change that now we could (albeit only on new versions).

[1] https://www.postgresql.org/message-id/aZ3RbTE8Racscykc@nathan


Attachments:

  [text/x-patch] v1-0001-Add-attnum-and-starelid-columns-to-pg_stats.patch (76.3K, 3-v1-0001-Add-attnum-and-starelid-columns-to-pg_stats.patch)
  download | inline diff:
From 59ac1286cee4a30961cc2661f8bf75ec0969e5ba Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 24 Feb 2026 16:12:55 -0500
Subject: [PATCH v1 1/2] Add attnum and starelid columns to pg_stats.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

Additionally, there have been times when it would have been nice to have
attnum as well as attname available.
---
 src/backend/catalog/system_views.sql       |   8 +-
 src/test/regress/expected/rules.out        |   2 +
 src/test/regress/expected/stats_import.out | 288 ++++++++++++++-------
 src/test/regress/sql/stats_import.sql      | 144 +++++++++--
 doc/src/sgml/system-views.sgml             |  19 ++
 5 files changed, 338 insertions(+), 123 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 1ea8f1faa9e..4eeab47a9e9 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -184,9 +184,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        s.starelid AS starelid,
+        a.attnum AS attnum,
+        a.attname AS attname,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 78a37d9fc8f..a2520db28e0 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2513,6 +2513,8 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    s.starelid,
+    a.attnum,
     a.attname,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index d6cc701500e..2249091ba0e 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -488,15 +488,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -515,15 +519,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -540,15 +548,19 @@ WARNING:  unrecognized argument name: "nope"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -566,15 +578,19 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -592,15 +608,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -620,15 +640,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -647,15 +671,19 @@ WARNING:  invalid input syntax for type integer: "four"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -672,15 +700,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -698,15 +730,19 @@ WARNING:  "histogram_bounds" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -722,15 +758,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -748,15 +788,19 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      5 | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -773,15 +817,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      |      5 | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -801,15 +849,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -827,15 +879,19 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      4 | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -853,15 +909,19 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      4 | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -878,15 +938,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      4 | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -905,15 +969,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -929,15 +997,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      |      4 | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -957,15 +1029,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      |      4 | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -985,15 +1061,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1011,15 +1091,19 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      |      5 | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1037,15 +1121,19 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      |      5 | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1062,15 +1150,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      |      5 | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1089,15 +1181,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attnum | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+--------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      |      1 | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 8db7cd93b88..0c368b09a8c 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -368,7 +368,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'avg_width', 5::integer,
     'n_distinct', 0.6::real);
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -387,7 +391,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'inherited', false::boolean,
     'null_frac', 0.4::real);
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -403,7 +411,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.2::real,
     'nope', 0.5::real);
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -420,7 +432,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -437,7 +453,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_vals', '{1,2,3}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -455,7 +475,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -473,7 +497,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -490,7 +518,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -507,7 +539,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -523,7 +559,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,2,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -540,7 +580,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -557,7 +601,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -575,7 +623,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -592,7 +644,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -609,7 +665,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_empty_frac', 0.5::real
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -626,7 +686,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -643,7 +707,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -659,7 +727,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -677,7 +749,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -695,7 +771,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -712,7 +792,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elems', '{one,two}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -729,7 +813,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -746,7 +834,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -763,7 +855,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attnum, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..59f8ff891e7 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,25 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>starelid</structfield> <type>oid</type>
+      </para>
+      <para>
+       ID of the relation
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>name</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>

base-commit: 4c1a27e53a508f74883cda52a6c8612121d7fd6b
-- 
2.53.0



  [text/x-patch] v1-0002-pg_dump-Use-starelid-in-getAttributeStats.patch (8.0K, 4-v1-0002-pg_dump-Use-starelid-in-getAttributeStats.patch)
  download | inline diff:
From 9f8b7b6177736ae14b4021647342e40602fdba0e Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v1 2/2] pg_dump: Use starelid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose starelid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use starelid on
versions in which starelid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 101 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 83 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 450cec285b3..a21cb0560f3 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7137,6 +7137,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11031,8 +11032,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11066,8 +11068,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11080,14 +11092,34 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing");
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11095,16 +11127,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11163,8 +11209,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11183,22 +11239,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (starelid, ord) "
+								 "ON s.starelid = u.starelid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11206,7 +11270,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 6deceef23f3..1d6b215d6a5 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-02-26 20:16 ` Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  1 sibling, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-02-26 20:16 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: [email protected]; [email protected]

Hi,

> Per side conversation in [1], this patch exposes pg_statistic.starelid in the pg_stats view (0001)
> and then changes pg_dump to use the starelid in the queries on pg_stats rather than the
> combination of schemaname+relname, which gets a bit clumsy in bulk array fetching, and
> also leads to bad query plans against pg_stats because the security barrier is also an
> optimization barrier, which means that queries often try to hash join, which causes the
> very large table pg_statistic to be sequentially scanned, and that's a bad time. Currently
> we get around this by adding a redundant qual to the query which gooses the plan towards
> an index, and that works fine for now, but there's no guarantee that it will continue to work
> in the future, so this change brings some plan safety as well.

This alone seems like a good enough reason to include startled in
pg_stat, besides other
future use-cases this will simplify as discussed in [1]

> 0001 also exposes pg_statistic.attnum. This is no direct application of this in 0002,
> but people have often expressed surprise that pg_dump orders the
> pg_restore_attribute_stats() calls by attname rather than attnum,
> and if we wanted to change that now we could (albeit only on new versions).

This seems logical

v1-0001 comments:

1/

-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        s.starelid AS starelid,
+        a.attnum AS attnum,
+        a.attname AS attname,

Ideally, we would want the OID and attnum to be first columns to match
the pg_stat_activity/pg_stat_progress style, but that will be too invasive.

The new attname column should be moved after tablename, however.

2/

+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>name</type>
+       (references <link
linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>

- This <type> should be int2
- Maybe for the describtion, it should be something like:

  "The number of the column, as in
<structname>pg_attribute</structname>.<structfield>attnum</structfield>"

  to be close to the description in pg_attribute

3/

+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>starelid</structfield> <type>oid</type>
+      </para>
+      <para>
+       ID of the relation
+      </para></entry>
+     </row>

This should indicate it is a reference to pg_class.oid, like so:

```
(references <link
linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
```

Maybe "ID of the table or index" is better, since this can only be a
table or index
for pg_stats.

I dislike the existing "pg_stats.tablename", since this can also be an
expression index.
"pg_stats.relation" with a description of "Name of table or index" is
more appropriate.
It is a change that we can possibly make in a major version. Looked
through the archives,
and did not see this being reported/discussed.

v1-0002:

I examined the version variants of getAttributeStats and all looks good,
and also ran a test on a 18 and 19 server version with the patched pg_dump
client and all looks good.

One minor comment is:


+                    pg_fatal("statistics table oid information missing");


I noticed in other pg_fatal messages, we include OIDs

            pg_fatal("could not find function definition for function
with OID %u",
                     cast->castfunc);

Should we do the same here?



[1] https://www.postgresql.org/message-id/aZ3RbTE8Racscykc@nathan

--
Sami Imseih
Amazon Web Services (AWS)






^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-02 04:03   ` Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-02 04:03 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: [email protected]; [email protected]

> Ideally, we would want the OID and attnum to be first columns to match
> the pg_stat_activity/pg_stat_progress style, but that will be too invasive.
>

I don't think there is an order that will make anyone happy, let alone
everyone.

The existing columns (schemaname, tablename, attname, inherited) constitute
a grain, so its hard to separate them.

Once we add attnum, that can replace attname in the above grain. Once we
add starelid/tableid, then that can be combined win inherited and either
attnum/attname for a grain. The ordering of these columns will largely fall
down to the perspective of the person seeking to use it.



>
> - This <type> should be int2
> - Maybe for the describtion, it should be something like:
>

+1


>
>   "The number of the column, as in
> <structname>pg_attribute</structname>.<structfield>attnum</structfield>"
>

We don't do that for attname, why would attnum be different?


>
>
> +     <row>
> +      <entry role="catalog_table_entry"><para role="column_definition">
> +       <structfield>starelid</structfield> <type>oid</type>
> +      </para>
> +      <para>
> +       ID of the relation
> +      </para></entry>
> +     </row>
>
> This should indicate it is a reference to pg_class.oid, like so:
>

I went with pg_attribute, but the reference is there now.


>
> Maybe "ID of the table or index" is better, since this can only be a
> table or index
> for pg_stats.
>

I went with table, because it matches the tablename definition (i.e. it is
equally inaccurate).


>
> I dislike the existing "pg_stats.tablename", since this can also be an
> expression index.
> "pg_stats.relation" with a description of "Name of table or index" is
> more appropriate.
> It is a change that we can possibly make in a major version. Looked
> through the archives,
> and did not see this being reported/discussed.
>

I don't see it changing in any version, minor or major.



>
> v1-0002:
>
> I examined the version variants of getAttributeStats and all looks good,
> and also ran a test on a 18 and 19 server version with the patched pg_dump
> client and all looks good.
>
> One minor comment is:
>
>
> +                    pg_fatal("statistics table oid information missing");
>
>
> I noticed in other pg_fatal messages, we include OIDs
>
>             pg_fatal("could not find function definition for function
> with OID %u",
>                      cast->castfunc);
>
> Should we do the same here?
>

If I had the oid, I wouldn't have the error. :)

I've modified the error message to give the namespace/tag of the entry.
Will post revised patch later.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-04 22:54     ` Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-04 22:54 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: [email protected]; [email protected]

>> I dislike the existing "pg_stats.tablename", since this can also be an
>> expression index.
>> "pg_stats.relation" with a description of "Name of table or index" is
>> more appropriate.
>> It is a change that we can possibly make in a major version. Looked
>> through the archives,
>> and did not see this being reported/discussed.
>
>
> I don't see it changing in any version, minor or major.

This could be a separate discussion as it's not the fault of this patch,
but clearly "tablename" is not correct here.

>> I noticed in other pg_fatal messages, we include OIDs
>>
>>             pg_fatal("could not find function definition for function
>> with OID %u",
>>                      cast->castfunc);
>>
>> Should we do the same here?
>
>
> If I had the oid, I wouldn't have the error. :)

oops, you're right.


I noticed that you changed the tests to selecting individual columns. I am
not clear as to why this is better?

-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram

Otherwise v2 LGTM.

--
Sami Imseih
Amazon Web Services (AWS)





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-05 20:40       ` Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-05 20:40 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: [email protected]; [email protected]

>
> >> "pg_stats.relation" with a description of "Name of table or index" is
> >> more appropriate.
> >> It is a change that we can possibly make in a major version. Looked
> >> through the archives,
> >> and did not see this being reported/discussed.
> >
> >
> > I don't see it changing in any version, minor or major.
>
> This could be a separate discussion as it's not the fault of this patch,
> but clearly "tablename" is not correct here.
>

Certainly up for debate, but changing it would break existing scripts, and
that's generally a non-starter around here.


> I noticed that you changed the tests to selecting individual columns. I am
> not clear as to why this is better?
>
> -SELECT *
> +SELECT schemaname, tablename, attname, attnum, inherited, null_frac,
> avg_width,
> +    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
> +    correlation, most_common_elems, most_common_elem_freqs,
> +    elem_count_histogram, range_length_histogram, range_empty_frac,
> +    range_bounds_histogram
>

Well, the oid is now a part of the view, and that's not stable from one
regression run to the next, so we have to exclude it.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-05 20:45         ` Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-05 20:45 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: [email protected]; [email protected]

>> I noticed that you changed the tests to selecting individual columns. I am
>> not clear as to why this is better?
>>
>> -SELECT *
>> +SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
>> +    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
>> +    correlation, most_common_elems, most_common_elem_freqs,
>> +    elem_count_histogram, range_length_histogram, range_empty_frac,
>> +    range_bounds_histogram

Makes sense.

BTW, I do not see a CF enty for this.

Thanks!

--
Sami Imseih
Amazon Web Services (AWS)





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-05 21:40           ` Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-05 21:40 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: [email protected]; [email protected]

>
>
> BTW, I do not see a CF enty for this.


I just created https://commitfest.postgresql.org/patch/6568/ - thanks!


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-06 23:08             ` Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-06 23:08 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Thu, Mar 05, 2026 at 04:40:56PM -0500, Corey Huinker wrote:
> I just created https://commitfest.postgresql.org/patch/6568/ - thanks!

I just skimmed through the latest patches, and they look generally
reasonable to me.  I'll take a closer look soon and hopefully get these
committed.

Note to self: 0001 requires a catversion bump.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-06 23:19               ` Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-06 23:19 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Fri, Mar 06, 2026 at 05:08:58PM -0600, Nathan Bossart wrote:
> I just skimmed through the latest patches, and they look generally
> reasonable to me.  I'll take a closer look soon and hopefully get these
> committed.

Oh, a question I forgot to ask: why wouldn't we do the same thing for
pg_stats_ext and pg_stats_ext_exprs?

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-09 15:44                 ` Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-09 15:44 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Corey Huinker <[email protected]>; [email protected]

> Oh, a question I forgot to ask: why wouldn't we do the same thing for
> pg_stats_ext and pg_stats_ext_exprs?

The primary purpose of adding the relid is to optimize queries on
pg_statistics in pg_dump.

+ *
* The redundant filter clause on s.tablename = ANY(...) seems
* 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.
+ * This seems to work for all version prior to v19, after which we
+ * will use the starelid, which is simpler.

pg_stats_ext and pg_stats_ext_expr do not have the same concern.

If we do add relid there, it will be for consistency only.

--
Sami Imseih
Amazon Web Services (AWS)





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-09 15:51                   ` Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-09 15:51 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: Corey Huinker <[email protected]>; [email protected]

On Mon, Mar 09, 2026 at 10:44:58AM -0500, Sami Imseih wrote:
>> Oh, a question I forgot to ask: why wouldn't we do the same thing for
>> pg_stats_ext and pg_stats_ext_exprs?
> 
> [...]
> 
> If we do add relid there, it will be for consistency only.

It might be only for consistency for now, but it strikes me as something
that could be handy down the road (in which case it'd be nice to minimize
the number of versions that need a fallback).

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-09 18:29                     ` Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-09 18:29 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 9, 2026 at 11:51 AM Nathan Bossart <[email protected]>
wrote:

> On Mon, Mar 09, 2026 at 10:44:58AM -0500, Sami Imseih wrote:
> >> Oh, a question I forgot to ask: why wouldn't we do the same thing for
> >> pg_stats_ext and pg_stats_ext_exprs?
> >
> > [...]
> >
> > If we do add relid there, it will be for consistency only.
>
> It might be only for consistency for now, but it strikes me as something
> that could be handy down the road (in which case it'd be nice to minimize
> the number of versions that need a fallback).
>
> --
> nathan
>

You're both right. Currently, we fetch extended stats one at a time, thus
there's no _immediate_ need to do so.

But "why wait until there is a crisis" is solid reasoning and for that I
had already coded up the change. I did have one small problem in that
Michael Paquier had hoped that we could get the expr index (-1, -2, etc) on
the expressions as that was something that we at least briefly thought we'd
need for importing expression statistics. However the existing query uses a
SELECT unnest(a), unnest(b) pattern in it, and WITH ORDINALITY is not
allowed, and the workarounds I found seemed a bit tortured. Hence, I
decided to leave that out so as not to distract from the now accepted
patch, and with that out of the way I'll happily inflict that tortured SQL
on y'all.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-09 18:56                       ` Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-09 18:56 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Nathan Bossart <[email protected]>; [email protected]

>> nathan
>
>
> You're both right. Currently, we fetch extended stats one at a time, thus there's no _immediate_ need to do so.
>
> But "why wait until there is a crisis" is solid reasoning and for that I had already coded up the change.
>I did have one small problem in that Michael Paquier had hoped that we could get the expr index (-1, -2, etc) on the expressions
> as that was something that we at least briefly thought we'd need for importing expression statistics. However the existing query
> uses a SELECT unnest(a), unnest(b) pattern in it, and WITH ORDINALITY is not allowed, and the workarounds I found seemed a
> bit tortured. Hence, I decided to leave that out so as not to distract from the now accepted patch, and with that out of the way
> I'll happily inflict that tortured SQL on y'all.

Can we add the tableid  for now (see 0003) and follow-up with another
thread with the sql changes to pg_dump?

I also corrected v2-0001. The docs were still referencing "starlid"
instead of "tableid"

--
Sami Imseih
Amazon Web Services (AWS)


Attachments:

  [application/octet-stream] v3-0002-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 2-v3-0002-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From 06aa5e704719167c6afc5c7f7b2f57f2be460cab Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v3 2/3] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 8bde1b382de..5961277d4ca 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7237,6 +7237,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11131,8 +11132,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11166,8 +11168,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11180,14 +11192,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11195,16 +11228,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11263,8 +11310,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11283,22 +11340,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11306,7 +11371,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.50.1 (Apple Git-155)



  [application/octet-stream] v3-0003-Add-tableid-column-to-pg_stats_ext-and-pg_stats_e.patch (4.9K, 3-v3-0003-Add-tableid-column-to-pg_stats_ext-and-pg_stats_e.patch)
  download | inline diff:
From debfe72bd36d009a504aee6f4ba809e0780c105f Mon Sep 17 00:00:00 2001
From: Sami Imseih <[email protected]>
Date: Mon, 9 Mar 2026 12:36:35 -0500
Subject: [PATCH v3 3/3] Add tableid column to pg_stats_ext and
 pg_stats_ext_exprs

Same as dcccf721929, add a tableid column to pg_stats_ext and
pg_stats_ext_exprs.  For now, this is done to be consistent with
pg_stats, but there could also be future cases where having the
OID of the table will be useful.

Discussion: https://www.postgresql.org/message-id/aa7sZcuRrlkeVJGX%40nathan
---
 doc/src/sgml/system-views.sgml             | 20 ++++++++++++++++++++
 src/backend/catalog/system_views.sql       |  2 ++
 src/test/regress/expected/rules.out        |  2 ++
 src/test/regress/expected/stats_import.out |  4 ++--
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 8ec5a23e3cf..15ecadb493e 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4686,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4897,6 +4907,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 70846f1555d..20ed78fddb0 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -280,6 +280,7 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           c.oid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
@@ -314,6 +315,7 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           c.oid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 46be5c7ac90..7bc7fab7191 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2618,6 +2618,7 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    c.oid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
@@ -2646,6 +2647,7 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    c.oid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 8d66d4d9329..fa1ba01f272 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -66,7 +66,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    16
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -107,7 +107,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    21
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
-- 
2.50.1 (Apple Git-155)



  [application/octet-stream] v3-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch (76.6K, 4-v3-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch)
  download | inline diff:
From dcccf7219294d8e2f4203da5a660fb4cc522fc7a Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 24 Feb 2026 16:12:55 -0500
Subject: [PATCH v3 1/3] Add tableid and attnum columns to pg_stats.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

Additionally, there have been times when it would have been nice to have
attnum as well as attname available.
---
 doc/src/sgml/system-views.sgml             |  20 ++
 src/backend/catalog/system_views.sql       |   8 +-
 src/test/regress/expected/rules.out        |   2 +
 src/test/regress/expected/stats_import.out | 288 ++++++++++++++-------
 src/test/regress/sql/stats_import.sql      | 144 +++++++++--
 5 files changed, 339 insertions(+), 123 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..8ec5a23e3cf 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ecb7c996e86..70846f1555d 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index deb6e2ad6a9..46be5c7ac90 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2524,7 +2524,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index c7adb783da2..8d66d4d9329 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -642,15 +642,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -669,15 +673,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -694,15 +702,19 @@ WARNING:  unrecognized argument name: "nope"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -720,15 +732,19 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -746,15 +762,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -774,15 +794,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -801,15 +825,19 @@ WARNING:  invalid input syntax for type integer: "four"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -826,15 +854,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -852,15 +884,19 @@ WARNING:  "histogram_bounds" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -876,15 +912,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -902,15 +942,19 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -927,15 +971,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -955,15 +1003,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -981,15 +1033,19 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1007,15 +1063,19 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1032,15 +1092,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1059,15 +1123,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1083,15 +1151,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1111,15 +1183,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1139,15 +1215,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1165,15 +1245,19 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1191,15 +1275,19 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1216,15 +1304,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1243,15 +1335,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0518bbf6f42..8fbec83b5e0 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -520,7 +520,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'avg_width', 5::integer,
     'n_distinct', 0.6::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -539,7 +543,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'inherited', false::boolean,
     'null_frac', 0.4::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -555,7 +563,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.2::real,
     'nope', 0.5::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -572,7 +584,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -589,7 +605,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_vals', '{1,2,3}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -607,7 +627,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -625,7 +649,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -642,7 +670,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -659,7 +691,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -675,7 +711,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,2,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -692,7 +732,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -709,7 +753,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -727,7 +775,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -744,7 +796,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -761,7 +817,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_empty_frac', 0.5::real
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -778,7 +838,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -795,7 +859,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -811,7 +879,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -829,7 +901,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -847,7 +923,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -864,7 +944,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elems', '{one,two}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -881,7 +965,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -898,7 +986,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -915,7 +1007,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-09 19:28                         ` Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-09 19:28 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: Nathan Bossart <[email protected]>; [email protected]

On Mon, Mar 9, 2026 at 2:56 PM Sami Imseih <[email protected]> wrote:

> >> nathan
> >
> >
> > You're both right. Currently, we fetch extended stats one at a time,
> thus there's no _immediate_ need to do so.
> >
> > But "why wait until there is a crisis" is solid reasoning and for that I
> had already coded up the change.
> >I did have one small problem in that Michael Paquier had hoped that we
> could get the expr index (-1, -2, etc) on the expressions
> > as that was something that we at least briefly thought we'd need for
> importing expression statistics. However the existing query
> > uses a SELECT unnest(a), unnest(b) pattern in it, and WITH ORDINALITY is
> not allowed, and the workarounds I found seemed a
> > bit tortured. Hence, I decided to leave that out so as not to distract
> from the now accepted patch, and with that out of the way
> > I'll happily inflict that tortured SQL on y'all.
>
> Can we add the tableid  for now (see 0003) and follow-up with another
> thread with the sql changes to pg_dump?
>

Presently, I don't think we make any changes to pg_dump, unless Nathan
feels strongly that we should. If and when the need for oid-based fetching
of extended stats becomes necessary, we'll at least have a couple versions
where the catalog already had the oids handy.


>
> I also corrected v2-0001. The docs were still referencing "starlid"
> instead of "tableid"
>

I'll make that change in my forthcoming patch. Just rebasing some things.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-09 21:04                           ` Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-09 21:04 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 09, 2026 at 03:28:40PM -0400, Corey Huinker wrote:
> Presently, I don't think we make any changes to pg_dump, unless Nathan
> feels strongly that we should. If and when the need for oid-based fetching
> of extended stats becomes necessary, we'll at least have a couple versions
> where the catalog already had the oids handy.

That's fine with me.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-09 22:42                             ` Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-09 22:42 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 9, 2026 at 5:04 PM Nathan Bossart <[email protected]>
wrote:

> On Mon, Mar 09, 2026 at 03:28:40PM -0400, Corey Huinker wrote:
> > Presently, I don't think we make any changes to pg_dump, unless Nathan
> > feels strongly that we should. If and when the need for oid-based
> fetching
> > of extended stats becomes necessary, we'll at least have a couple
> versions
> > where the catalog already had the oids handy.
>
> That's fine with me.
>
> --
> nathan
>

I was sidetracked for a bit because the tests (which are accurate) seemed
strange in that pg_stats_ext_exprs would have 2 rows with NULL
inherited...and it took me a bit to realize that that actually makes sense
because the pg_stats_ext_exprs should have one row per expression whether
or not there are stats to match it. If that sounds like it could mess up
vacuumdb, it actually can't, because we base those tests based off
pg_stats_ext not pg_stats_ext_exprs - which does vary according to whether
stats exist for the object or not. I added a comment to the regression test
to that effect.

The new column expr_attnum gives the negative number that a given
expression has in pg_dependencites and pg_ndistinct - as you might imagine,
the number is determined by its order within the list of expressions.

If you want 0003 split into two (one for pg_stats_ext and one for
pg_stats_ext_exprs) I can do that, but they felt like a package deal to me.


Attachments:

  [text/x-patch] v4-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch (76.7K, 3-v4-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch)
  download | inline diff:
From 5e393d997411b78ceea01e054765ffed214a303f Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 24 Feb 2026 16:12:55 -0500
Subject: [PATCH v4 1/3] Add tableid and attnum columns to pg_stats.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

Additionally, there have been times when it would have been nice to have
attnum as well as attname available.
---
 src/backend/catalog/system_views.sql       |   8 +-
 src/test/regress/expected/rules.out        |   2 +
 src/test/regress/expected/stats_import.out | 288 ++++++++++++++-------
 src/test/regress/sql/stats_import.sql      | 144 +++++++++--
 doc/src/sgml/system-views.sgml             |  20 ++
 5 files changed, 339 insertions(+), 123 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ecb7c996e86..70846f1555d 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index deb6e2ad6a9..46be5c7ac90 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2524,7 +2524,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index c7adb783da2..8d66d4d9329 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -642,15 +642,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -669,15 +673,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -694,15 +702,19 @@ WARNING:  unrecognized argument name: "nope"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -720,15 +732,19 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -746,15 +762,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -774,15 +794,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -801,15 +825,19 @@ WARNING:  invalid input syntax for type integer: "four"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -826,15 +854,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -852,15 +884,19 @@ WARNING:  "histogram_bounds" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -876,15 +912,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -902,15 +942,19 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -927,15 +971,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -955,15 +1003,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -981,15 +1033,19 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1007,15 +1063,19 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1032,15 +1092,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1059,15 +1123,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1083,15 +1151,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1111,15 +1183,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1139,15 +1215,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1165,15 +1245,19 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1191,15 +1275,19 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1216,15 +1304,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1243,15 +1335,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0518bbf6f42..8fbec83b5e0 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -520,7 +520,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'avg_width', 5::integer,
     'n_distinct', 0.6::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -539,7 +543,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'inherited', false::boolean,
     'null_frac', 0.4::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -555,7 +563,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.2::real,
     'nope', 0.5::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -572,7 +584,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -589,7 +605,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_vals', '{1,2,3}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -607,7 +627,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -625,7 +649,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -642,7 +670,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -659,7 +691,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -675,7 +711,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,2,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -692,7 +732,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -709,7 +753,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -727,7 +775,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -744,7 +796,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -761,7 +817,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_empty_frac', 0.5::real
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -778,7 +838,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -795,7 +859,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -811,7 +879,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -829,7 +901,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -847,7 +923,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -864,7 +944,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elems', '{one,two}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -881,7 +965,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -898,7 +986,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -915,7 +1007,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..8214f3cd062 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>

base-commit: 6307b096e2599edfe238816118b3f365a73fd12a
-- 
2.53.0



  [text/x-patch] v4-0002-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 4-v4-0002-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From 47896c0539cf7e329e8d5d7da4b740c09aa6fab7 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v4 2/3] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 137161aa5e0..9cdacbc3467 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7224,6 +7224,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11118,8 +11119,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11153,8 +11155,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11167,14 +11179,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11182,16 +11215,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11250,8 +11297,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11270,22 +11327,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11293,7 +11358,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



  [text/x-patch] v4-0003-Add-tableid-statid-expr_attnum-columns-to-pg_stat.patch (27.3K, 5-v4-0003-Add-tableid-statid-expr_attnum-columns-to-pg_stat.patch)
  download | inline diff:
From 5a0be7b5f683da6e8636fcc6cba830227b16c358 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Mon, 9 Mar 2026 16:53:43 -0400
Subject: [PATCH v4 3/3] Add tableid, statid, expr_attnum columns to
 pg_stats_ext[_exprs].

This mimics the work done in the previous patch adding the columns
tableid and statid to both pg_stats_ext and pg_stats_ext_exprs. It also
adds expr_attnum to pg_stats_ext_exprs.

There is no present need for these additional columns, but if and when
pg_dump starts fetching extended statistics object stats in bulk, they
will be available.
---
 src/backend/catalog/system_views.sql       | 163 +++++++++++----------
 src/test/regress/expected/rules.out        | 119 ++++++++-------
 src/test/regress/expected/stats_import.out |  22 ++-
 src/test/regress/sql/stats_import.sql      |   8 +
 doc/src/sgml/system-views.sgml             |  52 +++++++
 5 files changed, 227 insertions(+), 137 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 70846f1555d..09274eac9c8 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -280,8 +280,10 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
            ( SELECT array_agg(a.attname ORDER BY a.attnum)
              FROM unnest(s.stxkeys) k
@@ -314,92 +316,97 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
-           stat.expr,
+           expr.expr,
+           0 - expr.ordinality AS expr_attnum,
            sd.stxdinherit AS inherited,
-           (stat.a).stanullfrac AS null_frac,
-           (stat.a).stawidth AS avg_width,
-           (stat.a).stadistinct AS n_distinct,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5
-           END) AS most_common_vals,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5
-           END) AS most_common_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5
-           END) AS histogram_bounds,
-           (CASE
-               WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1]
-           END) correlation,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5
-           END) AS most_common_elems,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5
-           END) AS most_common_elem_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5
-           END) AS elem_count_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stavalues5
-           END) AS range_length_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stanumbers5[1]
-           END) AS range_empty_frac,
-           (CASE
-               WHEN (stat.a).stakind1 = 7 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 7 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 7 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 7 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 7 THEN (stat.a).stavalues5
-               END) AS range_bounds_histogram
+           a.stanullfrac AS null_frac,
+           a.stawidth AS avg_width,
+           a.stadistinct AS n_distinct,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stavalues1
+               WHEN a.stakind2 = 1 THEN a.stavalues2
+               WHEN a.stakind3 = 1 THEN a.stavalues3
+               WHEN a.stakind4 = 1 THEN a.stavalues4
+               WHEN a.stakind5 = 1 THEN a.stavalues5
+           END AS most_common_vals,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stanumbers1
+               WHEN a.stakind2 = 1 THEN a.stanumbers2
+               WHEN a.stakind3 = 1 THEN a.stanumbers3
+               WHEN a.stakind4 = 1 THEN a.stanumbers4
+               WHEN a.stakind5 = 1 THEN a.stanumbers5
+           END AS most_common_freqs,
+           CASE
+               WHEN a.stakind1 = 2 THEN a.stavalues1
+               WHEN a.stakind2 = 2 THEN a.stavalues2
+               WHEN a.stakind3 = 2 THEN a.stavalues3
+               WHEN a.stakind4 = 2 THEN a.stavalues4
+               WHEN a.stakind5 = 2 THEN a.stavalues5
+           END AS histogram_bounds,
+           CASE
+               WHEN a.stakind1 = 3 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 3 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 3 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 3 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 3 THEN a.stanumbers5[1]
+           END AS correlation,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stavalues1
+               WHEN a.stakind2 = 4 THEN a.stavalues2
+               WHEN a.stakind3 = 4 THEN a.stavalues3
+               WHEN a.stakind4 = 4 THEN a.stavalues4
+               WHEN a.stakind5 = 4 THEN a.stavalues5
+           END aS most_common_elems,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stanumbers1
+               WHEN a.stakind2 = 4 THEN a.stanumbers2
+               WHEN a.stakind3 = 4 THEN a.stanumbers3
+               WHEN a.stakind4 = 4 THEN a.stanumbers4
+               WHEN a.stakind5 = 4 THEN a.stanumbers5
+           END aS most_common_elem_freqs,
+           CASE
+               WHEN a.stakind1 = 5 THEN a.stanumbers1
+               WHEN a.stakind2 = 5 THEN a.stanumbers2
+               WHEN a.stakind3 = 5 THEN a.stanumbers3
+               WHEN a.stakind4 = 5 THEN a.stanumbers4
+               WHEN a.stakind5 = 5 THEN a.stanumbers5
+           END aS elem_count_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stavalues1
+               WHEN a.stakind2 = 6 THEN a.stavalues2
+               WHEN a.stakind3 = 6 THEN a.stavalues3
+               WHEN a.stakind4 = 6 THEN a.stavalues4
+               WHEN a.stakind5 = 6 THEN a.stavalues5
+           END aS range_length_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 6 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 6 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 6 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 6 THEN a.stanumbers5[1]
+           END aS range_empty_frac,
+           CASE
+               WHEN a.stakind1 = 7 THEN a.stavalues1
+               WHEN a.stakind2 = 7 THEN a.stavalues2
+               WHEN a.stakind3 = 7 THEN a.stavalues3
+               WHEN a.stakind4 = 7 THEN a.stavalues4
+               WHEN a.stakind5 = 7 THEN a.stavalues5
+           END AS range_bounds_histogram
     FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid)
          LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid)
          LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace)
          LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace)
-         JOIN LATERAL (
-             SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-                    unnest(sd.stxdexpr)::pg_statistic AS a
-         ) stat ON (stat.expr IS NOT NULL)
+         JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid))
+              WITH ORDINALITY AS expr(expr, ordinality)
+                ON s.stxexprs IS NOT NULL
+         LEFT JOIN LATERAL unnest(sd.stxdexpr)
+              WITH ORDINALITY AS a
+                ON a.ordinality = expr.ordinality
     WHERE pg_has_role(c.relowner, 'USAGE')
     AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
 
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 46be5c7ac90..eab38a43609 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2618,8 +2618,10 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
     ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
            FROM (unnest(s.stxkeys) k(k)
@@ -2646,101 +2648,104 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
-    stat.expr,
+    expr.expr,
+    (0 - expr.ordinality) AS expr_attnum,
     sd.stxdinherit AS inherited,
-    (stat.a).stanullfrac AS null_frac,
-    (stat.a).stawidth AS avg_width,
-    (stat.a).stadistinct AS n_distinct,
+    a.stanullfrac AS null_frac,
+    a.stawidth AS avg_width,
+    a.stadistinct AS n_distinct,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 1) THEN a.stavalues1
+            WHEN (a.stakind2 = 1) THEN a.stavalues2
+            WHEN (a.stakind3 = 1) THEN a.stavalues3
+            WHEN (a.stakind4 = 1) THEN a.stavalues4
+            WHEN (a.stakind5 = 1) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_vals,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 1) THEN a.stanumbers1
+            WHEN (a.stakind2 = 1) THEN a.stanumbers2
+            WHEN (a.stakind3 = 1) THEN a.stanumbers3
+            WHEN (a.stakind4 = 1) THEN a.stanumbers4
+            WHEN (a.stakind5 = 1) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 2) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 2) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 2) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 2) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 2) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 2) THEN a.stavalues1
+            WHEN (a.stakind2 = 2) THEN a.stavalues2
+            WHEN (a.stakind3 = 2) THEN a.stavalues3
+            WHEN (a.stakind4 = 2) THEN a.stavalues4
+            WHEN (a.stakind5 = 2) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS histogram_bounds,
         CASE
-            WHEN ((stat.a).stakind1 = 3) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 3) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 3) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 3) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 3) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 3) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 3) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 3) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 3) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 3) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS correlation,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 4) THEN a.stavalues1
+            WHEN (a.stakind2 = 4) THEN a.stavalues2
+            WHEN (a.stakind3 = 4) THEN a.stavalues3
+            WHEN (a.stakind4 = 4) THEN a.stavalues4
+            WHEN (a.stakind5 = 4) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_elems,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 4) THEN a.stanumbers1
+            WHEN (a.stakind2 = 4) THEN a.stanumbers2
+            WHEN (a.stakind3 = 4) THEN a.stanumbers3
+            WHEN (a.stakind4 = 4) THEN a.stanumbers4
+            WHEN (a.stakind5 = 4) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_elem_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 5) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 5) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 5) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 5) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 5) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 5) THEN a.stanumbers1
+            WHEN (a.stakind2 = 5) THEN a.stanumbers2
+            WHEN (a.stakind3 = 5) THEN a.stanumbers3
+            WHEN (a.stakind4 = 5) THEN a.stanumbers4
+            WHEN (a.stakind5 = 5) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS elem_count_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 6) THEN a.stavalues1
+            WHEN (a.stakind2 = 6) THEN a.stavalues2
+            WHEN (a.stakind3 = 6) THEN a.stavalues3
+            WHEN (a.stakind4 = 6) THEN a.stavalues4
+            WHEN (a.stakind5 = 6) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_length_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 6) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 6) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 6) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 6) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 6) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS range_empty_frac,
         CASE
-            WHEN ((stat.a).stakind1 = 7) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 7) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 7) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 7) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 7) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 7) THEN a.stavalues1
+            WHEN (a.stakind2 = 7) THEN a.stavalues2
+            WHEN (a.stakind3 = 7) THEN a.stavalues3
+            WHEN (a.stakind4 = 7) THEN a.stavalues4
+            WHEN (a.stakind5 = 7) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_bounds_histogram
-   FROM (((((pg_statistic_ext s
+   FROM ((((((pg_statistic_ext s
      JOIN pg_class c ON ((c.oid = s.stxrelid)))
      LEFT JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid)))
      LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace)))
      LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace)))
-     JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-            unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL)))
+     JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid)) WITH ORDINALITY expr(expr, ordinality) ON ((s.stxexprs IS NOT NULL)))
+     LEFT JOIN LATERAL unnest(sd.stxdexpr) WITH ORDINALITY a(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5, ordinality) ON ((a.ordinality = expr.ordinality)))
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_tables| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 8d66d4d9329..68e1b75f5e2 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -66,7 +66,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    17
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -107,7 +107,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    23
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
@@ -1684,6 +1684,8 @@ SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
 -------+-----------
 (0 rows)
 
+-- A NULL value on inherited makes sense here because the rows are expanded
+-- from pg_statistic_ext but the values come from the empty pg_statistic_ext_data.
 SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
   WHERE e.statistics_schemaname = 'stats_import' AND
   e.statistics_name = 'test_stat' GROUP BY e.inherited;
@@ -1701,6 +1703,14 @@ SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
      1 | t
 (1 row)
 
+SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
+  WHERE e.statistics_schemaname = 'stats_import' AND
+  e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
+ count | inherited 
+-------+-----------
+     1 | t
+(1 row)
+
 SELECT pg_catalog.pg_clear_extended_stats(
   schemaname => 'stats_import',
   relname => 'part_parent',
@@ -1719,6 +1729,14 @@ SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
 -------+-----------
 (0 rows)
 
+SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
+  WHERE e.statistics_schemaname = 'stats_import' AND
+  e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
+ count | inherited 
+-------+-----------
+     1 | 
+(1 row)
+
 -- Check that MAINTAIN is required when clearing statistics.
 CREATE ROLE regress_test_extstat_clear;
 GRANT ALL ON SCHEMA stats_import TO regress_test_extstat_clear;
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 8fbec83b5e0..081ff936fd8 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -1268,6 +1268,8 @@ COMMIT;
 SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
   WHERE e.statistics_schemaname = 'stats_import' AND
   e.statistics_name = 'test_stat' GROUP BY e.inherited;
+-- A NULL value on inherited makes sense here because the rows are expanded
+-- from pg_statistic_ext but the values come from the empty pg_statistic_ext_data.
 SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
   WHERE e.statistics_schemaname = 'stats_import' AND
   e.statistics_name = 'test_stat' GROUP BY e.inherited;
@@ -1275,6 +1277,9 @@ SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
 SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
   WHERE e.statistics_schemaname = 'stats_import' AND
   e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
+SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
+  WHERE e.statistics_schemaname = 'stats_import' AND
+  e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
 SELECT pg_catalog.pg_clear_extended_stats(
   schemaname => 'stats_import',
   relname => 'part_parent',
@@ -1284,6 +1289,9 @@ SELECT pg_catalog.pg_clear_extended_stats(
 SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e
   WHERE e.statistics_schemaname = 'stats_import' AND
   e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
+SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e
+  WHERE e.statistics_schemaname = 'stats_import' AND
+  e.statistics_name = 'part_parent_stat' GROUP BY e.inherited;
 
 -- Check that MAINTAIN is required when clearing statistics.
 CREATE ROLE regress_test_extstat_clear;
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 8214f3cd062..25a013abbf8 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4686,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4706,6 +4716,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4897,6 +4917,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4917,6 +4947,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4936,6 +4976,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-10 16:37                               ` Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-10 16:37 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 09, 2026 at 06:42:46PM -0400, Corey Huinker wrote:
> If you want 0003 split into two (one for pg_stats_ext and one for
> pg_stats_ext_exprs) I can do that, but they felt like a package deal to me.

Sorry to throw a curveball here, but I think the best way to structure this
patch set is as follows:

* 0001: Just the test changes (e.g., replacing * with column lists).  By
doing that first, the actual functionality changes in 0002 will be easier
to see.

* 0002: Adding columns to the all the views (this one will do a catalog
bump).  If we need to make a couple of test adjustments to verify the OIDs
or attribute IDs, that's fine, but those can be pretty minimal.

* 0003: Associated pg_dump changes.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-10 16:42                                 ` Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-10 16:42 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Tue, Mar 10, 2026 at 12:37 PM Nathan Bossart <[email protected]>
wrote:

> On Mon, Mar 09, 2026 at 06:42:46PM -0400, Corey Huinker wrote:
> > If you want 0003 split into two (one for pg_stats_ext and one for
> > pg_stats_ext_exprs) I can do that, but they felt like a package deal to
> me.
>
> Sorry to throw a curveball here, but I think the best way to structure this
> patch set is as follows:
>
> * 0001: Just the test changes (e.g., replacing * with column lists).  By
> doing that first, the actual functionality changes in 0002 will be easier
> to see.
>

Makes sense.


>
> * 0002: Adding columns to the all the views (this one will do a catalog
> bump).  If we need to make a couple of test adjustments to verify the OIDs
> or attribute IDs, that's fine, but those can be pretty minimal.
>

So all three views in one go. +1


>
> * 0003: Associated pg_dump changes.
>

On it.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-12 20:16                                   ` Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-12 20:16 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Tue, Mar 10, 2026 at 12:42 PM Corey Huinker <[email protected]>
wrote:

>
>
> On Tue, Mar 10, 2026 at 12:37 PM Nathan Bossart <[email protected]>
> wrote:
>
>> On Mon, Mar 09, 2026 at 06:42:46PM -0400, Corey Huinker wrote:
>> > If you want 0003 split into two (one for pg_stats_ext and one for
>> > pg_stats_ext_exprs) I can do that, but they felt like a package deal to
>> me.
>>
>> Sorry to throw a curveball here, but I think the best way to structure
>> this
>> patch set is as follows:
>>
>> * 0001: Just the test changes (e.g., replacing * with column lists).  By
>> doing that first, the actual functionality changes in 0002 will be easier
>> to see.
>>
>
> Makes sense.
>
>
>>
>> * 0002: Adding columns to the all the views (this one will do a catalog
>> bump).  If we need to make a couple of test adjustments to verify the OIDs
>> or attribute IDs, that's fine, but those can be pretty minimal.
>>
>
> So all three views in one go. +1
>
>
>>
>> * 0003: Associated pg_dump changes.
>>
>
> On it.
>

Apologies for the delay. I thought I had posted this. I rebased it
against a630ac5c2016e52 (current HEAD).


Attachments:

  [text/x-patch] v5-0001-Add-test-view-pg_stats_check.patch (13.9K, 3-v5-0001-Add-test-view-pg_stats_check.patch)
  download | inline diff:
From 68782c75ac3de636511274d4699355533d7bfa20 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:25:29 -0400
Subject: [PATCH v5 1/3] Add test view pg_stats_check.

Add the view stats_import.pg_stats_check, allowing the columns selected
to be changed across all tests using the view by just changing the the
view definition.

This will allow for us to seamlessly add new columns that we do want to
see in the test results (attnum) while also allowing us to screen out
new columns that cannot be in the test results (tableid).
---
 src/test/regress/expected/stats_import.out | 64 +++++++++++++---------
 src/test/regress/sql/stats_import.sql      | 60 ++++++++++++--------
 2 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index c7adb783da2..12d70bc4723 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -1,5 +1,16 @@
 CREATE SCHEMA stats_import;
 --
+-- Set up convenience views
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+--
 -- Setup functions for set-difference convenience functions
 --
 -- Test to detect any new columns added to pg_statistic.  If any columns
@@ -643,7 +654,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -670,7 +681,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -695,7 +706,7 @@ WARNING:  unrecognized argument name: "nope"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -721,7 +732,7 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -747,7 +758,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -775,7 +786,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -802,7 +813,7 @@ WARNING:  invalid input syntax for type integer: "four"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -827,7 +838,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -853,7 +864,7 @@ WARNING:  "histogram_bounds" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -877,7 +888,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -903,7 +914,7 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -928,7 +939,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -956,7 +967,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -982,7 +993,7 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1008,7 +1019,7 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1033,7 +1044,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1060,7 +1071,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1084,7 +1095,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1112,7 +1123,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1140,7 +1151,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1166,7 +1177,7 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1192,7 +1203,7 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1217,7 +1228,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1244,7 +1255,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -3362,8 +3373,9 @@ SELECT COUNT(*) FROM stats_import.test_range_expr_null
 (1 row)
 
 DROP SCHEMA stats_import CASCADE;
-NOTICE:  drop cascades to 18 other objects
-DETAIL:  drop cascades to view stats_import.pg_statistic_flat_t
+NOTICE:  drop cascades to 19 other objects
+DETAIL:  drop cascades to view stats_import.pg_stats_check
+drop cascades to view stats_import.pg_statistic_flat_t
 drop cascades to function stats_import.pg_statistic_flat(text)
 drop cascades to function stats_import.pg_statistic_get_difference(text,text)
 drop cascades to view stats_import.pg_stats_ext_flat_t
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0518bbf6f42..fe54eb46f43 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -1,5 +1,17 @@
 CREATE SCHEMA stats_import;
 
+--
+-- Set up convenience views
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+
 --
 -- Setup functions for set-difference convenience functions
 --
@@ -521,7 +533,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'n_distinct', 0.6::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -540,7 +552,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.4::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -556,7 +568,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'nope', 0.5::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -573,7 +585,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -590,7 +602,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -608,7 +620,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -626,7 +638,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -643,7 +655,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -660,7 +672,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -676,7 +688,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -693,7 +705,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -710,7 +722,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -728,7 +740,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -745,7 +757,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -762,7 +774,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -779,7 +791,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -796,7 +808,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -812,7 +824,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -830,7 +842,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -848,7 +860,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -865,7 +877,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -882,7 +894,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -899,7 +911,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -916,7 +928,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false

base-commit: a630ac5c2016e523a1c29df117b7c1a563a7f6f8
-- 
2.53.0



  [text/x-patch] v5-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch (77.9K, 4-v5-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch)
  download | inline diff:
From 2bc82e5b176a0278ffab25dfb48aa20d117049c5 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:51:00 -0400
Subject: [PATCH v5 2/3] Add tableid, statid, attnum, expr_attnum columns to
 pg_stats views.

Add tableid and attnum columns to pg_stats.  Add tableid, statid columns
to pg_stats_ext.  Add tableid, statid, expr_attnum columns to
pg_stats_ext_exprs.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

This patch makes simlilar changes to pg_stats_ext and
pg_stats_ext_exprs, but there is no immediate need to utlize those
changes in pg_dump.
---
 src/backend/catalog/system_views.sql       | 171 +++++++++++----------
 src/test/regress/expected/rules.out        | 121 ++++++++-------
 src/test/regress/expected/stats_import.out | 150 +++++++++---------
 src/test/regress/sql/stats_import.sql      |   2 +-
 doc/src/sgml/system-views.sgml             |  72 +++++++++
 5 files changed, 302 insertions(+), 214 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 339c016e510..1367bcbad4b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
@@ -278,8 +280,10 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
            ( SELECT array_agg(a.attname ORDER BY a.attnum)
              FROM unnest(s.stxkeys) k
@@ -312,92 +316,97 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
-           stat.expr,
+           expr.expr,
+           0 - expr.ordinality AS expr_attnum,
            sd.stxdinherit AS inherited,
-           (stat.a).stanullfrac AS null_frac,
-           (stat.a).stawidth AS avg_width,
-           (stat.a).stadistinct AS n_distinct,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5
-           END) AS most_common_vals,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5
-           END) AS most_common_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5
-           END) AS histogram_bounds,
-           (CASE
-               WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1]
-           END) correlation,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5
-           END) AS most_common_elems,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5
-           END) AS most_common_elem_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5
-           END) AS elem_count_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stavalues5
-           END) AS range_length_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stanumbers5[1]
-           END) AS range_empty_frac,
-           (CASE
-               WHEN (stat.a).stakind1 = 7 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 7 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 7 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 7 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 7 THEN (stat.a).stavalues5
-               END) AS range_bounds_histogram
+           a.stanullfrac AS null_frac,
+           a.stawidth AS avg_width,
+           a.stadistinct AS n_distinct,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stavalues1
+               WHEN a.stakind2 = 1 THEN a.stavalues2
+               WHEN a.stakind3 = 1 THEN a.stavalues3
+               WHEN a.stakind4 = 1 THEN a.stavalues4
+               WHEN a.stakind5 = 1 THEN a.stavalues5
+           END AS most_common_vals,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stanumbers1
+               WHEN a.stakind2 = 1 THEN a.stanumbers2
+               WHEN a.stakind3 = 1 THEN a.stanumbers3
+               WHEN a.stakind4 = 1 THEN a.stanumbers4
+               WHEN a.stakind5 = 1 THEN a.stanumbers5
+           END AS most_common_freqs,
+           CASE
+               WHEN a.stakind1 = 2 THEN a.stavalues1
+               WHEN a.stakind2 = 2 THEN a.stavalues2
+               WHEN a.stakind3 = 2 THEN a.stavalues3
+               WHEN a.stakind4 = 2 THEN a.stavalues4
+               WHEN a.stakind5 = 2 THEN a.stavalues5
+           END AS histogram_bounds,
+           CASE
+               WHEN a.stakind1 = 3 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 3 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 3 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 3 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 3 THEN a.stanumbers5[1]
+           END AS correlation,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stavalues1
+               WHEN a.stakind2 = 4 THEN a.stavalues2
+               WHEN a.stakind3 = 4 THEN a.stavalues3
+               WHEN a.stakind4 = 4 THEN a.stavalues4
+               WHEN a.stakind5 = 4 THEN a.stavalues5
+           END aS most_common_elems,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stanumbers1
+               WHEN a.stakind2 = 4 THEN a.stanumbers2
+               WHEN a.stakind3 = 4 THEN a.stanumbers3
+               WHEN a.stakind4 = 4 THEN a.stanumbers4
+               WHEN a.stakind5 = 4 THEN a.stanumbers5
+           END aS most_common_elem_freqs,
+           CASE
+               WHEN a.stakind1 = 5 THEN a.stanumbers1
+               WHEN a.stakind2 = 5 THEN a.stanumbers2
+               WHEN a.stakind3 = 5 THEN a.stanumbers3
+               WHEN a.stakind4 = 5 THEN a.stanumbers4
+               WHEN a.stakind5 = 5 THEN a.stanumbers5
+           END aS elem_count_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stavalues1
+               WHEN a.stakind2 = 6 THEN a.stavalues2
+               WHEN a.stakind3 = 6 THEN a.stavalues3
+               WHEN a.stakind4 = 6 THEN a.stavalues4
+               WHEN a.stakind5 = 6 THEN a.stavalues5
+           END aS range_length_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 6 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 6 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 6 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 6 THEN a.stanumbers5[1]
+           END aS range_empty_frac,
+           CASE
+               WHEN a.stakind1 = 7 THEN a.stavalues1
+               WHEN a.stakind2 = 7 THEN a.stavalues2
+               WHEN a.stakind3 = 7 THEN a.stavalues3
+               WHEN a.stakind4 = 7 THEN a.stavalues4
+               WHEN a.stakind5 = 7 THEN a.stavalues5
+           END AS range_bounds_histogram
     FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid)
          LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid)
          LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace)
          LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace)
-         JOIN LATERAL (
-             SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-                    unnest(sd.stxdexpr)::pg_statistic AS a
-         ) stat ON (stat.expr IS NOT NULL)
+         JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid))
+              WITH ORDINALITY AS expr(expr, ordinality)
+                ON s.stxexprs IS NOT NULL
+         LEFT JOIN LATERAL unnest(sd.stxdexpr)
+              WITH ORDINALITY AS a
+                ON a.ordinality = expr.ordinality
     WHERE pg_has_role(c.relowner, 'USAGE')
     AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
 
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index f373ad704b6..7e1af2edb32 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2542,7 +2542,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
@@ -2634,8 +2636,10 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
     ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
            FROM (unnest(s.stxkeys) k(k)
@@ -2662,101 +2666,104 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
-    stat.expr,
+    expr.expr,
+    (0 - expr.ordinality) AS expr_attnum,
     sd.stxdinherit AS inherited,
-    (stat.a).stanullfrac AS null_frac,
-    (stat.a).stawidth AS avg_width,
-    (stat.a).stadistinct AS n_distinct,
+    a.stanullfrac AS null_frac,
+    a.stawidth AS avg_width,
+    a.stadistinct AS n_distinct,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 1) THEN a.stavalues1
+            WHEN (a.stakind2 = 1) THEN a.stavalues2
+            WHEN (a.stakind3 = 1) THEN a.stavalues3
+            WHEN (a.stakind4 = 1) THEN a.stavalues4
+            WHEN (a.stakind5 = 1) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_vals,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 1) THEN a.stanumbers1
+            WHEN (a.stakind2 = 1) THEN a.stanumbers2
+            WHEN (a.stakind3 = 1) THEN a.stanumbers3
+            WHEN (a.stakind4 = 1) THEN a.stanumbers4
+            WHEN (a.stakind5 = 1) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 2) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 2) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 2) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 2) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 2) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 2) THEN a.stavalues1
+            WHEN (a.stakind2 = 2) THEN a.stavalues2
+            WHEN (a.stakind3 = 2) THEN a.stavalues3
+            WHEN (a.stakind4 = 2) THEN a.stavalues4
+            WHEN (a.stakind5 = 2) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS histogram_bounds,
         CASE
-            WHEN ((stat.a).stakind1 = 3) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 3) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 3) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 3) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 3) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 3) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 3) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 3) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 3) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 3) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS correlation,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 4) THEN a.stavalues1
+            WHEN (a.stakind2 = 4) THEN a.stavalues2
+            WHEN (a.stakind3 = 4) THEN a.stavalues3
+            WHEN (a.stakind4 = 4) THEN a.stavalues4
+            WHEN (a.stakind5 = 4) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_elems,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 4) THEN a.stanumbers1
+            WHEN (a.stakind2 = 4) THEN a.stanumbers2
+            WHEN (a.stakind3 = 4) THEN a.stanumbers3
+            WHEN (a.stakind4 = 4) THEN a.stanumbers4
+            WHEN (a.stakind5 = 4) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_elem_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 5) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 5) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 5) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 5) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 5) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 5) THEN a.stanumbers1
+            WHEN (a.stakind2 = 5) THEN a.stanumbers2
+            WHEN (a.stakind3 = 5) THEN a.stanumbers3
+            WHEN (a.stakind4 = 5) THEN a.stanumbers4
+            WHEN (a.stakind5 = 5) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS elem_count_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 6) THEN a.stavalues1
+            WHEN (a.stakind2 = 6) THEN a.stavalues2
+            WHEN (a.stakind3 = 6) THEN a.stavalues3
+            WHEN (a.stakind4 = 6) THEN a.stavalues4
+            WHEN (a.stakind5 = 6) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_length_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 6) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 6) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 6) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 6) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 6) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS range_empty_frac,
         CASE
-            WHEN ((stat.a).stakind1 = 7) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 7) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 7) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 7) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 7) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 7) THEN a.stavalues1
+            WHEN (a.stakind2 = 7) THEN a.stavalues2
+            WHEN (a.stakind3 = 7) THEN a.stavalues3
+            WHEN (a.stakind4 = 7) THEN a.stavalues4
+            WHEN (a.stakind5 = 7) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_bounds_histogram
-   FROM (((((pg_statistic_ext s
+   FROM ((((((pg_statistic_ext s
      JOIN pg_class c ON ((c.oid = s.stxrelid)))
      LEFT JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid)))
      LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace)))
      LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace)))
-     JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-            unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL)))
+     JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid)) WITH ORDINALITY expr(expr, ordinality) ON ((s.stxexprs IS NOT NULL)))
+     LEFT JOIN LATERAL unnest(sd.stxdexpr) WITH ORDINALITY a(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5, ordinality) ON ((a.ordinality = expr.ordinality)))
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_tables| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 12d70bc4723..4f0e846b005 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -3,7 +3,7 @@ CREATE SCHEMA stats_import;
 -- Set up convenience views
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
@@ -77,7 +77,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    17
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -118,7 +118,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    23
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
@@ -659,9 +659,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -686,9 +686,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -711,9 +711,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -737,9 +737,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -763,9 +763,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -791,9 +791,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -818,9 +818,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -843,9 +843,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -869,9 +869,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -893,9 +893,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -919,9 +919,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -944,9 +944,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -972,9 +972,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -998,9 +998,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1024,9 +1024,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1049,9 +1049,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1076,9 +1076,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1100,9 +1100,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1128,9 +1128,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1156,9 +1156,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1182,9 +1182,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1208,9 +1208,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1233,9 +1233,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1260,9 +1260,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index fe54eb46f43..8a8ec9a6c64 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -4,7 +4,7 @@ CREATE SCHEMA stats_import;
 -- Set up convenience views
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..25a013abbf8 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
@@ -4666,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4686,6 +4716,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4877,6 +4917,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4897,6 +4947,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4916,6 +4976,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
-- 
2.53.0



  [text/x-patch] v5-0003-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 5-v5-0003-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From b82f256884c8237367ab22da72adeadbddc37031 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v5 3/3] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 137161aa5e0..9cdacbc3467 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7224,6 +7224,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11118,8 +11119,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11153,8 +11155,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11167,14 +11179,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11182,16 +11215,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11250,8 +11297,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11270,22 +11327,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11293,7 +11358,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-12 21:08                                     ` Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-12 21:08 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Nathan Bossart <[email protected]>; [email protected]

> Apologies for the delay. I thought I had posted this. I rebased it against a630ac5c2016e52 (current HEAD).

Thanks!

just a few things.


v5-0001:

+-- Set up convenience views
+--
+CREATE VIEW stats_import.pg_stats_check AS

It will be good to add more commentary here to the next person adding
a test, and mention
that only stable values should be included in this view. what do you think?

v5-0002:

This is the wrong link. It should be catalog-pg-attribute and not
catalog-pg-class

+       (references <link
linkend="catalog-pg-class"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)

and a few occurrences where the link to pg_statistic_ext is pointing
to catalog-pg-class:

+       (references <link
linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)


v5-0003:

LGTM


--
Sami Imseih
Amazon Web Services (AWS)





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-12 23:54                                       ` Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-12 23:54 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: Nathan Bossart <[email protected]>; [email protected]

> It will be good to add more commentary here to the next person adding
> a test, and mention
> that only stable values should be included in this view. what do you think?
>

I added a comment, but I don't think a test writer would be confused for
long if they did break that rule.


>
>
> +       (references <link
>
> linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
>

Fixed catalog-pg-attribute and catalog-pg-statistic-ext


Attachments:

  [text/x-patch] v6-0001-Add-test-view-pg_stats_check.patch (13.9K, 3-v6-0001-Add-test-view-pg_stats_check.patch)
  download | inline diff:
From a03ce9ded18ee7ffc5c48f937d314aba375bbe8c Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:25:29 -0400
Subject: [PATCH v6 1/3] Add test view pg_stats_check.

Add the view stats_import.pg_stats_check, allowing the columns selected
to be changed across all tests using the view by just changing the the
view definition.

This will allow for us to seamlessly add new columns that we do want to
see in the test results (attnum) while also allowing us to screen out
new columns that cannot be in the test results (tableid).
---
 src/test/regress/expected/stats_import.out | 64 +++++++++++++---------
 src/test/regress/sql/stats_import.sql      | 60 ++++++++++++--------
 2 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index c7adb783da2..12d70bc4723 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -1,5 +1,16 @@
 CREATE SCHEMA stats_import;
 --
+-- Set up convenience views
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+--
 -- Setup functions for set-difference convenience functions
 --
 -- Test to detect any new columns added to pg_statistic.  If any columns
@@ -643,7 +654,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -670,7 +681,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -695,7 +706,7 @@ WARNING:  unrecognized argument name: "nope"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -721,7 +732,7 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -747,7 +758,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -775,7 +786,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -802,7 +813,7 @@ WARNING:  invalid input syntax for type integer: "four"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -827,7 +838,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -853,7 +864,7 @@ WARNING:  "histogram_bounds" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -877,7 +888,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -903,7 +914,7 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -928,7 +939,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -956,7 +967,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -982,7 +993,7 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1008,7 +1019,7 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1033,7 +1044,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1060,7 +1071,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1084,7 +1095,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1112,7 +1123,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1140,7 +1151,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1166,7 +1177,7 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1192,7 +1203,7 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1217,7 +1228,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1244,7 +1255,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -3362,8 +3373,9 @@ SELECT COUNT(*) FROM stats_import.test_range_expr_null
 (1 row)
 
 DROP SCHEMA stats_import CASCADE;
-NOTICE:  drop cascades to 18 other objects
-DETAIL:  drop cascades to view stats_import.pg_statistic_flat_t
+NOTICE:  drop cascades to 19 other objects
+DETAIL:  drop cascades to view stats_import.pg_stats_check
+drop cascades to view stats_import.pg_statistic_flat_t
 drop cascades to function stats_import.pg_statistic_flat(text)
 drop cascades to function stats_import.pg_statistic_get_difference(text,text)
 drop cascades to view stats_import.pg_stats_ext_flat_t
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0518bbf6f42..fe54eb46f43 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -1,5 +1,17 @@
 CREATE SCHEMA stats_import;
 
+--
+-- Set up convenience views
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+
 --
 -- Setup functions for set-difference convenience functions
 --
@@ -521,7 +533,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'n_distinct', 0.6::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -540,7 +552,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.4::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -556,7 +568,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'nope', 0.5::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -573,7 +585,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -590,7 +602,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -608,7 +620,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -626,7 +638,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -643,7 +655,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -660,7 +672,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -676,7 +688,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -693,7 +705,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -710,7 +722,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -728,7 +740,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -745,7 +757,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -762,7 +774,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -779,7 +791,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -796,7 +808,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -812,7 +824,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -830,7 +842,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -848,7 +860,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -865,7 +877,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -882,7 +894,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -899,7 +911,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -916,7 +928,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false

base-commit: a0b6ef29a51818a4073a5f390ed10ef6453d5c11
-- 
2.53.0



  [text/x-patch] v6-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch (78.0K, 4-v6-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch)
  download | inline diff:
From bee766997a938d115bcf97b0ffb0b181f9863b75 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:51:00 -0400
Subject: [PATCH v6 2/3] Add tableid, statid, attnum, expr_attnum columns to
 pg_stats views.

Add tableid and attnum columns to pg_stats.  Add tableid, statid columns
to pg_stats_ext.  Add tableid, statid, expr_attnum columns to
pg_stats_ext_exprs.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

This patch makes simlilar changes to pg_stats_ext and
pg_stats_ext_exprs, but there is no immediate need to utlize those
changes in pg_dump.
---
 src/backend/catalog/system_views.sql       | 171 +++++++++++----------
 src/test/regress/expected/rules.out        | 121 ++++++++-------
 src/test/regress/expected/stats_import.out | 150 +++++++++---------
 src/test/regress/sql/stats_import.sql      |   5 +-
 doc/src/sgml/system-views.sgml             |  72 +++++++++
 5 files changed, 304 insertions(+), 215 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 339c016e510..1367bcbad4b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
@@ -278,8 +280,10 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
            ( SELECT array_agg(a.attname ORDER BY a.attnum)
              FROM unnest(s.stxkeys) k
@@ -312,92 +316,97 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
-           stat.expr,
+           expr.expr,
+           0 - expr.ordinality AS expr_attnum,
            sd.stxdinherit AS inherited,
-           (stat.a).stanullfrac AS null_frac,
-           (stat.a).stawidth AS avg_width,
-           (stat.a).stadistinct AS n_distinct,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5
-           END) AS most_common_vals,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5
-           END) AS most_common_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5
-           END) AS histogram_bounds,
-           (CASE
-               WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1]
-           END) correlation,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5
-           END) AS most_common_elems,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5
-           END) AS most_common_elem_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5
-           END) AS elem_count_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stavalues5
-           END) AS range_length_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stanumbers5[1]
-           END) AS range_empty_frac,
-           (CASE
-               WHEN (stat.a).stakind1 = 7 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 7 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 7 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 7 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 7 THEN (stat.a).stavalues5
-               END) AS range_bounds_histogram
+           a.stanullfrac AS null_frac,
+           a.stawidth AS avg_width,
+           a.stadistinct AS n_distinct,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stavalues1
+               WHEN a.stakind2 = 1 THEN a.stavalues2
+               WHEN a.stakind3 = 1 THEN a.stavalues3
+               WHEN a.stakind4 = 1 THEN a.stavalues4
+               WHEN a.stakind5 = 1 THEN a.stavalues5
+           END AS most_common_vals,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stanumbers1
+               WHEN a.stakind2 = 1 THEN a.stanumbers2
+               WHEN a.stakind3 = 1 THEN a.stanumbers3
+               WHEN a.stakind4 = 1 THEN a.stanumbers4
+               WHEN a.stakind5 = 1 THEN a.stanumbers5
+           END AS most_common_freqs,
+           CASE
+               WHEN a.stakind1 = 2 THEN a.stavalues1
+               WHEN a.stakind2 = 2 THEN a.stavalues2
+               WHEN a.stakind3 = 2 THEN a.stavalues3
+               WHEN a.stakind4 = 2 THEN a.stavalues4
+               WHEN a.stakind5 = 2 THEN a.stavalues5
+           END AS histogram_bounds,
+           CASE
+               WHEN a.stakind1 = 3 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 3 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 3 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 3 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 3 THEN a.stanumbers5[1]
+           END AS correlation,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stavalues1
+               WHEN a.stakind2 = 4 THEN a.stavalues2
+               WHEN a.stakind3 = 4 THEN a.stavalues3
+               WHEN a.stakind4 = 4 THEN a.stavalues4
+               WHEN a.stakind5 = 4 THEN a.stavalues5
+           END aS most_common_elems,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stanumbers1
+               WHEN a.stakind2 = 4 THEN a.stanumbers2
+               WHEN a.stakind3 = 4 THEN a.stanumbers3
+               WHEN a.stakind4 = 4 THEN a.stanumbers4
+               WHEN a.stakind5 = 4 THEN a.stanumbers5
+           END aS most_common_elem_freqs,
+           CASE
+               WHEN a.stakind1 = 5 THEN a.stanumbers1
+               WHEN a.stakind2 = 5 THEN a.stanumbers2
+               WHEN a.stakind3 = 5 THEN a.stanumbers3
+               WHEN a.stakind4 = 5 THEN a.stanumbers4
+               WHEN a.stakind5 = 5 THEN a.stanumbers5
+           END aS elem_count_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stavalues1
+               WHEN a.stakind2 = 6 THEN a.stavalues2
+               WHEN a.stakind3 = 6 THEN a.stavalues3
+               WHEN a.stakind4 = 6 THEN a.stavalues4
+               WHEN a.stakind5 = 6 THEN a.stavalues5
+           END aS range_length_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 6 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 6 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 6 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 6 THEN a.stanumbers5[1]
+           END aS range_empty_frac,
+           CASE
+               WHEN a.stakind1 = 7 THEN a.stavalues1
+               WHEN a.stakind2 = 7 THEN a.stavalues2
+               WHEN a.stakind3 = 7 THEN a.stavalues3
+               WHEN a.stakind4 = 7 THEN a.stavalues4
+               WHEN a.stakind5 = 7 THEN a.stavalues5
+           END AS range_bounds_histogram
     FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid)
          LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid)
          LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace)
          LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace)
-         JOIN LATERAL (
-             SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-                    unnest(sd.stxdexpr)::pg_statistic AS a
-         ) stat ON (stat.expr IS NOT NULL)
+         JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid))
+              WITH ORDINALITY AS expr(expr, ordinality)
+                ON s.stxexprs IS NOT NULL
+         LEFT JOIN LATERAL unnest(sd.stxdexpr)
+              WITH ORDINALITY AS a
+                ON a.ordinality = expr.ordinality
     WHERE pg_has_role(c.relowner, 'USAGE')
     AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
 
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index f373ad704b6..7e1af2edb32 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2542,7 +2542,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
@@ -2634,8 +2636,10 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
     ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
            FROM (unnest(s.stxkeys) k(k)
@@ -2662,101 +2666,104 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
-    stat.expr,
+    expr.expr,
+    (0 - expr.ordinality) AS expr_attnum,
     sd.stxdinherit AS inherited,
-    (stat.a).stanullfrac AS null_frac,
-    (stat.a).stawidth AS avg_width,
-    (stat.a).stadistinct AS n_distinct,
+    a.stanullfrac AS null_frac,
+    a.stawidth AS avg_width,
+    a.stadistinct AS n_distinct,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 1) THEN a.stavalues1
+            WHEN (a.stakind2 = 1) THEN a.stavalues2
+            WHEN (a.stakind3 = 1) THEN a.stavalues3
+            WHEN (a.stakind4 = 1) THEN a.stavalues4
+            WHEN (a.stakind5 = 1) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_vals,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 1) THEN a.stanumbers1
+            WHEN (a.stakind2 = 1) THEN a.stanumbers2
+            WHEN (a.stakind3 = 1) THEN a.stanumbers3
+            WHEN (a.stakind4 = 1) THEN a.stanumbers4
+            WHEN (a.stakind5 = 1) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 2) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 2) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 2) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 2) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 2) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 2) THEN a.stavalues1
+            WHEN (a.stakind2 = 2) THEN a.stavalues2
+            WHEN (a.stakind3 = 2) THEN a.stavalues3
+            WHEN (a.stakind4 = 2) THEN a.stavalues4
+            WHEN (a.stakind5 = 2) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS histogram_bounds,
         CASE
-            WHEN ((stat.a).stakind1 = 3) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 3) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 3) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 3) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 3) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 3) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 3) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 3) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 3) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 3) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS correlation,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 4) THEN a.stavalues1
+            WHEN (a.stakind2 = 4) THEN a.stavalues2
+            WHEN (a.stakind3 = 4) THEN a.stavalues3
+            WHEN (a.stakind4 = 4) THEN a.stavalues4
+            WHEN (a.stakind5 = 4) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_elems,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 4) THEN a.stanumbers1
+            WHEN (a.stakind2 = 4) THEN a.stanumbers2
+            WHEN (a.stakind3 = 4) THEN a.stanumbers3
+            WHEN (a.stakind4 = 4) THEN a.stanumbers4
+            WHEN (a.stakind5 = 4) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_elem_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 5) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 5) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 5) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 5) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 5) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 5) THEN a.stanumbers1
+            WHEN (a.stakind2 = 5) THEN a.stanumbers2
+            WHEN (a.stakind3 = 5) THEN a.stanumbers3
+            WHEN (a.stakind4 = 5) THEN a.stanumbers4
+            WHEN (a.stakind5 = 5) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS elem_count_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 6) THEN a.stavalues1
+            WHEN (a.stakind2 = 6) THEN a.stavalues2
+            WHEN (a.stakind3 = 6) THEN a.stavalues3
+            WHEN (a.stakind4 = 6) THEN a.stavalues4
+            WHEN (a.stakind5 = 6) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_length_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 6) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 6) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 6) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 6) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 6) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS range_empty_frac,
         CASE
-            WHEN ((stat.a).stakind1 = 7) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 7) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 7) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 7) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 7) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 7) THEN a.stavalues1
+            WHEN (a.stakind2 = 7) THEN a.stavalues2
+            WHEN (a.stakind3 = 7) THEN a.stavalues3
+            WHEN (a.stakind4 = 7) THEN a.stavalues4
+            WHEN (a.stakind5 = 7) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_bounds_histogram
-   FROM (((((pg_statistic_ext s
+   FROM ((((((pg_statistic_ext s
      JOIN pg_class c ON ((c.oid = s.stxrelid)))
      LEFT JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid)))
      LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace)))
      LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace)))
-     JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-            unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL)))
+     JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid)) WITH ORDINALITY expr(expr, ordinality) ON ((s.stxexprs IS NOT NULL)))
+     LEFT JOIN LATERAL unnest(sd.stxdexpr) WITH ORDINALITY a(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5, ordinality) ON ((a.ordinality = expr.ordinality)))
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_tables| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 12d70bc4723..4f0e846b005 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -3,7 +3,7 @@ CREATE SCHEMA stats_import;
 -- Set up convenience views
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
@@ -77,7 +77,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    17
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -118,7 +118,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    23
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
@@ -659,9 +659,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -686,9 +686,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -711,9 +711,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -737,9 +737,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -763,9 +763,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -791,9 +791,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -818,9 +818,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -843,9 +843,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -869,9 +869,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -893,9 +893,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -919,9 +919,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -944,9 +944,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -972,9 +972,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -998,9 +998,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1024,9 +1024,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1049,9 +1049,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1076,9 +1076,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1100,9 +1100,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1128,9 +1128,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1156,9 +1156,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1182,9 +1182,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1208,9 +1208,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1233,9 +1233,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1260,9 +1260,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index fe54eb46f43..cb0d274fe4b 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -1,10 +1,11 @@
 CREATE SCHEMA stats_import;
 
 --
--- Set up convenience views
+-- Set up convenience views. Only stable values can be exposed by these
+-- views.
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..403a8d07400 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
@@ -4666,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4686,6 +4716,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4877,6 +4917,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4897,6 +4947,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4916,6 +4976,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
-- 
2.53.0



  [text/x-patch] v6-0003-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 5-v6-0003-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From 2f6c80b5a09f3baddf056fcf5033004691c4890e Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v6 3/3] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 137161aa5e0..9cdacbc3467 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7224,6 +7224,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11118,8 +11119,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11153,8 +11155,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11167,14 +11179,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11182,16 +11215,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11250,8 +11297,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11270,22 +11327,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11293,7 +11358,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-13 15:38                                         ` Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Sami Imseih @ 2026-03-13 15:38 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Nathan Bossart <[email protected]>; [email protected]

>> It will be good to add more commentary here to the next person adding
>> a test, and mention
>> that only stable values should be included in this view. what do you think?
>
>
> I added a comment, but I don't think a test writer would be confused for long if they did break that rule.

Thanks! it looks like you added the additional comment to 0002 rather than 0001
which introduced the view. I fixed that in the attached.

>> +       (references <link
>> linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
>
>
> Fixed catalog-pg-attribute and catalog-pg-statistic-ext

A few references were missed in 0002.

+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-class"><structname>pg_statistic_ext</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>

Also fixed in v7


--
Sami Imseih
Amazon Web Services (AWS)


Attachments:

  [application/octet-stream] v7-0001-Add-test-view-pg_stats_check.patch (14.0K, 2-v7-0001-Add-test-view-pg_stats_check.patch)
  download | inline diff:
From 58173141d8b2bc730589a30c93474b6bc780342b Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:25:29 -0400
Subject: [PATCH v7 1/3] Add test view pg_stats_check.

Add the view stats_import.pg_stats_check, allowing the columns selected
to be changed across all tests using the view by just changing the the
view definition.

This will allow for us to seamlessly add new columns that we do want to
see in the test results (attnum) while also allowing us to screen out
new columns that cannot be in the test results (tableid).
---
 src/test/regress/expected/stats_import.out | 65 +++++++++++++---------
 src/test/regress/sql/stats_import.sql      | 61 ++++++++++++--------
 2 files changed, 76 insertions(+), 50 deletions(-)

diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index c7adb783da2..2f538023f38 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -1,5 +1,17 @@
 CREATE SCHEMA stats_import;
 --
+-- Set up convenience views. Only stable values can be exposed by these
+-- views.
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+--
 -- Setup functions for set-difference convenience functions
 --
 -- Test to detect any new columns added to pg_statistic.  If any columns
@@ -643,7 +655,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -670,7 +682,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -695,7 +707,7 @@ WARNING:  unrecognized argument name: "nope"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -721,7 +733,7 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -747,7 +759,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -775,7 +787,7 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -802,7 +814,7 @@ WARNING:  invalid input syntax for type integer: "four"
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -827,7 +839,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -853,7 +865,7 @@ WARNING:  "histogram_bounds" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -877,7 +889,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -903,7 +915,7 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -928,7 +940,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -956,7 +968,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -982,7 +994,7 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1008,7 +1020,7 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1033,7 +1045,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1060,7 +1072,7 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1084,7 +1096,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1112,7 +1124,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1140,7 +1152,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1166,7 +1178,7 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1192,7 +1204,7 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1217,7 +1229,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -1244,7 +1256,7 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
 (1 row)
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -3362,8 +3374,9 @@ SELECT COUNT(*) FROM stats_import.test_range_expr_null
 (1 row)
 
 DROP SCHEMA stats_import CASCADE;
-NOTICE:  drop cascades to 18 other objects
-DETAIL:  drop cascades to view stats_import.pg_statistic_flat_t
+NOTICE:  drop cascades to 19 other objects
+DETAIL:  drop cascades to view stats_import.pg_stats_check
+drop cascades to view stats_import.pg_statistic_flat_t
 drop cascades to function stats_import.pg_statistic_flat(text)
 drop cascades to function stats_import.pg_statistic_get_difference(text,text)
 drop cascades to view stats_import.pg_stats_ext_flat_t
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0518bbf6f42..c36bdaf78ee 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -1,5 +1,18 @@
 CREATE SCHEMA stats_import;
 
+--
+-- Set up convenience views. Only stable values can be exposed by these
+-- views.
+--
+CREATE VIEW stats_import.pg_stats_check AS
+SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
+    histogram_bounds::text AS histogram_bounds, correlation,
+    most_common_elems::text AS most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram::text AS range_length_histogram,
+    range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram
+FROM pg_stats;
+
 --
 -- Setup functions for set-difference convenience functions
 --
@@ -521,7 +534,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'n_distinct', 0.6::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -540,7 +553,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.4::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -556,7 +569,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'nope', 0.5::real);
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -573,7 +586,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -590,7 +603,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -608,7 +621,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -626,7 +639,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -643,7 +656,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -660,7 +673,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -676,7 +689,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -693,7 +706,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -710,7 +723,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -728,7 +741,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -745,7 +758,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -762,7 +775,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -779,7 +792,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -796,7 +809,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -812,7 +825,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -830,7 +843,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -848,7 +861,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -865,7 +878,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -882,7 +895,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -899,7 +912,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
@@ -916,7 +929,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     );
 
 SELECT *
-FROM pg_stats
+FROM stats_import.pg_stats_check
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
-- 
2.47.3



  [application/octet-stream] v7-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch (77.9K, 3-v7-0002-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch)
  download | inline diff:
From 434a2838fec308b8ba8e4279b4c7f8c51f183438 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:51:00 -0400
Subject: [PATCH v7 2/3] Add tableid, statid, attnum, expr_attnum columns to
 pg_stats views.

Add tableid and attnum columns to pg_stats.  Add tableid, statid columns
to pg_stats_ext.  Add tableid, statid, expr_attnum columns to
pg_stats_ext_exprs.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

This patch makes simlilar changes to pg_stats_ext and
pg_stats_ext_exprs, but there is no immediate need to utlize those
changes in pg_dump.
---
 doc/src/sgml/system-views.sgml             |  72 +++++++++
 src/backend/catalog/system_views.sql       | 171 +++++++++++----------
 src/test/regress/expected/rules.out        | 121 ++++++++-------
 src/test/regress/expected/stats_import.out | 150 +++++++++---------
 src/test/regress/sql/stats_import.sql      |   2 +-
 5 files changed, 302 insertions(+), 214 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..199e7747a54 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
@@ -4666,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4686,6 +4716,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4877,6 +4917,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4897,6 +4947,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4916,6 +4976,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 90d48bc9c80..068e9cdaa43 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
@@ -278,8 +280,10 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
            ( SELECT array_agg(a.attname ORDER BY a.attnum)
              FROM unnest(s.stxkeys) k
@@ -312,92 +316,97 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
-           stat.expr,
+           expr.expr,
+           0 - expr.ordinality AS expr_attnum,
            sd.stxdinherit AS inherited,
-           (stat.a).stanullfrac AS null_frac,
-           (stat.a).stawidth AS avg_width,
-           (stat.a).stadistinct AS n_distinct,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5
-           END) AS most_common_vals,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5
-           END) AS most_common_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5
-           END) AS histogram_bounds,
-           (CASE
-               WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1]
-           END) correlation,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5
-           END) AS most_common_elems,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5
-           END) AS most_common_elem_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5
-           END) AS elem_count_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stavalues5
-           END) AS range_length_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stanumbers5[1]
-           END) AS range_empty_frac,
-           (CASE
-               WHEN (stat.a).stakind1 = 7 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 7 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 7 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 7 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 7 THEN (stat.a).stavalues5
-               END) AS range_bounds_histogram
+           a.stanullfrac AS null_frac,
+           a.stawidth AS avg_width,
+           a.stadistinct AS n_distinct,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stavalues1
+               WHEN a.stakind2 = 1 THEN a.stavalues2
+               WHEN a.stakind3 = 1 THEN a.stavalues3
+               WHEN a.stakind4 = 1 THEN a.stavalues4
+               WHEN a.stakind5 = 1 THEN a.stavalues5
+           END AS most_common_vals,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stanumbers1
+               WHEN a.stakind2 = 1 THEN a.stanumbers2
+               WHEN a.stakind3 = 1 THEN a.stanumbers3
+               WHEN a.stakind4 = 1 THEN a.stanumbers4
+               WHEN a.stakind5 = 1 THEN a.stanumbers5
+           END AS most_common_freqs,
+           CASE
+               WHEN a.stakind1 = 2 THEN a.stavalues1
+               WHEN a.stakind2 = 2 THEN a.stavalues2
+               WHEN a.stakind3 = 2 THEN a.stavalues3
+               WHEN a.stakind4 = 2 THEN a.stavalues4
+               WHEN a.stakind5 = 2 THEN a.stavalues5
+           END AS histogram_bounds,
+           CASE
+               WHEN a.stakind1 = 3 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 3 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 3 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 3 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 3 THEN a.stanumbers5[1]
+           END AS correlation,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stavalues1
+               WHEN a.stakind2 = 4 THEN a.stavalues2
+               WHEN a.stakind3 = 4 THEN a.stavalues3
+               WHEN a.stakind4 = 4 THEN a.stavalues4
+               WHEN a.stakind5 = 4 THEN a.stavalues5
+           END aS most_common_elems,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stanumbers1
+               WHEN a.stakind2 = 4 THEN a.stanumbers2
+               WHEN a.stakind3 = 4 THEN a.stanumbers3
+               WHEN a.stakind4 = 4 THEN a.stanumbers4
+               WHEN a.stakind5 = 4 THEN a.stanumbers5
+           END aS most_common_elem_freqs,
+           CASE
+               WHEN a.stakind1 = 5 THEN a.stanumbers1
+               WHEN a.stakind2 = 5 THEN a.stanumbers2
+               WHEN a.stakind3 = 5 THEN a.stanumbers3
+               WHEN a.stakind4 = 5 THEN a.stanumbers4
+               WHEN a.stakind5 = 5 THEN a.stanumbers5
+           END aS elem_count_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stavalues1
+               WHEN a.stakind2 = 6 THEN a.stavalues2
+               WHEN a.stakind3 = 6 THEN a.stavalues3
+               WHEN a.stakind4 = 6 THEN a.stavalues4
+               WHEN a.stakind5 = 6 THEN a.stavalues5
+           END aS range_length_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 6 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 6 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 6 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 6 THEN a.stanumbers5[1]
+           END aS range_empty_frac,
+           CASE
+               WHEN a.stakind1 = 7 THEN a.stavalues1
+               WHEN a.stakind2 = 7 THEN a.stavalues2
+               WHEN a.stakind3 = 7 THEN a.stavalues3
+               WHEN a.stakind4 = 7 THEN a.stavalues4
+               WHEN a.stakind5 = 7 THEN a.stavalues5
+           END AS range_bounds_histogram
     FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid)
          LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid)
          LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace)
          LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace)
-         JOIN LATERAL (
-             SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-                    unnest(sd.stxdexpr)::pg_statistic AS a
-         ) stat ON (stat.expr IS NOT NULL)
+         JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid))
+              WITH ORDINALITY AS expr(expr, ordinality)
+                ON s.stxexprs IS NOT NULL
+         LEFT JOIN LATERAL unnest(sd.stxdexpr)
+              WITH ORDINALITY AS a
+                ON a.ordinality = expr.ordinality
     WHERE pg_has_role(c.relowner, 'USAGE')
     AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
 
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 71d7262049e..d0fd813aa8a 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2543,7 +2543,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
@@ -2635,8 +2637,10 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
     ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
            FROM (unnest(s.stxkeys) k(k)
@@ -2663,101 +2667,104 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
-    stat.expr,
+    expr.expr,
+    (0 - expr.ordinality) AS expr_attnum,
     sd.stxdinherit AS inherited,
-    (stat.a).stanullfrac AS null_frac,
-    (stat.a).stawidth AS avg_width,
-    (stat.a).stadistinct AS n_distinct,
+    a.stanullfrac AS null_frac,
+    a.stawidth AS avg_width,
+    a.stadistinct AS n_distinct,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 1) THEN a.stavalues1
+            WHEN (a.stakind2 = 1) THEN a.stavalues2
+            WHEN (a.stakind3 = 1) THEN a.stavalues3
+            WHEN (a.stakind4 = 1) THEN a.stavalues4
+            WHEN (a.stakind5 = 1) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_vals,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 1) THEN a.stanumbers1
+            WHEN (a.stakind2 = 1) THEN a.stanumbers2
+            WHEN (a.stakind3 = 1) THEN a.stanumbers3
+            WHEN (a.stakind4 = 1) THEN a.stanumbers4
+            WHEN (a.stakind5 = 1) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 2) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 2) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 2) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 2) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 2) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 2) THEN a.stavalues1
+            WHEN (a.stakind2 = 2) THEN a.stavalues2
+            WHEN (a.stakind3 = 2) THEN a.stavalues3
+            WHEN (a.stakind4 = 2) THEN a.stavalues4
+            WHEN (a.stakind5 = 2) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS histogram_bounds,
         CASE
-            WHEN ((stat.a).stakind1 = 3) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 3) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 3) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 3) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 3) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 3) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 3) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 3) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 3) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 3) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS correlation,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 4) THEN a.stavalues1
+            WHEN (a.stakind2 = 4) THEN a.stavalues2
+            WHEN (a.stakind3 = 4) THEN a.stavalues3
+            WHEN (a.stakind4 = 4) THEN a.stavalues4
+            WHEN (a.stakind5 = 4) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_elems,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 4) THEN a.stanumbers1
+            WHEN (a.stakind2 = 4) THEN a.stanumbers2
+            WHEN (a.stakind3 = 4) THEN a.stanumbers3
+            WHEN (a.stakind4 = 4) THEN a.stanumbers4
+            WHEN (a.stakind5 = 4) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_elem_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 5) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 5) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 5) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 5) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 5) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 5) THEN a.stanumbers1
+            WHEN (a.stakind2 = 5) THEN a.stanumbers2
+            WHEN (a.stakind3 = 5) THEN a.stanumbers3
+            WHEN (a.stakind4 = 5) THEN a.stanumbers4
+            WHEN (a.stakind5 = 5) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS elem_count_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 6) THEN a.stavalues1
+            WHEN (a.stakind2 = 6) THEN a.stavalues2
+            WHEN (a.stakind3 = 6) THEN a.stavalues3
+            WHEN (a.stakind4 = 6) THEN a.stavalues4
+            WHEN (a.stakind5 = 6) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_length_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 6) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 6) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 6) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 6) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 6) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS range_empty_frac,
         CASE
-            WHEN ((stat.a).stakind1 = 7) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 7) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 7) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 7) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 7) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 7) THEN a.stavalues1
+            WHEN (a.stakind2 = 7) THEN a.stavalues2
+            WHEN (a.stakind3 = 7) THEN a.stavalues3
+            WHEN (a.stakind4 = 7) THEN a.stavalues4
+            WHEN (a.stakind5 = 7) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_bounds_histogram
-   FROM (((((pg_statistic_ext s
+   FROM ((((((pg_statistic_ext s
      JOIN pg_class c ON ((c.oid = s.stxrelid)))
      LEFT JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid)))
      LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace)))
      LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace)))
-     JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-            unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL)))
+     JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid)) WITH ORDINALITY expr(expr, ordinality) ON ((s.stxexprs IS NOT NULL)))
+     LEFT JOIN LATERAL unnest(sd.stxdexpr) WITH ORDINALITY a(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5, ordinality) ON ((a.ordinality = expr.ordinality)))
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_tables| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 2f538023f38..33f3defd3b9 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -4,7 +4,7 @@ CREATE SCHEMA stats_import;
 -- views.
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
@@ -78,7 +78,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    17
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -119,7 +119,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    23
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
@@ -660,9 +660,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -687,9 +687,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -712,9 +712,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -738,9 +738,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -764,9 +764,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -792,9 +792,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -819,9 +819,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -844,9 +844,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -870,9 +870,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -894,9 +894,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -920,9 +920,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -945,9 +945,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -973,9 +973,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -999,9 +999,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1025,9 +1025,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1050,9 +1050,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1077,9 +1077,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1101,9 +1101,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1129,9 +1129,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1157,9 +1157,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1183,9 +1183,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1209,9 +1209,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1234,9 +1234,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1261,9 +1261,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index c36bdaf78ee..cb0d274fe4b 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -5,7 +5,7 @@ CREATE SCHEMA stats_import;
 -- views.
 --
 CREATE VIEW stats_import.pg_stats_check AS
-SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
     n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs,
     histogram_bounds::text AS histogram_bounds, correlation,
     most_common_elems::text AS most_common_elems, most_common_elem_freqs,
-- 
2.47.3



  [application/octet-stream] v7-0003-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 4-v7-0003-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From cd54341ff76e13a7ccab6b7c60a036e35147b743 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v7 3/3] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 137161aa5e0..9cdacbc3467 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7224,6 +7224,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11118,8 +11119,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11153,8 +11155,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11167,14 +11179,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11182,16 +11215,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11250,8 +11297,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11270,22 +11327,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11293,7 +11358,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.47.3



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
@ 2026-03-13 20:07                                           ` Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-13 20:07 UTC (permalink / raw)
  To: Sami Imseih <[email protected]>; +Cc: Corey Huinker <[email protected]>; [email protected]

I committed 0001, albeit with some editorialization.  The others might need
some rebasing, which I can help with next week if someone else doesn't beat
me to it.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-14 21:13                                             ` Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-14 21:13 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Fri, Mar 13, 2026 at 4:07 PM Nathan Bossart <[email protected]>
wrote:

> I committed 0001, albeit with some editorialization.  The others might need
> some rebasing, which I can help with next week if someone else doesn't beat
> me to it.
>
>
"_stable", nice name choice. Rebasing was nonzero but just barely.


Attachments:

  [text/x-patch] v8-0001-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch (78.1K, 3-v8-0001-Add-tableid-statid-attnum-expr_attnum-columns-to-.patch)
  download | inline diff:
From 9f933a84e4c3e62f30b0b542eb4206f0dfabcf9f Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 10 Mar 2026 13:51:00 -0400
Subject: [PATCH v8 1/2] Add tableid, statid, attnum, expr_attnum columns to
 pg_stats views.

Add tableid and attnum columns to pg_stats.  Add tableid, statid columns
to pg_stats_ext.  Add tableid, statid, expr_attnum columns to
pg_stats_ext_exprs.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

This patch makes simlilar changes to pg_stats_ext and
pg_stats_ext_exprs, but there is no immediate need to utlize those
changes in pg_dump.
---
 src/backend/catalog/system_views.sql       | 171 +++++++++++----------
 src/test/regress/expected/rules.out        | 121 ++++++++-------
 src/test/regress/expected/stats_import.out | 150 +++++++++---------
 src/test/regress/sql/stats_import.sql      |   2 +-
 doc/src/sgml/system-views.sgml             |  72 +++++++++
 5 files changed, 302 insertions(+), 214 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 90d48bc9c80..068e9cdaa43 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -189,9 +189,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
@@ -278,8 +280,10 @@ REVOKE ALL ON pg_statistic FROM public;
 CREATE VIEW pg_stats_ext WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
            ( SELECT array_agg(a.attname ORDER BY a.attnum)
              FROM unnest(s.stxkeys) k
@@ -312,92 +316,97 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
 CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
     SELECT cn.nspname AS schemaname,
            c.relname AS tablename,
+           s.stxrelid AS tableid,
            sn.nspname AS statistics_schemaname,
            s.stxname AS statistics_name,
+           s.oid AS statid,
            pg_get_userbyid(s.stxowner) AS statistics_owner,
-           stat.expr,
+           expr.expr,
+           0 - expr.ordinality AS expr_attnum,
            sd.stxdinherit AS inherited,
-           (stat.a).stanullfrac AS null_frac,
-           (stat.a).stawidth AS avg_width,
-           (stat.a).stadistinct AS n_distinct,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5
-           END) AS most_common_vals,
-           (CASE
-               WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5
-           END) AS most_common_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5
-           END) AS histogram_bounds,
-           (CASE
-               WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1]
-           END) correlation,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5
-           END) AS most_common_elems,
-           (CASE
-               WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5
-           END) AS most_common_elem_freqs,
-           (CASE
-               WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1
-               WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2
-               WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3
-               WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4
-               WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5
-           END) AS elem_count_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stavalues5
-           END) AS range_length_histogram,
-           (CASE
-               WHEN (stat.a).stakind1 = 6 THEN (stat.a).stanumbers1[1]
-               WHEN (stat.a).stakind2 = 6 THEN (stat.a).stanumbers2[1]
-               WHEN (stat.a).stakind3 = 6 THEN (stat.a).stanumbers3[1]
-               WHEN (stat.a).stakind4 = 6 THEN (stat.a).stanumbers4[1]
-               WHEN (stat.a).stakind5 = 6 THEN (stat.a).stanumbers5[1]
-           END) AS range_empty_frac,
-           (CASE
-               WHEN (stat.a).stakind1 = 7 THEN (stat.a).stavalues1
-               WHEN (stat.a).stakind2 = 7 THEN (stat.a).stavalues2
-               WHEN (stat.a).stakind3 = 7 THEN (stat.a).stavalues3
-               WHEN (stat.a).stakind4 = 7 THEN (stat.a).stavalues4
-               WHEN (stat.a).stakind5 = 7 THEN (stat.a).stavalues5
-               END) AS range_bounds_histogram
+           a.stanullfrac AS null_frac,
+           a.stawidth AS avg_width,
+           a.stadistinct AS n_distinct,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stavalues1
+               WHEN a.stakind2 = 1 THEN a.stavalues2
+               WHEN a.stakind3 = 1 THEN a.stavalues3
+               WHEN a.stakind4 = 1 THEN a.stavalues4
+               WHEN a.stakind5 = 1 THEN a.stavalues5
+           END AS most_common_vals,
+           CASE
+               WHEN a.stakind1 = 1 THEN a.stanumbers1
+               WHEN a.stakind2 = 1 THEN a.stanumbers2
+               WHEN a.stakind3 = 1 THEN a.stanumbers3
+               WHEN a.stakind4 = 1 THEN a.stanumbers4
+               WHEN a.stakind5 = 1 THEN a.stanumbers5
+           END AS most_common_freqs,
+           CASE
+               WHEN a.stakind1 = 2 THEN a.stavalues1
+               WHEN a.stakind2 = 2 THEN a.stavalues2
+               WHEN a.stakind3 = 2 THEN a.stavalues3
+               WHEN a.stakind4 = 2 THEN a.stavalues4
+               WHEN a.stakind5 = 2 THEN a.stavalues5
+           END AS histogram_bounds,
+           CASE
+               WHEN a.stakind1 = 3 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 3 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 3 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 3 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 3 THEN a.stanumbers5[1]
+           END AS correlation,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stavalues1
+               WHEN a.stakind2 = 4 THEN a.stavalues2
+               WHEN a.stakind3 = 4 THEN a.stavalues3
+               WHEN a.stakind4 = 4 THEN a.stavalues4
+               WHEN a.stakind5 = 4 THEN a.stavalues5
+           END aS most_common_elems,
+           CASE
+               WHEN a.stakind1 = 4 THEN a.stanumbers1
+               WHEN a.stakind2 = 4 THEN a.stanumbers2
+               WHEN a.stakind3 = 4 THEN a.stanumbers3
+               WHEN a.stakind4 = 4 THEN a.stanumbers4
+               WHEN a.stakind5 = 4 THEN a.stanumbers5
+           END aS most_common_elem_freqs,
+           CASE
+               WHEN a.stakind1 = 5 THEN a.stanumbers1
+               WHEN a.stakind2 = 5 THEN a.stanumbers2
+               WHEN a.stakind3 = 5 THEN a.stanumbers3
+               WHEN a.stakind4 = 5 THEN a.stanumbers4
+               WHEN a.stakind5 = 5 THEN a.stanumbers5
+           END aS elem_count_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stavalues1
+               WHEN a.stakind2 = 6 THEN a.stavalues2
+               WHEN a.stakind3 = 6 THEN a.stavalues3
+               WHEN a.stakind4 = 6 THEN a.stavalues4
+               WHEN a.stakind5 = 6 THEN a.stavalues5
+           END aS range_length_histogram,
+           CASE
+               WHEN a.stakind1 = 6 THEN a.stanumbers1[1]
+               WHEN a.stakind2 = 6 THEN a.stanumbers2[1]
+               WHEN a.stakind3 = 6 THEN a.stanumbers3[1]
+               WHEN a.stakind4 = 6 THEN a.stanumbers4[1]
+               WHEN a.stakind5 = 6 THEN a.stanumbers5[1]
+           END aS range_empty_frac,
+           CASE
+               WHEN a.stakind1 = 7 THEN a.stavalues1
+               WHEN a.stakind2 = 7 THEN a.stavalues2
+               WHEN a.stakind3 = 7 THEN a.stavalues3
+               WHEN a.stakind4 = 7 THEN a.stavalues4
+               WHEN a.stakind5 = 7 THEN a.stavalues5
+           END AS range_bounds_histogram
     FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid)
          LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid)
          LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace)
          LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace)
-         JOIN LATERAL (
-             SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-                    unnest(sd.stxdexpr)::pg_statistic AS a
-         ) stat ON (stat.expr IS NOT NULL)
+         JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid))
+              WITH ORDINALITY AS expr(expr, ordinality)
+                ON s.stxexprs IS NOT NULL
+         LEFT JOIN LATERAL unnest(sd.stxdexpr)
+              WITH ORDINALITY AS a
+                ON a.ordinality = expr.ordinality
     WHERE pg_has_role(c.relowner, 'USAGE')
     AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
 
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 71d7262049e..d0fd813aa8a 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2543,7 +2543,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
@@ -2635,8 +2637,10 @@ pg_stats| SELECT n.nspname AS schemaname,
   WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
     ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
            FROM (unnest(s.stxkeys) k(k)
@@ -2663,101 +2667,104 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
     c.relname AS tablename,
+    s.stxrelid AS tableid,
     sn.nspname AS statistics_schemaname,
     s.stxname AS statistics_name,
+    s.oid AS statid,
     pg_get_userbyid(s.stxowner) AS statistics_owner,
-    stat.expr,
+    expr.expr,
+    (0 - expr.ordinality) AS expr_attnum,
     sd.stxdinherit AS inherited,
-    (stat.a).stanullfrac AS null_frac,
-    (stat.a).stawidth AS avg_width,
-    (stat.a).stadistinct AS n_distinct,
+    a.stanullfrac AS null_frac,
+    a.stawidth AS avg_width,
+    a.stadistinct AS n_distinct,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 1) THEN a.stavalues1
+            WHEN (a.stakind2 = 1) THEN a.stavalues2
+            WHEN (a.stakind3 = 1) THEN a.stavalues3
+            WHEN (a.stakind4 = 1) THEN a.stavalues4
+            WHEN (a.stakind5 = 1) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_vals,
         CASE
-            WHEN ((stat.a).stakind1 = 1) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 1) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 1) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 1) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 1) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 1) THEN a.stanumbers1
+            WHEN (a.stakind2 = 1) THEN a.stanumbers2
+            WHEN (a.stakind3 = 1) THEN a.stanumbers3
+            WHEN (a.stakind4 = 1) THEN a.stanumbers4
+            WHEN (a.stakind5 = 1) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 2) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 2) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 2) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 2) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 2) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 2) THEN a.stavalues1
+            WHEN (a.stakind2 = 2) THEN a.stavalues2
+            WHEN (a.stakind3 = 2) THEN a.stavalues3
+            WHEN (a.stakind4 = 2) THEN a.stavalues4
+            WHEN (a.stakind5 = 2) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS histogram_bounds,
         CASE
-            WHEN ((stat.a).stakind1 = 3) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 3) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 3) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 3) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 3) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 3) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 3) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 3) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 3) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 3) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS correlation,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 4) THEN a.stavalues1
+            WHEN (a.stakind2 = 4) THEN a.stavalues2
+            WHEN (a.stakind3 = 4) THEN a.stavalues3
+            WHEN (a.stakind4 = 4) THEN a.stavalues4
+            WHEN (a.stakind5 = 4) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS most_common_elems,
         CASE
-            WHEN ((stat.a).stakind1 = 4) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 4) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 4) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 4) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 4) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 4) THEN a.stanumbers1
+            WHEN (a.stakind2 = 4) THEN a.stanumbers2
+            WHEN (a.stakind3 = 4) THEN a.stanumbers3
+            WHEN (a.stakind4 = 4) THEN a.stanumbers4
+            WHEN (a.stakind5 = 4) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS most_common_elem_freqs,
         CASE
-            WHEN ((stat.a).stakind1 = 5) THEN (stat.a).stanumbers1
-            WHEN ((stat.a).stakind2 = 5) THEN (stat.a).stanumbers2
-            WHEN ((stat.a).stakind3 = 5) THEN (stat.a).stanumbers3
-            WHEN ((stat.a).stakind4 = 5) THEN (stat.a).stanumbers4
-            WHEN ((stat.a).stakind5 = 5) THEN (stat.a).stanumbers5
+            WHEN (a.stakind1 = 5) THEN a.stanumbers1
+            WHEN (a.stakind2 = 5) THEN a.stanumbers2
+            WHEN (a.stakind3 = 5) THEN a.stanumbers3
+            WHEN (a.stakind4 = 5) THEN a.stanumbers4
+            WHEN (a.stakind5 = 5) THEN a.stanumbers5
             ELSE NULL::real[]
         END AS elem_count_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 6) THEN a.stavalues1
+            WHEN (a.stakind2 = 6) THEN a.stavalues2
+            WHEN (a.stakind3 = 6) THEN a.stavalues3
+            WHEN (a.stakind4 = 6) THEN a.stavalues4
+            WHEN (a.stakind5 = 6) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_length_histogram,
         CASE
-            WHEN ((stat.a).stakind1 = 6) THEN (stat.a).stanumbers1[1]
-            WHEN ((stat.a).stakind2 = 6) THEN (stat.a).stanumbers2[1]
-            WHEN ((stat.a).stakind3 = 6) THEN (stat.a).stanumbers3[1]
-            WHEN ((stat.a).stakind4 = 6) THEN (stat.a).stanumbers4[1]
-            WHEN ((stat.a).stakind5 = 6) THEN (stat.a).stanumbers5[1]
+            WHEN (a.stakind1 = 6) THEN a.stanumbers1[1]
+            WHEN (a.stakind2 = 6) THEN a.stanumbers2[1]
+            WHEN (a.stakind3 = 6) THEN a.stanumbers3[1]
+            WHEN (a.stakind4 = 6) THEN a.stanumbers4[1]
+            WHEN (a.stakind5 = 6) THEN a.stanumbers5[1]
             ELSE NULL::real
         END AS range_empty_frac,
         CASE
-            WHEN ((stat.a).stakind1 = 7) THEN (stat.a).stavalues1
-            WHEN ((stat.a).stakind2 = 7) THEN (stat.a).stavalues2
-            WHEN ((stat.a).stakind3 = 7) THEN (stat.a).stavalues3
-            WHEN ((stat.a).stakind4 = 7) THEN (stat.a).stavalues4
-            WHEN ((stat.a).stakind5 = 7) THEN (stat.a).stavalues5
+            WHEN (a.stakind1 = 7) THEN a.stavalues1
+            WHEN (a.stakind2 = 7) THEN a.stavalues2
+            WHEN (a.stakind3 = 7) THEN a.stavalues3
+            WHEN (a.stakind4 = 7) THEN a.stavalues4
+            WHEN (a.stakind5 = 7) THEN a.stavalues5
             ELSE NULL::anyarray
         END AS range_bounds_histogram
-   FROM (((((pg_statistic_ext s
+   FROM ((((((pg_statistic_ext s
      JOIN pg_class c ON ((c.oid = s.stxrelid)))
      LEFT JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid)))
      LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace)))
      LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace)))
-     JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr,
-            unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL)))
+     JOIN LATERAL unnest(pg_get_statisticsobjdef_expressions(s.oid)) WITH ORDINALITY expr(expr, ordinality) ON ((s.stxexprs IS NOT NULL)))
+     LEFT JOIN LATERAL unnest(sd.stxdexpr) WITH ORDINALITY a(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5, ordinality) ON ((a.ordinality = expr.ordinality)))
   WHERE (pg_has_role(c.relowner, 'USAGE'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_tables| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 0aa9f657376..4edf07f175f 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -3,7 +3,7 @@ CREATE SCHEMA stats_import;
 -- Convenience view for columns of pg_stats that are stable across test runs.
 --
 CREATE VIEW stats_import.pg_stats_stable AS
-  SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+  SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
       n_distinct, most_common_vals::text as most_common_vals,
       most_common_freqs, histogram_bounds::text AS histogram_bounds,
       correlation, most_common_elems::text AS most_common_elems,
@@ -78,7 +78,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    15
+    17
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext.
@@ -119,7 +119,7 @@ SELECT COUNT(*) FROM pg_attribute
     attnum > 0;
  count 
 -------
-    20
+    23
 (1 row)
 
 -- Create a view that is used purely for the type based on pg_stats_ext_exprs.
@@ -660,9 +660,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -687,9 +687,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -712,9 +712,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -738,9 +738,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -764,9 +764,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -792,9 +792,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -819,9 +819,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -844,9 +844,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -870,9 +870,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -894,9 +894,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -920,9 +920,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -945,9 +945,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -973,9 +973,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -999,9 +999,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -1025,9 +1025,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -1050,9 +1050,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -1077,9 +1077,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -1101,9 +1101,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -1129,9 +1129,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -1157,9 +1157,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1183,9 +1183,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1209,9 +1209,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1234,9 +1234,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1261,9 +1261,9 @@ WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 0bfa3d44cef..b8e701e4cf4 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -4,7 +4,7 @@ CREATE SCHEMA stats_import;
 -- Convenience view for columns of pg_stats that are stable across test runs.
 --
 CREATE VIEW stats_import.pg_stats_stable AS
-  SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
+  SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
       n_distinct, most_common_vals::text as most_common_vals,
       most_common_freqs, histogram_bounds::text AS histogram_bounds,
       correlation, most_common_elems::text AS most_common_elems,
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..199e7747a54 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>
@@ -4666,6 +4686,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4686,6 +4716,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4877,6 +4917,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>tableid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_schemaname</structfield> <type>name</type>
@@ -4897,6 +4947,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>statid</structfield> <type>oid</type>
+       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+      </para>
+      <para>
+       ID of the extended statistics object
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>statistics_owner</structfield> <type>name</type>
@@ -4916,6 +4976,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>expr_attnum</structfield> <type>int2</type>
+      </para>
+      <para>
+       Synthetic attnum used to reference this expression in
+       <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxdndistinct</structfield>
+       and
+       <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxddependencies</structfield>
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>

base-commit: 0123ce131fca454009439dfa3b2266d1d40737d7
-- 
2.53.0



  [text/x-patch] v8-0002-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 4-v8-0002-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From 99642064ca183e9a484f5ea18e5f1b6a6a369298 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v8 2/2] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 137161aa5e0..9cdacbc3467 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7224,6 +7224,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11118,8 +11119,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11153,8 +11155,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11167,14 +11179,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11182,16 +11215,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11250,8 +11297,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11270,22 +11327,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11293,7 +11358,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1c11a79083f..6fa248cc812 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-16 19:19                                               ` Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-16 19:19 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]

On Sat, Mar 14, 2026 at 05:13:19PM -0400, Corey Huinker wrote:
> "_stable", nice name choice. Rebasing was nonzero but just barely.

Thanks.  Here is what I have staged for commit for the next patch in the
series.

>  CREATE VIEW pg_stats WITH (security_barrier) AS
>      SELECT
> -        nspname AS schemaname,
> -        relname AS tablename,
> -        attname AS attname,
> +        n.nspname AS schemaname,
> +        c.relname AS tablename,
> +        a.attrelid AS tableid,
> +        a.attname AS attname,
> +        a.attnum AS attnum,

I didn't see why we needed to change the lines for the existing columns, so
I left those parts out.

>  CREATE VIEW pg_stats_ext WITH (security_barrier) AS
>      SELECT cn.nspname AS schemaname,
>             c.relname AS tablename,
> +           s.stxrelid AS tableid,
>             sn.nspname AS statistics_schemaname,
>             s.stxname AS statistics_name,
> +           s.oid AS statid,

I went with "statistics_id" to match the naming scheme.

>  CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
>      SELECT cn.nspname AS schemaname,
>             c.relname AS tablename,
> +           s.stxrelid AS tableid,
>             sn.nspname AS statistics_schemaname,
>             s.stxname AS statistics_name,
> +           s.oid AS statid,
>             pg_get_userbyid(s.stxowner) AS statistics_owner,
> -           stat.expr,
> +           expr.expr,
> +           0 - expr.ordinality AS expr_attnum,

I left the expr_attnum stuff out.  It seems to make this patch quite large
and complicated, we don't plan to use it for the pg_dump patch, and I'm not
sure about showing users a "synthetic attnum" that seems to have no other
point of reference.  Would this information be useful in pg_dump somewhere?
I'm curious to hear more about the intent.

>  CREATE VIEW stats_import.pg_stats_stable AS
> -  SELECT schemaname, tablename, attname, inherited, null_frac, avg_width,
> +  SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,

I didn't see much value in adding attnum here given the size of the changes
to the expected output it produces.

> +       <structfield>tableid</structfield> <type>oid</type>
> +       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)

While we might be pulling the OID from pg_attribute in the view, we seem to
point to the true origin for these reference notes elsewhere, so I changed
it to pg_class.oid here.

> +       <structfield>tableid</structfield> <type>oid</type>
> +       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)

... and here.

> +       <structfield>tableid</structfield> <type>oid</type>
> +       (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxrelid</structfield>)

... and here.

-- 
nathan


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-16 20:04                                                 ` Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-16 20:04 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]; [email protected]

>
>
> >  CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
> >      SELECT cn.nspname AS schemaname,
> >             c.relname AS tablename,
> > +           s.stxrelid AS tableid,
> >             sn.nspname AS statistics_schemaname,
> >             s.stxname AS statistics_name,
> > +           s.oid AS statid,
> >             pg_get_userbyid(s.stxowner) AS statistics_owner,
> > -           stat.expr,
> > +           expr.expr,
> > +           0 - expr.ordinality AS expr_attnum,
>
> I left the expr_attnum stuff out.  It seems to make this patch quite large
> and complicated, we don't plan to use it for the pg_dump patch, and I'm not
> sure about showing users a "synthetic attnum" that seems to have no other
> point of reference.  Would this information be useful in pg_dump somewhere?
> I'm curious to hear more about the intent.
>

expr_attnum was something that Michael Paquier had lamented that the view
didn't have. There is obviously no present need for it, as pg_dump isn't
being modified for extended stats at all.


> I didn't see much value in adding attnum here given the size of the changes
> to the expected output it produces.
>

Same reasons for putting that in - people had lamented that we couldn't
order the dump by attnum, and ordering by attname feels weird somehow.
Again, we don't presently need it.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-16 20:15                                                   ` Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-16 20:15 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Sami Imseih <[email protected]>; [email protected]; [email protected]

On Mon, Mar 16, 2026 at 04:04:23PM -0400, Corey Huinker wrote:
>> I left the expr_attnum stuff out.  It seems to make this patch quite large
>> and complicated, we don't plan to use it for the pg_dump patch, and I'm not
>> sure about showing users a "synthetic attnum" that seems to have no other
>> point of reference.  Would this information be useful in pg_dump somewhere?
>> I'm curious to hear more about the intent.
> 
> expr_attnum was something that Michael Paquier had lamented that the view
> didn't have. There is obviously no present need for it, as pg_dump isn't
> being modified for extended stats at all.

Okay.  I think I'll continue to leave this one out for now.

>> I didn't see much value in adding attnum here given the size of the changes
>> to the expected output it produces.
> 
> Same reasons for putting that in - people had lamented that we couldn't
> order the dump by attnum, and ordering by attname feels weird somehow.
> Again, we don't presently need it.

This note was about adding attnum to the pg_stats_stable view in the test.
I don't have any problem with adding it to pg_stats.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-16 21:49                                                     ` Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Michael Paquier @ 2026-03-16 21:49 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Corey Huinker <[email protected]>; Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 16, 2026 at 03:15:14PM -0500, Nathan Bossart wrote:
> On Mon, Mar 16, 2026 at 04:04:23PM -0400, Corey Huinker wrote:
>> expr_attnum was something that Michael Paquier had lamented that the view
>> didn't have. There is obviously no present need for it, as pg_dump isn't
>> being modified for extended stats at all.
> 
> Okay.  I think I'll continue to leave this one out for now.

Lamenting is the right term.  The expressions stored in an extended
stats object have attnumbers computed by the backend, starting from -1
and decremented, and we don't expose this information at all in any
system view.  It could have helped in enforcing a stronger ordering of
the items dumps for the extstats restore functions.  I still think
that it could provide an extra layer of safety.  Now, we don't
critically require it either based on how we pass down the input
arrays, how we dump the data from the catalogs, and how we treat the
order of the items given as function args.
--
Michael


Attachments:

  [application/pgp-signature] signature.asc (833B, 2-signature.asc)
  download

^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
@ 2026-03-16 22:52                                                       ` Nathan Bossart <[email protected]>
  2026-03-16 23:02                                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-16 22:52 UTC (permalink / raw)
  To: Michael Paquier <[email protected]>; +Cc: Corey Huinker <[email protected]>; Sami Imseih <[email protected]>; [email protected]

On Tue, Mar 17, 2026 at 06:49:17AM +0900, Michael Paquier wrote:
> On Mon, Mar 16, 2026 at 03:15:14PM -0500, Nathan Bossart wrote:
>> On Mon, Mar 16, 2026 at 04:04:23PM -0400, Corey Huinker wrote:
>>> expr_attnum was something that Michael Paquier had lamented that the view
>>> didn't have. There is obviously no present need for it, as pg_dump isn't
>>> being modified for extended stats at all.
>> 
>> Okay.  I think I'll continue to leave this one out for now.
> 
> Lamenting is the right term.  The expressions stored in an extended
> stats object have attnumbers computed by the backend, starting from -1
> and decremented, and we don't expose this information at all in any
> system view.  It could have helped in enforcing a stronger ordering of
> the items dumps for the extstats restore functions.  I still think
> that it could provide an extra layer of safety.  Now, we don't
> critically require it either based on how we pass down the input
> arrays, how we dump the data from the catalogs, and how we treat the
> order of the items given as function args.

FTR I'm not mortally opposed to the idea.  I just want to get the easier
stuff out of the way first so we can commit the pg_dump change.  Then we
can give expr_attnum our undivided attention.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-16 23:02                                                         ` Michael Paquier <[email protected]>
  2026-03-17 02:05                                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Michael Paquier @ 2026-03-16 23:02 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: Corey Huinker <[email protected]>; Sami Imseih <[email protected]>; [email protected]

On Mon, Mar 16, 2026 at 05:52:38PM -0500, Nathan Bossart wrote:
> FTR I'm not mortally opposed to the idea.  I just want to get the easier
> stuff out of the way first so we can commit the pg_dump change.  Then we
> can give expr_attnum our undivided attention.

Makes sense here to keep it simple.  I don't want to change the
extstat restore code more than necessary at this stage of the CF
calendar cycle, except for bugs and issues discussed during the beta
cycle.  Perhaps we could do something in this area for v20.  Or
perhaps not.
--
Michael


Attachments:

  [application/pgp-signature] signature.asc (833B, 2-signature.asc)
  download

^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 23:02                                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
@ 2026-03-17 02:05                                                           ` Corey Huinker <[email protected]>
  2026-03-17 14:26                                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Corey Huinker @ 2026-03-17 02:05 UTC (permalink / raw)
  To: Michael Paquier <[email protected]>; +Cc: Nathan Bossart <[email protected]>; Sami Imseih <[email protected]>; [email protected]

>
> Makes sense here to keep it simple.  I don't want to change the
> extstat restore code more than necessary at this stage of the CF
> calendar cycle, except for bugs and issues discussed during the beta
> cycle.


+1. I've also not advocated any changes to the extstat dump/restore code,
and I doubt I would until we start needing to fetch them in batches.


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 23:02                                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-17 02:05                                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-03-17 14:26                                                             ` Nathan Bossart <[email protected]>
  2026-03-17 15:01                                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-17 14:26 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Michael Paquier <[email protected]>; Sami Imseih <[email protected]>; [email protected]

Committed the next patch in the series.  I'll have a rebased version of the
last one ready to share soon.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 23:02                                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-17 02:05                                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-17 14:26                                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-17 15:01                                                               ` Nathan Bossart <[email protected]>
  2026-03-17 16:34                                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 36+ messages in thread

From: Nathan Bossart @ 2026-03-17 15:01 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Michael Paquier <[email protected]>; Sami Imseih <[email protected]>; [email protected]

On Tue, Mar 17, 2026 at 09:26:57AM -0500, Nathan Bossart wrote:
> Committed the next patch in the series.  I'll have a rebased version of the
> last one ready to share soon.

As promised...

-- 
nathan


^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:16 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-02 04:03   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-04 22:54     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 20:40       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-05 20:45         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-05 21:40           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-06 23:08             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-06 23:19               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 15:44                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 15:51                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 18:29                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 18:56                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-09 19:28                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-09 21:04                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-09 22:42                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-10 16:37                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-10 16:42                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 20:16                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-12 21:08                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-12 23:54                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-13 15:38                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Sami Imseih <[email protected]>
  2026-03-13 20:07                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-14 21:13                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 19:19                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 20:04                                                 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-16 20:15                                                   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 21:49                                                     ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-16 22:52                                                       ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-16 23:02                                                         ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Michael Paquier <[email protected]>
  2026-03-17 02:05                                                           ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-03-17 14:26                                                             ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
  2026-03-17 15:01                                                               ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Nathan Bossart <[email protected]>
@ 2026-03-17 16:34                                                                 ` Nathan Bossart <[email protected]>
  0 siblings, 0 replies; 36+ messages in thread

From: Nathan Bossart @ 2026-03-17 16:34 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: Michael Paquier <[email protected]>; Sami Imseih <[email protected]>; [email protected]

On Tue, Mar 17, 2026 at 10:01:42AM -0500, Nathan Bossart wrote:
> On Tue, Mar 17, 2026 at 09:26:57AM -0500, Nathan Bossart wrote:
>> Committed the next patch in the series.  I'll have a rebased version of the
>> last one ready to share soon.
> 
> As promised...

Committed.

-- 
nathan





^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
@ 2026-02-26 20:36 ` Tom Lane <[email protected]>
  2026-03-02 05:18   ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  1 sibling, 1 reply; 36+ messages in thread

From: Tom Lane @ 2026-02-26 20:36 UTC (permalink / raw)
  To: Corey Huinker <[email protected]>; +Cc: [email protected]; [email protected]

Corey Huinker <[email protected]> writes:
> Per side conversation in [1], this patch exposes pg_statistic.starelid in
> the pg_stats view (0001) and then changes pg_dump to use the starelid in
> the queries on pg_stats rather than the combination of schemaname+relname,

I don't object to the idea, but I don't like exposing the name
"starelid".  That just screams implementation artifact, and it
goes against the idea that pg_stats is trying to hide the physical
representation of pg_statistic.  I wish we could use "tableoid",
but that's taken already as a system column.  Maybe "tableid" or
"tablerelid"?

Also, the proposed column ordering seems excessively random:

        n.nspname AS schemaname,
        c.relname AS tablename,
        s.starelid AS starelid,
        a.attnum AS attnum,
        a.attname AS attname,
        stainherit AS inherited,

I could see either of these as plausible:

        n.nspname AS schemaname,
        c.relname AS tablename,
        s.starelid AS tableid,
        a.attname AS attname,
        a.attnum AS attnum,
        stainherit AS inherited,

        n.nspname AS schemaname,
        c.relname AS tablename,
        a.attname AS attname,
        s.starelid AS tableid,
        a.attnum AS attnum,
        stainherit AS inherited,

but I don't see the rationale behind your version.

			regards, tom lane






^ permalink  raw  reply  [nested|flat] 36+ messages in thread

* Re: Add starelid, attnum to pg_stats and leverage this in pg_dump
  2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
  2026-02-26 20:36 ` Re: Add starelid, attnum to pg_stats and leverage this in pg_dump Tom Lane <[email protected]>
@ 2026-03-02 05:18   ` Corey Huinker <[email protected]>
  0 siblings, 0 replies; 36+ messages in thread

From: Corey Huinker @ 2026-03-02 05:18 UTC (permalink / raw)
  To: Tom Lane <[email protected]>; +Cc: [email protected]; [email protected]

>
> I don't object to the idea, but I don't like exposing the name
> "starelid".  That just screams implementation artifact, and it
> goes against the idea that pg_stats is trying to hide the physical
> representation of pg_statistic.  I wish we could use "tableoid",
> but that's taken already as a system column.  Maybe "tableid" or
> "tablerelid"?
>

I went with tableid, as it pairs with tablename, and at least they're
inaccurate in the same way.


>
> Also, the proposed column ordering seems excessively random:
>
>         n.nspname AS schemaname,
>         c.relname AS tablename,
>         s.starelid AS starelid,
>         a.attnum AS attnum,
>         a.attname AS attname,
>         stainherit AS inherited,
>
> I could see either of these as plausible:
>
>         n.nspname AS schemaname,
>         c.relname AS tablename,
>         s.starelid AS tableid,
>         a.attname AS attname,
>         a.attnum AS attnum,
>         stainherit AS inherited,
>
>         n.nspname AS schemaname,
>         c.relname AS tablename,
>         a.attname AS attname,
>         s.starelid AS tableid,
>         a.attnum AS attnum,
>         stainherit AS inherited,
>
> but I don't see the rationale behind your version.
>

The rationale went like this:

In order to get the grain of this table you need:
    (  (schemaname AND tablename) OR tableid )
    AND
    (attnum OR attname)
    AND
    inherited

As I stated earlier, I don't think there's a way to "win" with the column
ordering here, any ordering we choose will look awkward to at least one use
case. Your first suggestion seems fine to me, so I'm going with that one in
this round.


Attachments:

  [text/x-patch] v2-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch (76.7K, 3-v2-0001-Add-tableid-and-attnum-columns-to-pg_stats.patch)
  download | inline diff:
From aec84aefb0dc524a7781ec9678f7a61da09f161a Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Tue, 24 Feb 2026 16:12:55 -0500
Subject: [PATCH v2 1/2] Add tableid and attnum columns to pg_stats.

The primary purpose of this patch is to expose the starelid column of
pg_statistic in the pg_stats view. Having this available will allow us
to simplify some code in pg_dump which currently has to store arrays of
nspname+relname in order to fetch a resonable amount of statistics in
one query. Furthermore, the query used in pg_dump requires a redundant
qual in the WHERE clause to ensure that it uses a specific index, thus
avoiding a hash join and the expensive sequential scan of pg_statistic
that that entails.

Additionally, there have been times when it would have been nice to have
attnum as well as attname available.
---
 src/backend/catalog/system_views.sql       |   8 +-
 src/test/regress/expected/rules.out        |   2 +
 src/test/regress/expected/stats_import.out | 288 ++++++++++++++-------
 src/test/regress/sql/stats_import.sql      | 144 +++++++++--
 doc/src/sgml/system-views.sgml             |  20 ++
 5 files changed, 339 insertions(+), 123 deletions(-)

diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 1ea8f1faa9e..014998dc380 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -184,9 +184,11 @@ CREATE VIEW pg_sequences AS
 
 CREATE VIEW pg_stats WITH (security_barrier) AS
     SELECT
-        nspname AS schemaname,
-        relname AS tablename,
-        attname AS attname,
+        n.nspname AS schemaname,
+        c.relname AS tablename,
+        a.attrelid AS tableid,
+        a.attname AS attname,
+        a.attnum AS attnum,
         stainherit AS inherited,
         stanullfrac AS null_frac,
         stawidth AS avg_width,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 78a37d9fc8f..c34ef96ec95 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2513,7 +2513,9 @@ pg_statio_user_tables| SELECT relid,
   WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
 pg_stats| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
+    a.attrelid AS tableid,
     a.attname,
+    a.attnum,
     s.stainherit AS inherited,
     s.stanullfrac AS null_frac,
     s.stawidth AS avg_width,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index d6cc701500e..3090cc6aac8 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -488,15 +488,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -515,15 +519,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: unrecognized argument name, rest get set
@@ -540,15 +548,19 @@ WARNING:  unrecognized argument name: "nope"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 1, rest get set
@@ -566,15 +578,19 @@ WARNING:  argument "most_common_vals" must be specified when argument "most_comm
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv / mcf null mismatch part 2, rest get set
@@ -592,15 +608,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcf type mismatch, mcv-pair fails, rest get set
@@ -620,15 +640,19 @@ WARNING:  argument "most_common_freqs" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcv cast failure, mcv-pair fails, rest get set
@@ -647,15 +671,19 @@ WARNING:  invalid input syntax for type integer: "four"
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -672,15 +700,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: NULL in histogram array, rest get set
@@ -698,15 +730,19 @@ WARNING:  "histogram_bounds" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -722,15 +758,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: elem_count_histogram null element, rest get set
@@ -748,15 +788,19 @@ WARNING:  argument "elem_count_histogram" array must not contain null values
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -773,15 +817,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.26 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: range stats on a scalar type, rest ok
@@ -801,15 +849,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.27 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch, rest ok
@@ -827,15 +879,19 @@ WARNING:  argument "range_empty_frac" must be specified when argument "range_len
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
@@ -853,15 +909,19 @@ WARNING:  argument "range_length_histogram" must be specified when argument "ran
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -878,15 +938,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
 -- warn: range bounds histogram on scalar, rest ok
@@ -905,15 +969,19 @@ DETAIL:  Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUN
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.31 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_bounds_histogram
@@ -929,15 +997,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: cannot set most_common_elems for range type, rest ok
@@ -957,15 +1029,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test      | arange  | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac |        range_bounds_histogram        
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test      | arange  |      4 | f         |      0.32 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
 (1 row)
 
 -- warn: scalars can't have mcelem, rest ok
@@ -985,15 +1061,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.33 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem mismatch, rest ok
@@ -1011,15 +1091,19 @@ WARNING:  argument "most_common_elem_freqs" must be specified when argument "mos
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.34 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: mcelem / mcelem null mismatch part 2, rest ok
@@ -1037,15 +1121,19 @@ WARNING:  argument "most_common_elems" must be specified when argument "most_com
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- ok: mcelem
@@ -1062,15 +1150,19 @@ SELECT pg_catalog.pg_restore_attribute_stats(
  t
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test      | tags    | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs |                                                                                            elem_count_histogram                                                                                             | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test      | tags    |      5 | f         |      0.35 |         0 |          0 |                  |                   |                  |             | {one,three}       | {0.3,0.2,0.2,0.3,0}    | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
 (1 row)
 
 -- warn: scalars can't have elem_count_histogram, rest ok
@@ -1089,15 +1181,19 @@ DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
  f
 (1 row)
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
-  schemaname  | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+  schemaname  | tablename | attname | attnum | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram 
+--------------+-----------+---------+--------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test      | id      |      1 | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- test for multiranges
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 8db7cd93b88..d59d45c11b0 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -368,7 +368,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'avg_width', 5::integer,
     'n_distinct', 0.6::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -387,7 +391,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'inherited', false::boolean,
     'null_frac', 0.4::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -403,7 +411,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'null_frac', 0.2::real,
     'nope', 0.5::real);
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -420,7 +432,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -437,7 +453,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_vals', '{1,2,3}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -455,7 +475,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -473,7 +497,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -490,7 +518,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -507,7 +539,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -523,7 +559,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'histogram_bounds', '{1,2,3,4}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -540,7 +580,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -557,7 +601,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -575,7 +623,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -592,7 +644,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -609,7 +665,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_empty_frac', 0.5::real
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -626,7 +686,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -643,7 +707,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -659,7 +727,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -677,7 +749,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -695,7 +771,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -712,7 +792,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elems', '{one,two}'::text
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -729,7 +813,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -746,7 +834,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
@@ -763,7 +855,11 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
-SELECT *
+SELECT schemaname, tablename, attname, attnum, inherited, null_frac, avg_width,
+    n_distinct, most_common_vals, most_common_freqs, histogram_bounds,
+    correlation, most_common_elems, most_common_elem_freqs,
+    elem_count_histogram, range_length_histogram, range_empty_frac,
+    range_bounds_histogram
 FROM pg_stats
 WHERE schemaname = 'stats_import'
 AND tablename = 'test'
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index e5fe423fc61..51afd3002bf 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -4414,6 +4414,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>starelid</structfield> <type>tableid</type>
+       (references <link linkend="catalog-pg-class"><structname>pg_attribute</structname></link>.<structfield>attrelid</structfield>)
+      </para>
+      <para>
+       ID of the table
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attname</structfield> <type>name</type>
@@ -4424,6 +4434,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>attnum</structfield> <type>int2</type>
+       (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+      </para>
+      <para>
+       Position of column described by this row
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>inherited</structfield> <type>bool</type>

base-commit: 2176520089e8c78a2eadb693670f65eaabf8ede2
-- 
2.53.0



  [text/x-patch] v2-0002-pg_dump-Use-tableid-in-getAttributeStats.patch (8.0K, 4-v2-0002-pg_dump-Use-tableid-in-getAttributeStats.patch)
  download | inline diff:
From 64d195fb0d98bedd9607e39947f36db54215f025 Mon Sep 17 00:00:00 2001
From: Corey Huinker <[email protected]>
Date: Wed, 25 Feb 2026 15:56:14 -0500
Subject: [PATCH v2 2/2] pg_dump: Use tableid in getAttributeStats

The existing query for fetching attribute stats is clumsy for several
reasons. One is that the volume of stats returned is unpredictable and
could be very large, so stats must be fetched in medium-sized batches.
The other is that the stats fetching query is on pg_stats, which
historically does not expose tableid, requiring us to pass in an array
of schemanames and an array of tablenames and unnest them in pairs. This
results in a hash join which gives very poor performance, but adding an
extra qual was able to trick the query into using an existing index.
That trick always seems brittle because it is, and while it works on all
past versions, there is no guarantee that it will continue to work on
future versions.

With that in mind, change the pg_dump query to instead use tableid on
versions in which tableid is available in pg_stats. This virtually
guarantees that pg_statistic will use index lookups, eliminates the
"trick" qual mentioned above, and is just simpler.
---
 src/bin/pg_dump/pg_dump.c | 102 +++++++++++++++++++++++++++++++-------
 src/bin/pg_dump/pg_dump.h |   1 +
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index dd8adef0a3e..a34ea1f3325 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -7137,6 +7137,7 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 		dobj->components |= DUMP_COMPONENT_STATISTICS;
 		dobj->name = pg_strdup(rel->name);
 		dobj->namespace = rel->namespace;
+		info->starelid = rel->catId.oid;
 		info->relpages = relpages;
 		info->reltuples = pstrdup(reltuples);
 		info->relallvisible = relallvisible;
@@ -11031,8 +11032,9 @@ static PGresult *
 fetchAttributeStats(Archive *fout)
 {
 	ArchiveHandle *AH = (ArchiveHandle *) fout;
-	PQExpBuffer nspnames = createPQExpBuffer();
-	PQExpBuffer relnames = createPQExpBuffer();
+	PQExpBuffer nspnames = NULL;
+	PQExpBuffer relnames = NULL;
+	PQExpBuffer starelids = NULL;
 	int			count = 0;
 	PGresult   *res = NULL;
 	static TocEntry *te;
@@ -11066,8 +11068,18 @@ fetchAttributeStats(Archive *fout)
 		restarted = true;
 	}
 
-	appendPQExpBufferChar(nspnames, '{');
-	appendPQExpBufferChar(relnames, '{');
+	if (fout->remoteVersion >= 190000)
+	{
+		starelids = createPQExpBuffer();
+		appendPQExpBufferChar(starelids, '{');
+	}
+	else
+	{
+		nspnames = createPQExpBuffer();
+		relnames = createPQExpBuffer();
+		appendPQExpBufferChar(nspnames, '{');
+		appendPQExpBufferChar(relnames, '{');
+	}
 
 	/*
 	 * Scan the TOC for the next set of relevant stats entries.  We assume
@@ -11080,14 +11092,35 @@ fetchAttributeStats(Archive *fout)
 		if ((te->reqs & REQ_STATS) != 0 &&
 			strcmp(te->desc, "STATISTICS DATA") == 0)
 		{
-			appendPGArray(nspnames, te->namespace);
-			appendPGArray(relnames, te->tag);
+			if (fout->remoteVersion >= 190000)
+			{
+				RelStatsInfo *rsinfo = (RelStatsInfo *) te->defnDumperArg;
+
+				if (rsinfo == NULL)
+					pg_fatal("statistics table oid information missing for %s.%s",
+							 te->namespace, te->tag);
+
+				if (count > 0)
+					appendPQExpBufferChar(starelids, ',');
+				appendPQExpBuffer(starelids, "%u", rsinfo->starelid);
+			}
+			else
+			{
+				appendPGArray(nspnames, te->namespace);
+				appendPGArray(relnames, te->tag);
+			}
+
 			count++;
 		}
 	}
 
-	appendPQExpBufferChar(nspnames, '}');
-	appendPQExpBufferChar(relnames, '}');
+	if (fout->remoteVersion >= 190000)
+		appendPQExpBufferChar(starelids, '}');
+	else
+	{
+		appendPQExpBufferChar(nspnames, '}');
+		appendPQExpBufferChar(relnames, '}');
+	}
 
 	/* Execute the query for the next batch of relations. */
 	if (count > 0)
@@ -11095,16 +11128,30 @@ fetchAttributeStats(Archive *fout)
 		PQExpBuffer query = createPQExpBuffer();
 
 		appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
-		appendStringLiteralAH(query, nspnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[],");
-		appendStringLiteralAH(query, relnames->data, fout);
-		appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		if (fout->remoteVersion >= 190000)
+		{
+			appendStringLiteralAH(query, starelids->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.oid[])");
+		}
+		else
+		{
+			appendStringLiteralAH(query, nspnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[],");
+			appendStringLiteralAH(query, relnames->data, fout);
+			appendPQExpBufferStr(query, "::pg_catalog.name[])");
+		}
+
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 		destroyPQExpBuffer(query);
 	}
 
-	destroyPQExpBuffer(nspnames);
-	destroyPQExpBuffer(relnames);
+	if (fout->remoteVersion >= 190000)
+		destroyPQExpBuffer(starelids);
+	else
+	{
+		destroyPQExpBuffer(nspnames);
+		destroyPQExpBuffer(relnames);
+	}
 	return res;
 }
 
@@ -11163,8 +11210,18 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 	query = createPQExpBuffer();
 	if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
 	{
+		/*
+		 * Before v19, the starelid was not available in pg_stats. Prior to
+		 * that we must identify tables with schemaname+relname.
+		 */
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.oid[]) AS\n");
+		else
+			appendPQExpBufferStr(query,
+								 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n");
+
 		appendPQExpBufferStr(query,
-							 "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
 							 "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
 							 "s.null_frac, s.avg_width, s.n_distinct, "
 							 "s.most_common_vals, s.most_common_freqs, "
@@ -11183,22 +11240,30 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "NULL AS range_empty_frac,"
 								 "NULL AS range_bounds_histogram ");
 
+		appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s ");
+
 		/*
 		 * The results must be in the order of the relations supplied in the
 		 * parameters to ensure we remain in sync as we walk through the TOC.
+		 *
 		 * The redundant filter clause on s.tablename = ANY(...) seems
 		 * 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.
+		 * This seems to work for all version prior to v19, after which we
+		 * will use the starelid, which is simpler.
 		 *
 		 * 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)
+		if (fout->remoteVersion >= 190000)
+			appendPQExpBufferStr(query,
+								 "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) "
+								 "ON s.tableid = u.tableid "
+								 "ORDER BY u.ord, s.attname, s.inherited");
+		else 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 "
@@ -11206,7 +11271,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
 								 "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");
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 6deceef23f3..1d6b215d6a5 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -448,6 +448,7 @@ typedef struct _indexAttachInfo
 typedef struct _relStatsInfo
 {
 	DumpableObject dobj;
+	Oid			starelid;
 	int32		relpages;
 	char	   *reltuples;
 	int32		relallvisible;
-- 
2.53.0



^ permalink  raw  reply  [nested|flat] 36+ messages in thread


end of thread, other threads:[~2026-03-17 16:34 UTC | newest]

Thread overview: 36+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-02-25 21:22 Add starelid, attnum to pg_stats and leverage this in pg_dump Corey Huinker <[email protected]>
2026-02-26 20:16 ` Sami Imseih <[email protected]>
2026-03-02 04:03   ` Corey Huinker <[email protected]>
2026-03-04 22:54     ` Sami Imseih <[email protected]>
2026-03-05 20:40       ` Corey Huinker <[email protected]>
2026-03-05 20:45         ` Sami Imseih <[email protected]>
2026-03-05 21:40           ` Corey Huinker <[email protected]>
2026-03-06 23:08             ` Nathan Bossart <[email protected]>
2026-03-06 23:19               ` Nathan Bossart <[email protected]>
2026-03-09 15:44                 ` Sami Imseih <[email protected]>
2026-03-09 15:51                   ` Nathan Bossart <[email protected]>
2026-03-09 18:29                     ` Corey Huinker <[email protected]>
2026-03-09 18:56                       ` Sami Imseih <[email protected]>
2026-03-09 19:28                         ` Corey Huinker <[email protected]>
2026-03-09 21:04                           ` Nathan Bossart <[email protected]>
2026-03-09 22:42                             ` Corey Huinker <[email protected]>
2026-03-10 16:37                               ` Nathan Bossart <[email protected]>
2026-03-10 16:42                                 ` Corey Huinker <[email protected]>
2026-03-12 20:16                                   ` Corey Huinker <[email protected]>
2026-03-12 21:08                                     ` Sami Imseih <[email protected]>
2026-03-12 23:54                                       ` Corey Huinker <[email protected]>
2026-03-13 15:38                                         ` Sami Imseih <[email protected]>
2026-03-13 20:07                                           ` Nathan Bossart <[email protected]>
2026-03-14 21:13                                             ` Corey Huinker <[email protected]>
2026-03-16 19:19                                               ` Nathan Bossart <[email protected]>
2026-03-16 20:04                                                 ` Corey Huinker <[email protected]>
2026-03-16 20:15                                                   ` Nathan Bossart <[email protected]>
2026-03-16 21:49                                                     ` Michael Paquier <[email protected]>
2026-03-16 22:52                                                       ` Nathan Bossart <[email protected]>
2026-03-16 23:02                                                         ` Michael Paquier <[email protected]>
2026-03-17 02:05                                                           ` Corey Huinker <[email protected]>
2026-03-17 14:26                                                             ` Nathan Bossart <[email protected]>
2026-03-17 15:01                                                               ` Nathan Bossart <[email protected]>
2026-03-17 16:34                                                                 ` Nathan Bossart <[email protected]>
2026-02-26 20:36 ` Tom Lane <[email protected]>
2026-03-02 05:18   ` Corey Huinker <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox