From f3087b04784d6853970bf41eb619281d72ce94bd Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Wed, 26 Feb 2025 21:02:44 -0500
Subject: [PATCH vTestReorg] Organize and deduplicate statistics import tests.

Many changes, refactorings, and rebasings have taken their toll on the
statistics import tests. Now that things appear more stable and the
pg_set_* functions are gone in favor of using pg_restore_* in all cases,
it's safe to remove duplicates, combine tests where possible, and make
the test descriptions a bit more descriptive and uniform.
---
 src/test/regress/expected/stats_import.out | 672 +++++++++------------
 src/test/regress/sql/stats_import.sql      | 546 +++++++----------
 2 files changed, 500 insertions(+), 718 deletions(-)

diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 1f150f7b08d..eaa3fe0f812 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -13,17 +13,58 @@ CREATE TABLE stats_import.test(
     tags text[]
 ) WITH (autovacuum_enabled = false);
 CREATE INDEX test_i ON stats_import.test(id);
+--
+-- relstats tests
+--
+--- error: relation is wrong type
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 0::oid,
+        'relpages', 17::integer,
+        'reltuples', 400.0::real,
+        'relallvisible', 4::integer);
+WARNING:  argument "relation" has type "oid", expected type "regclass"
+ERROR:  "relation" cannot be NULL
+-- error: relation not found
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 0::oid::regclass,
+        'relpages', 17::integer,
+        'reltuples', 400.0::real,
+        'relallvisible', 4::integer);
+ERROR:  could not open relation with OID 0
+-- error: odd number of variadic arguments cannot be pairs
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relpages', '17'::integer,
+        'reltuples', 400::real,
+        'relallvisible');
+ERROR:  variadic arguments must be name/value pairs
+HINT:  Provide an even number of variadic arguments that can be divided into pairs.
+-- error: argument name is NULL
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        NULL, '17'::integer,
+        'relallvisible', 14::integer);
+ERROR:  name at variadic position 5 is NULL
+-- error: argument name is not a text type
+SELECT pg_restore_relation_stats(
+        'relation', '0'::oid::regclass,
+        'version', 150000::integer,
+        17, '17'::integer,
+        'relallvisible', 44::integer);
+ERROR:  name at variadic position 5 has type "integer", expected type "text"
 -- starting stats
 SELECT relpages, reltuples, relallvisible
 FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
+WHERE oid = 'stats_import.test_i'::regclass;
  relpages | reltuples | relallvisible 
 ----------+-----------+---------------
-        0 |        -1 |             0
+        1 |         0 |             0
 (1 row)
 
-BEGIN;
 -- regular indexes have special case locking rules
+BEGIN;
 SELECT
     pg_catalog.pg_restore_relation_stats(
         'relation', 'stats_import.test_i'::regclass,
@@ -50,32 +91,6 @@ WHERE relation = 'stats_import.test_i'::regclass AND
 (1 row)
 
 COMMIT;
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.test_i'::regclass,
-        'relpages', 19::integer );
- pg_restore_relation_stats 
----------------------------
- t
-(1 row)
-
--- clear
-SELECT
-    pg_catalog.pg_clear_relation_stats(
-        'stats_import.test'::regclass);
- pg_clear_relation_stats 
--------------------------
- 
-(1 row)
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-        0 |        -1 |             0
-(1 row)
-
 --  relpages may be -1 for partitioned tables
 CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
 CREATE TABLE stats_import.part_child_1
@@ -92,26 +107,6 @@ WHERE oid = 'stats_import.part_parent'::regclass;
        -1
 (1 row)
 
--- although partitioned tables have no storage, setting relpages to a
--- positive value is still allowed
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent_i'::regclass,
-        'relpages', 2::integer);
- pg_restore_relation_stats 
----------------------------
- t
-(1 row)
-
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent'::regclass,
-        'relpages', 2::integer);
- pg_restore_relation_stats 
----------------------------
- t
-(1 row)
-
 --
 -- Partitioned indexes aren't analyzed but it is possible to set
 -- stats. The locking rules are different from normal indexes due to
@@ -145,30 +140,19 @@ WHERE relation = 'stats_import.part_parent_i'::regclass AND
 (1 row)
 
 COMMIT;
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent_i'::regclass,
-        'relpages', 2::integer);
- pg_restore_relation_stats 
----------------------------
- t
+SELECT relpages
+FROM pg_class
+WHERE oid = 'stats_import.part_parent_i'::regclass;
+ relpages 
+----------
+        2
 (1 row)
 
--- nothing stops us from setting it to -1
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent'::regclass,
-        'relpages', -1::integer);
- pg_restore_relation_stats 
----------------------------
- t
-(1 row)
-
--- ok: set all stats
+-- ok: set all stats, no bounds checking
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
-        'relpages', '17'::integer,
+        'relpages', '-17'::integer,
         'reltuples', 400::real,
         'relallvisible', 4::integer);
  pg_restore_relation_stats 
@@ -181,10 +165,10 @@ FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
  relpages | reltuples | relallvisible 
 ----------+-----------+---------------
-       17 |       400 |             4
+      -17 |       400 |             4
 (1 row)
 
--- ok: just relpages
+-- ok: set just relpages, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -202,7 +186,7 @@ WHERE oid = 'stats_import.test'::regclass;
        16 |       400 |             4
 (1 row)
 
--- ok: just reltuples
+-- ok: set just reltuples, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -220,7 +204,7 @@ WHERE oid = 'stats_import.test'::regclass;
        16 |       500 |             4
 (1 row)
 
--- ok: just relallvisible
+-- ok: set just relallvisible, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -238,7 +222,7 @@ WHERE oid = 'stats_import.test'::regclass;
        16 |       500 |             5
 (1 row)
 
--- warn: bad relpages type
+-- warn: bad relpages type, rest updated
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -259,20 +243,136 @@ WHERE oid = 'stats_import.test'::regclass;
        16 |       400 |             4
 (1 row)
 
+-- unrecognized argument name, rest ok
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relpages', '171'::integer,
+        'nope', 10::integer);
+WARNING:  unrecognized argument name: "nope"
+ pg_restore_relation_stats 
+---------------------------
+ f
+(1 row)
+
+SELECT relpages, reltuples, relallvisible
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+ relpages | reltuples | relallvisible 
+----------+-----------+---------------
+      171 |       400 |             4
+(1 row)
+
+-- ok: clear stats
+SELECT pg_catalog.pg_clear_relation_stats(
+    relation => 'stats_import.test'::regclass);
+ pg_clear_relation_stats 
+-------------------------
+ 
+(1 row)
+
+SELECT relpages, reltuples, relallvisible
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+ relpages | reltuples | relallvisible 
+----------+-----------+---------------
+        0 |        -1 |             0
+(1 row)
+
 -- invalid relkinds for statistics
 CREATE SEQUENCE stats_import.testseq;
-CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
-SELECT
-    pg_catalog.pg_clear_relation_stats(
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 'stats_import.testseq'::regclass);
+ERROR:  cannot modify statistics for relation "testseq"
+DETAIL:  This operation is not supported for sequences.
+SELECT pg_catalog.pg_clear_relation_stats(
         'stats_import.testseq'::regclass);
 ERROR:  cannot modify statistics for relation "testseq"
 DETAIL:  This operation is not supported for sequences.
-SELECT
-    pg_catalog.pg_clear_relation_stats(
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 'stats_import.testview'::regclass);
+ERROR:  cannot modify statistics for relation "testview"
+DETAIL:  This operation is not supported for views.
+SELECT pg_catalog.pg_clear_relation_stats(
         'stats_import.testview'::regclass);
 ERROR:  cannot modify statistics for relation "testview"
 DETAIL:  This operation is not supported for views.
--- ok: no stakinds
+--
+-- attribute stats
+--
+-- error: object does not exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', '0'::oid::regclass,
+    'attname', 'id'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  could not open relation with OID 0
+-- error: relation null
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', NULL::oid::regclass,
+    'attname', 'id'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  "relation" cannot be NULL
+-- error: NULL attname
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', NULL::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  must specify either attname or attnum
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'nope'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real,
+    'avg_width', 2::integer,
+    'n_distinct', 0.3::real);
+ERROR:  column "nope" of relation "test" does not exist
+-- error: both attname and attnum
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'id'::name,
+    'attnum', 1::smallint,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  cannot specify both attname and attnum
+-- error: neither attname nor attnum
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  must specify either attname or attnum
+-- error: attribute is system column
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'xmin'::name,
+    'inherited', false::boolean,
+    'null_frac', 0.1::real);
+ERROR:  cannot modify statistics on system column "xmin"
+-- error: inherited null
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'id'::name,
+    'inherited', NULL::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+ERROR:  "inherited" cannot be NULL
+-- error: attribute is system column
+SELECT pg_catalog.pg_clear_attribute_stats(
+    relation => 'stats_import.test'::regclass,
+    attname => 'ctid'::name,
+    inherited => false::boolean);
+ERROR:  cannot clear statistics on system column "ctid"
+-- ok: just the fixed values, no stakinds
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
@@ -297,15 +397,17 @@ AND attname = 'id';
  stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- ok: restore by attnum
+--
+-- ok: restore by attnum, we normally reserve this for
+-- indexes, but there is no reason it shouldn't work
+-- for any stat-having relation.
+--
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attnum', 1::smallint,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.4::real,
-    'avg_width', 5::integer,
-    'n_distinct', 0.6::real);
+    'null_frac', 0.4::real);
  pg_restore_attribute_stats 
 ----------------------------
  t
@@ -322,14 +424,13 @@ AND attname = 'id';
  stats_import | test      | id      | f         |       0.4 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: unrecognized argument name
+-- warn: unrecognized argument name, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
     'null_frac', 0.2::real,
-    'avg_width', NULL::integer,
     'nope', 0.5::real);
 WARNING:  unrecognized argument name: "nope"
  pg_restore_attribute_stats 
@@ -348,15 +449,13 @@ AND attname = 'id';
  stats_import | test      | id      | f         |       0.2 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: mcv / mcf null mismatch part 1
+-- warn: mcv / mcf null mismatch part 1, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.6::real,
-    'avg_width', 7::integer,
-    'n_distinct', -0.7::real,
+    'null_frac', 0.21::real,
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 WARNING:  "most_common_vals" must be specified when "most_common_freqs" is specified
@@ -373,18 +472,16 @@ 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.6 |         7 |       -0.7 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: mcv / mcf null mismatch part 2
+-- warn: mcv / mcf null mismatch part 2, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.7::real,
-    'avg_width', 8::integer,
-    'n_distinct', -0.8::real,
+    'null_frac', 0.21::real,
     'most_common_vals', '{1,2,3}'::text
     );
 WARNING:  "most_common_freqs" must be specified when "most_common_vals" is specified
@@ -401,18 +498,16 @@ 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.7 |         8 |       -0.8 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.21 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: mcv / mcf type mismatch
+-- warn: mcf type mismatch, mcv-pair fails, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.8::real,
-    'avg_width', 9::integer,
-    'n_distinct', -0.9::real,
+    'null_frac', 0.22::real,
     'most_common_vals', '{2,1,3}'::text,
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
@@ -431,18 +526,16 @@ 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.8 |         9 |       -0.9 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.22 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: mcv cast failure
+-- warn: mcv cast failure, mcv-pair fails, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.9::real,
-    'avg_width', 10::integer,
-    'n_distinct', -0.4::real,
+    'null_frac', 0.23::real,
     'most_common_vals', '{2,four,3}'::text,
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
@@ -460,7 +553,7 @@ 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.9 |        10 |       -0.4 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.23 |         5 |        0.6 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: mcv+mcf
@@ -469,9 +562,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 1::integer,
-    'n_distinct', -0.1::real,
     'most_common_vals', '{2,1,3}'::text,
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
@@ -488,18 +578,16 @@ 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.1 |         1 |       -0.1 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.23 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: NULL in histogram array
+-- warn: NULL in histogram array, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.2::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.2::real,
+    'null_frac', 0.24::real,
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 WARNING:  "histogram_bounds" array cannot contain NULL values
@@ -516,7 +604,7 @@ 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 |         2 |       -0.2 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | id      | f         |      0.24 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: histogram_bounds
@@ -525,10 +613,8 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.3::real,
-    'avg_width', 3::integer,
-    'n_distinct', -0.3::real,
-    'histogram_bounds', '{1,2,3,4}'::text );
+    'histogram_bounds', '{1,2,3,4}'::text
+    );
  pg_restore_attribute_stats 
 ----------------------------
  t
@@ -542,19 +628,17 @@ 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.3 |         3 |       -0.3 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | 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
+-- warn: elem_count_histogram null element, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.4::real,
-    'avg_width', 5::integer,
-    'n_distinct', -0.4::real,
-    'elem_count_histogram', '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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[]
+    'null_frac', 0.25::real,
+    'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 WARNING:  "elem_count_histogram" array cannot contain NULL values
  pg_restore_attribute_stats 
@@ -570,7 +654,7 @@ 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.4 |         5 |       -0.4 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | tags    | f         |      0.25 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: elem_count_histogram
@@ -579,9 +663,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'tags'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.5::real,
-    'avg_width', 6::integer,
-    'n_distinct', -0.55::real,
+    'null_frac', 0.26::real,
     '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[]
     );
  pg_restore_attribute_stats 
@@ -597,18 +679,16 @@ 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.5 |         6 |      -0.55 |                  |                   |                  |             |                   |                        | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} |                        |                  | 
+ 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} |                        |                  | 
 (1 row)
 
--- range stats on a scalar type
+-- warn: range stats on a scalar type, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.6::real,
-    'avg_width', 7::integer,
-    'n_distinct', -0.15::real,
+    'null_frac', 0.27::real,
     'range_empty_frac', 0.5::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
@@ -627,18 +707,16 @@ 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.6 |         7 |      -0.15 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | 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
+-- warn: range_empty_frac range_length_hist null mismatch, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.7::real,
-    'avg_width', 8::integer,
-    'n_distinct', -0.25::real,
+    'null_frac', 0.28::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 WARNING:  "range_empty_frac" must be specified when "range_length_histogram" is specified
@@ -655,18 +733,16 @@ 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.7 |         8 |      -0.25 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | arange  | f         |      0.28 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
--- warn: range_empty_frac range_length_hist null mismatch part 2
+-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.8::real,
-    'avg_width', 9::integer,
-    'n_distinct', -0.35::real,
+    'null_frac', 0.29::real,
     'range_empty_frac', 0.5::real
     );
 WARNING:  "range_length_histogram" must be specified when "range_empty_frac" is specified
@@ -683,7 +759,7 @@ 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.8 |         9 |      -0.35 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 -- ok: range_empty_frac + range_length_hist
@@ -692,9 +768,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.9::real,
-    'avg_width', 1::integer,
-    'n_distinct', -0.19::real,
     'range_empty_frac', 0.5::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
@@ -711,18 +784,16 @@ 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.9 |         1 |      -0.19 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
+ stats_import | test      | arange  | f         |      0.29 |         0 |          0 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | 
 (1 row)
 
--- warn: range bounds histogram on scalar
+-- warn: range bounds histogram on scalar, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.29::real,
+    'null_frac', 0.31::real,
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 WARNING:  attribute "id" is not a range type
@@ -740,7 +811,7 @@ 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.1 |         2 |      -0.29 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | 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
@@ -749,9 +820,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.2::real,
-    'avg_width', 3::integer,
-    'n_distinct', -0.39::real,
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
  pg_restore_attribute_stats 
@@ -767,26 +835,17 @@ 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.2 |         3 |      -0.39 |                  |                   |                  |             |                   |                        |                      | {399,499,Infinity}     |              0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+ stats_import | test      | 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
+-- warn: cannot set most_common_elems for range type, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text,
-    'most_common_freqs', '{0.3,0.25,0.05}'::real[],
-    'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
-    'correlation', 1.1::real,
+    'null_frac', 0.32::real,
     'most_common_elems', '{3,1}'::text,
-    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
-    'range_empty_frac', -0.5::real,
-    'range_length_histogram', '{399,499,Infinity}'::text,
-    'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
+    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 WARNING:  unable to determine element type of attribute "arange"
 DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
@@ -801,19 +860,17 @@ 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.5 |         2 |       -0.1 | {"[2,3)","[1,2)","[3,4)"} | {0.3,0.25,0.05}   | {"[1,2)","[2,3)","[3,4)","[4,5)"} |         1.1 |                   |                        |                      | {399,499,Infinity}     |             -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+  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)"}
 (1 row)
 
--- warn: scalars can't have mcelem
+-- warn: scalars can't have mcelem, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.33::real,
     'most_common_elems', '{1,3}'::text,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
@@ -832,17 +889,15 @@ 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.5 |         2 |       -0.1 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
+ stats_import | test      | 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
+-- warn: mcelem / mcelem mismatch, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.34::real,
     'most_common_elems', '{one,two}'::text
     );
 WARNING:  "most_common_elem_freqs" must be specified when "most_common_elems" is specified
@@ -859,17 +914,15 @@ 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.5 |         2 |       -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} |                        |                  | 
+ 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} |                        |                  | 
 (1 row)
 
--- warn: mcelem / mcelem null mismatch part 2
+-- warn: mcelem / mcelem null mismatch part 2, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.35::real,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 WARNING:  "most_common_elems" must be specified when "most_common_elem_freqs" is specified
@@ -878,14 +931,22 @@ WARNING:  "most_common_elems" must be specified when "most_common_elem_freqs" is
  f
 (1 row)
 
+SELECT *
+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} |                        |                  | 
+(1 row)
+
 -- ok: mcelem
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
     'most_common_elems', '{one,three}'::text,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
@@ -902,18 +963,16 @@ 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.5 |         2 |       -0.1 |                  |                   |                  |             | {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} |                        |                  | 
+ 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} |                        |                  | 
 (1 row)
 
--- warn: scalars can't have elem_count_histogram
+-- warn: scalars can't have elem_count_histogram, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    '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[]
+    'null_frac', 0.36::real,
+    'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 WARNING:  unable to determine element type of attribute "id"
 DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
@@ -930,43 +989,7 @@ 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.5 |         2 |       -0.1 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
-(1 row)
-
--- warn: too many stat kinds
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'arange'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    'most_common_vals', '{"[2,3)","[1,3)","[3,9)"}'::text,
-    'most_common_freqs', '{0.3,0.25,0.05}'::real[],
-    'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,)"}'::text,
-    'correlation', 1.1::real,
-    'most_common_elems', '{3,1}'::text,
-    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
-    'range_empty_frac', -0.5::real,
-    'range_length_histogram', '{399,499,Infinity}'::text,
-    'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text);
-WARNING:  unable to determine element type of attribute "arange"
-DETAIL:  Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
- pg_restore_attribute_stats 
-----------------------------
- f
-(1 row)
-
-SELECT *
-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.5 |         2 |       -0.1 | {"[2,3)","[1,3)","[3,9)"} | {0.3,0.25,0.05}   | {"[1,2)","[2,3)","[3,4)","[4,)"} |         1.1 |                   |                        |                      | {399,499,Infinity}     |             -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+ stats_import | test      | id      | f         |      0.36 |         5 |        0.6 | {2,1,3}          | {0.3,0.25,0.05}   | {1,2,3,4}        |             |                   |                        |                      |                        |                  | 
 (1 row)
 
 --
@@ -986,19 +1009,6 @@ SELECT 3, 'tre', (3, 3.3, 'TRE', '2003-03-03', NULL)::stats_import.complex_type,
 UNION ALL
 SELECT 4, 'four', NULL, int4range(0,100), NULL;
 CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1));
--- restoring stats on index
-SELECT * FROM pg_catalog.pg_restore_relation_stats(
-    'relation', 'stats_import.is_odd'::regclass,
-    'version', '180000'::integer,
-    'relpages', '11'::integer,
-    'reltuples', '10000'::real,
-    'relallvisible', '0'::integer
-);
- pg_restore_relation_stats 
----------------------------
- t
-(1 row)
-
 -- Generate statistics on table with data
 ANALYZE stats_import.test;
 CREATE TABLE stats_import.test_clone ( LIKE stats_import.test )
@@ -1176,7 +1186,18 @@ WHERE s.starelid = 'stats_import.is_odd'::regclass;
 ---------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
 (0 rows)
 
--- ok
+-- attribute stats exist before a clear, but not after
+SELECT COUNT(*)
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+ count 
+-------
+     1
+(1 row)
+
 SELECT pg_catalog.pg_clear_attribute_stats(
     relation => 'stats_import.test'::regclass,
     attname => 'arange'::name,
@@ -1186,154 +1207,17 @@ SELECT pg_catalog.pg_clear_attribute_stats(
  
 (1 row)
 
---
--- Negative tests
---
---- error: relation is wrong type
-SELECT pg_catalog.pg_restore_relation_stats(
-        'relation', 0::oid,
-        'relpages', 17::integer,
-        'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
-WARNING:  argument "relation" has type "oid", expected type "regclass"
-ERROR:  "relation" cannot be NULL
---- error: relation not found
-SELECT pg_catalog.pg_restore_relation_stats(
-        'relation', 0::regclass,
-        'relpages', 17::integer,
-        'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
-ERROR:  could not open relation with OID 0
--- warn and error: unrecognized argument name
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'nope', 4::integer);
-WARNING:  unrecognized argument name: "nope"
-ERROR:  could not open relation with OID 0
--- error: argument name is NULL
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        NULL, '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-ERROR:  name at variadic position 5 is NULL
--- error: argument name is an integer
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        17, '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-ERROR:  name at variadic position 5 has type "integer", expected type "text"
--- error: odd number of variadic arguments cannot be pairs
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible');
-ERROR:  variadic arguments must be name/value pairs
-HINT:  Provide an even number of variadic arguments that can be divided into pairs.
--- error: object doesn't exist
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-ERROR:  could not open relation with OID 0
--- error: object does not exist
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', '0'::oid::regclass,
-    'attname', 'id'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  could not open relation with OID 0
--- error: relation null
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', NULL::oid,
-    'attname', 'id'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  "relation" cannot be NULL
--- error: missing attname
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', NULL::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  must specify either attname or attnum
--- error: both attname and attnum
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'id'::name,
-    'attnum', 1::smallint,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  cannot specify both attname and attnum
--- error: attname doesn't exist
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'nope'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  column "nope" of relation "test" does not exist
--- error: attribute is system column
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'xmin'::name,
-    'inherited', false::boolean,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  cannot modify statistics on system column "xmin"
--- error: inherited null
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'id'::name,
-    'inherited', NULL::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-ERROR:  "inherited" cannot be NULL
--- error: relation not found
-SELECT pg_catalog.pg_clear_relation_stats(
-    relation => 'stats_import.nope'::regclass);
-ERROR:  relation "stats_import.nope" does not exist
-LINE 2:     relation => 'stats_import.nope'::regclass);
-                        ^
--- error: attribute is system column
-SELECT pg_catalog.pg_clear_attribute_stats(
-    relation => 'stats_import.test'::regclass,
-    attname => 'ctid'::name,
-    inherited => false::boolean);
-ERROR:  cannot clear statistics on system column "ctid"
--- error: attname doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
-    relation => 'stats_import.test'::regclass,
-    attname => 'nope'::name,
-    inherited => false::boolean);
-ERROR:  column "nope" of relation "test" does not exist
+SELECT COUNT(*)
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+ count 
+-------
+     0
+(1 row)
+
 DROP SCHEMA stats_import CASCADE;
 NOTICE:  drop cascades to 6 other objects
 DETAIL:  drop cascades to type stats_import.complex_type
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 8c183bceb8a..69e6cc960de 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -17,13 +17,53 @@ CREATE TABLE stats_import.test(
 
 CREATE INDEX test_i ON stats_import.test(id);
 
+--
+-- relstats tests
+--
+
+--- error: relation is wrong type
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 0::oid,
+        'relpages', 17::integer,
+        'reltuples', 400.0::real,
+        'relallvisible', 4::integer);
+
+-- error: relation not found
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 0::oid::regclass,
+        'relpages', 17::integer,
+        'reltuples', 400.0::real,
+        'relallvisible', 4::integer);
+
+-- error: odd number of variadic arguments cannot be pairs
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relpages', '17'::integer,
+        'reltuples', 400::real,
+        'relallvisible');
+
+-- error: argument name is NULL
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        NULL, '17'::integer,
+        'relallvisible', 14::integer);
+
+-- error: argument name is not a text type
+SELECT pg_restore_relation_stats(
+        'relation', '0'::oid::regclass,
+        'version', 150000::integer,
+        17, '17'::integer,
+        'relallvisible', 44::integer);
+
 -- starting stats
 SELECT relpages, reltuples, relallvisible
 FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
+WHERE oid = 'stats_import.test_i'::regclass;
 
-BEGIN;
 -- regular indexes have special case locking rules
+BEGIN;
 SELECT
     pg_catalog.pg_restore_relation_stats(
         'relation', 'stats_import.test_i'::regclass,
@@ -39,20 +79,6 @@ WHERE relation = 'stats_import.test_i'::regclass AND
 
 COMMIT;
 
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.test_i'::regclass,
-        'relpages', 19::integer );
-
--- clear
-SELECT
-    pg_catalog.pg_clear_relation_stats(
-        'stats_import.test'::regclass);
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
 --  relpages may be -1 for partitioned tables
 CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
 CREATE TABLE stats_import.part_child_1
@@ -68,18 +94,6 @@ SELECT relpages
 FROM pg_class
 WHERE oid = 'stats_import.part_parent'::regclass;
 
--- although partitioned tables have no storage, setting relpages to a
--- positive value is still allowed
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent_i'::regclass,
-        'relpages', 2::integer);
-
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent'::regclass,
-        'relpages', 2::integer);
-
 --
 -- Partitioned indexes aren't analyzed but it is possible to set
 -- stats. The locking rules are different from normal indexes due to
@@ -103,22 +117,15 @@ WHERE relation = 'stats_import.part_parent_i'::regclass AND
 
 COMMIT;
 
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent_i'::regclass,
-        'relpages', 2::integer);
+SELECT relpages
+FROM pg_class
+WHERE oid = 'stats_import.part_parent_i'::regclass;
 
--- nothing stops us from setting it to -1
-SELECT
-    pg_catalog.pg_restore_relation_stats(
-        'relation', 'stats_import.part_parent'::regclass,
-        'relpages', -1::integer);
-
--- ok: set all stats
+-- ok: set all stats, no bounds checking
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
-        'relpages', '17'::integer,
+        'relpages', '-17'::integer,
         'reltuples', 400::real,
         'relallvisible', 4::integer);
 
@@ -126,7 +133,7 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
--- ok: just relpages
+-- ok: set just relpages, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -136,7 +143,7 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
--- ok: just reltuples
+-- ok: set just reltuples, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -146,7 +153,7 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
--- ok: just relallvisible
+-- ok: set just relallvisible, rest stay same
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -156,7 +163,7 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
--- warn: bad relpages type
+-- warn: bad relpages type, rest updated
 SELECT pg_restore_relation_stats(
         'relation', 'stats_import.test'::regclass,
         'version', 150000::integer,
@@ -168,17 +175,118 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
+-- unrecognized argument name, rest ok
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relpages', '171'::integer,
+        'nope', 10::integer);
+
+SELECT relpages, reltuples, relallvisible
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+
+-- ok: clear stats
+SELECT pg_catalog.pg_clear_relation_stats(
+    relation => 'stats_import.test'::regclass);
+
+SELECT relpages, reltuples, relallvisible
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+
 -- invalid relkinds for statistics
 CREATE SEQUENCE stats_import.testseq;
-CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
-SELECT
-    pg_catalog.pg_clear_relation_stats(
+
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 'stats_import.testseq'::regclass);
+
+SELECT pg_catalog.pg_clear_relation_stats(
         'stats_import.testseq'::regclass);
-SELECT
-    pg_catalog.pg_clear_relation_stats(
+
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+
+SELECT pg_catalog.pg_restore_relation_stats(
+        'relation', 'stats_import.testview'::regclass);
+
+SELECT pg_catalog.pg_clear_relation_stats(
         'stats_import.testview'::regclass);
 
--- ok: no stakinds
+--
+-- attribute stats
+--
+
+-- error: object does not exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', '0'::oid::regclass,
+    'attname', 'id'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: relation null
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', NULL::oid::regclass,
+    'attname', 'id'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: NULL attname
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', NULL::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'nope'::name,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real,
+    'avg_width', 2::integer,
+    'n_distinct', 0.3::real);
+
+-- error: both attname and attnum
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'id'::name,
+    'attnum', 1::smallint,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: neither attname nor attnum
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'inherited', false::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: attribute is system column
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'xmin'::name,
+    'inherited', false::boolean,
+    'null_frac', 0.1::real);
+
+-- error: inherited null
+SELECT pg_catalog.pg_restore_attribute_stats(
+    'relation', 'stats_import.test'::regclass,
+    'attname', 'id'::name,
+    'inherited', NULL::boolean,
+    'version', 150000::integer,
+    'null_frac', 0.1::real);
+
+-- error: attribute is system column
+SELECT pg_catalog.pg_clear_attribute_stats(
+    relation => 'stats_import.test'::regclass,
+    attname => 'ctid'::name,
+    inherited => false::boolean);
+
+-- ok: just the fixed values, no stakinds
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
@@ -195,15 +303,17 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- ok: restore by attnum
+--
+-- ok: restore by attnum, we normally reserve this for
+-- indexes, but there is no reason it shouldn't work
+-- for any stat-having relation.
+--
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attnum', 1::smallint,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.4::real,
-    'avg_width', 5::integer,
-    'n_distinct', 0.6::real);
+    'null_frac', 0.4::real);
 
 SELECT *
 FROM pg_stats
@@ -212,14 +322,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: unrecognized argument name
+-- warn: unrecognized argument name, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
     'null_frac', 0.2::real,
-    'avg_width', NULL::integer,
     'nope', 0.5::real);
 
 SELECT *
@@ -229,15 +338,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: mcv / mcf null mismatch part 1
+-- warn: mcv / mcf null mismatch part 1, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.6::real,
-    'avg_width', 7::integer,
-    'n_distinct', -0.7::real,
+    'null_frac', 0.21::real,
     'most_common_freqs', '{0.1,0.2,0.3}'::real[]
     );
 
@@ -248,15 +355,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: mcv / mcf null mismatch part 2
+-- warn: mcv / mcf null mismatch part 2, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.7::real,
-    'avg_width', 8::integer,
-    'n_distinct', -0.8::real,
+    'null_frac', 0.21::real,
     'most_common_vals', '{1,2,3}'::text
     );
 
@@ -267,15 +372,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: mcv / mcf type mismatch
+-- warn: mcf type mismatch, mcv-pair fails, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.8::real,
-    'avg_width', 9::integer,
-    'n_distinct', -0.9::real,
+    'null_frac', 0.22::real,
     'most_common_vals', '{2,1,3}'::text,
     'most_common_freqs', '{0.2,0.1}'::double precision[]
     );
@@ -287,15 +390,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: mcv cast failure
+-- warn: mcv cast failure, mcv-pair fails, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.9::real,
-    'avg_width', 10::integer,
-    'n_distinct', -0.4::real,
+    'null_frac', 0.23::real,
     'most_common_vals', '{2,four,3}'::text,
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
@@ -313,9 +414,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 1::integer,
-    'n_distinct', -0.1::real,
     'most_common_vals', '{2,1,3}'::text,
     'most_common_freqs', '{0.3,0.25,0.05}'::real[]
     );
@@ -327,15 +425,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: NULL in histogram array
+-- warn: NULL in histogram array, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.2::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.2::real,
+    'null_frac', 0.24::real,
     'histogram_bounds', '{1,NULL,3,4}'::text
     );
 
@@ -352,10 +448,8 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.3::real,
-    'avg_width', 3::integer,
-    'n_distinct', -0.3::real,
-    'histogram_bounds', '{1,2,3,4}'::text );
+    'histogram_bounds', '{1,2,3,4}'::text
+    );
 
 SELECT *
 FROM pg_stats
@@ -364,16 +458,14 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: elem_count_histogram null element
+-- warn: elem_count_histogram null element, rest get set
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.4::real,
-    'avg_width', 5::integer,
-    'n_distinct', -0.4::real,
-    'elem_count_histogram', '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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[]
+    'null_frac', 0.25::real,
+    'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
     );
 
 SELECT *
@@ -389,9 +481,7 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'tags'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.5::real,
-    'avg_width', 6::integer,
-    'n_distinct', -0.55::real,
+    'null_frac', 0.26::real,
     '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[]
     );
 
@@ -402,15 +492,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
 
--- range stats on a scalar type
+-- warn: range stats on a scalar type, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.6::real,
-    'avg_width', 7::integer,
-    'n_distinct', -0.15::real,
+    'null_frac', 0.27::real,
     'range_empty_frac', 0.5::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
@@ -422,15 +510,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: range_empty_frac range_length_hist null mismatch
+-- warn: range_empty_frac range_length_hist null mismatch, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.7::real,
-    'avg_width', 8::integer,
-    'n_distinct', -0.25::real,
+    'null_frac', 0.28::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
 
@@ -441,15 +527,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
 
--- warn: range_empty_frac range_length_hist null mismatch part 2
+-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.8::real,
-    'avg_width', 9::integer,
-    'n_distinct', -0.35::real,
+    'null_frac', 0.29::real,
     'range_empty_frac', 0.5::real
     );
 
@@ -466,9 +550,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.9::real,
-    'avg_width', 1::integer,
-    'n_distinct', -0.19::real,
     'range_empty_frac', 0.5::real,
     'range_length_histogram', '{399,499,Infinity}'::text
     );
@@ -480,15 +561,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
 
--- warn: range bounds histogram on scalar
+-- warn: range bounds histogram on scalar, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.29::real,
+    'null_frac', 0.31::real,
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
@@ -505,9 +584,6 @@ SELECT pg_catalog.pg_restore_attribute_stats(
     'attname', 'arange'::name,
     'inherited', false::boolean,
     'version', 150000::integer,
-    'null_frac', 0.2::real,
-    'avg_width', 3::integer,
-    'n_distinct', -0.39::real,
     'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
     );
 
@@ -518,23 +594,14 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
 
--- warn: cannot set most_common_elems for range type
+-- warn: cannot set most_common_elems for range type, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'arange'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text,
-    'most_common_freqs', '{0.3,0.25,0.05}'::real[],
-    'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
-    'correlation', 1.1::real,
+    'null_frac', 0.32::real,
     'most_common_elems', '{3,1}'::text,
-    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
-    'range_empty_frac', -0.5::real,
-    'range_length_histogram', '{399,499,Infinity}'::text,
-    'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
+    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
 
 SELECT *
@@ -544,14 +611,12 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'arange';
 
--- warn: scalars can't have mcelem
+-- warn: scalars can't have mcelem, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.33::real,
     'most_common_elems', '{1,3}'::text,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
@@ -563,14 +628,12 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: mcelem / mcelem mismatch
+-- warn: mcelem / mcelem mismatch, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.34::real,
     'most_common_elems', '{one,two}'::text
     );
 
@@ -581,25 +644,27 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
 
--- warn: mcelem / mcelem null mismatch part 2
+-- warn: mcelem / mcelem null mismatch part 2, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
+    'null_frac', 0.35::real,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
     );
 
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'tags';
+
 -- ok: mcelem
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'tags'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
     'most_common_elems', '{one,three}'::text,
     'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
     );
@@ -611,15 +676,13 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'tags';
 
--- warn: scalars can't have elem_count_histogram
+-- warn: scalars can't have elem_count_histogram, rest ok
 SELECT pg_catalog.pg_restore_attribute_stats(
     'relation', 'stats_import.test'::regclass,
     'attname', 'id'::name,
     'inherited', false::boolean,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    '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[]
+    'null_frac', 0.36::real,
+    'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
     );
 
 SELECT *
@@ -629,32 +692,6 @@ AND tablename = 'test'
 AND inherited = false
 AND attname = 'id';
 
--- warn: too many stat kinds
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'arange'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.5::real,
-    'avg_width', 2::integer,
-    'n_distinct', -0.1::real,
-    'most_common_vals', '{"[2,3)","[1,3)","[3,9)"}'::text,
-    'most_common_freqs', '{0.3,0.25,0.05}'::real[],
-    'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,)"}'::text,
-    'correlation', 1.1::real,
-    'most_common_elems', '{3,1}'::text,
-    'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
-    'range_empty_frac', -0.5::real,
-    'range_length_histogram', '{399,499,Infinity}'::text,
-    'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text);
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'arange';
-
 --
 -- Test the ability to exactly copy data from one table to an identical table,
 -- correctly reconstructing the stakind order as well as the staopN and
@@ -674,15 +711,6 @@ SELECT 4, 'four', NULL, int4range(0,100), NULL;
 
 CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1));
 
--- restoring stats on index
-SELECT * FROM pg_catalog.pg_restore_relation_stats(
-    'relation', 'stats_import.is_odd'::regclass,
-    'version', '180000'::integer,
-    'relpages', '11'::integer,
-    'reltuples', '10000'::real,
-    'relallvisible', '0'::integer
-);
-
 -- Generate statistics on table with data
 ANALYZE stats_import.test;
 
@@ -835,154 +863,24 @@ FROM pg_statistic s
 JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
 WHERE s.starelid = 'stats_import.is_odd'::regclass;
 
--- ok
+-- attribute stats exist before a clear, but not after
+SELECT COUNT(*)
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+
 SELECT pg_catalog.pg_clear_attribute_stats(
     relation => 'stats_import.test'::regclass,
     attname => 'arange'::name,
     inherited => false::boolean);
 
---
--- Negative tests
---
-
---- error: relation is wrong type
-SELECT pg_catalog.pg_restore_relation_stats(
-        'relation', 0::oid,
-        'relpages', 17::integer,
-        'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
-
---- error: relation not found
-SELECT pg_catalog.pg_restore_relation_stats(
-        'relation', 0::regclass,
-        'relpages', 17::integer,
-        'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
-
--- warn and error: unrecognized argument name
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'nope', 4::integer);
-
--- error: argument name is NULL
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        NULL, '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-
--- error: argument name is an integer
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        17, '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-
--- error: odd number of variadic arguments cannot be pairs
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible');
-
--- error: object doesn't exist
-SELECT pg_restore_relation_stats(
-        'relation', '0'::oid::regclass,
-        'version', 150000::integer,
-        'relpages', '17'::integer,
-        'reltuples', 400::real,
-        'relallvisible', 4::integer);
-
--- error: object does not exist
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', '0'::oid::regclass,
-    'attname', 'id'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: relation null
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', NULL::oid,
-    'attname', 'id'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: missing attname
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', NULL::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: both attname and attnum
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'id'::name,
-    'attnum', 1::smallint,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: attname doesn't exist
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'nope'::name,
-    'inherited', false::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: attribute is system column
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'xmin'::name,
-    'inherited', false::boolean,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: inherited null
-SELECT pg_catalog.pg_restore_attribute_stats(
-    'relation', 'stats_import.test'::regclass,
-    'attname', 'id'::name,
-    'inherited', NULL::boolean,
-    'version', 150000::integer,
-    'null_frac', 0.1::real,
-    'avg_width', 2::integer,
-    'n_distinct', 0.3::real);
-
--- error: relation not found
-SELECT pg_catalog.pg_clear_relation_stats(
-    relation => 'stats_import.nope'::regclass);
-
--- error: attribute is system column
-SELECT pg_catalog.pg_clear_attribute_stats(
-    relation => 'stats_import.test'::regclass,
-    attname => 'ctid'::name,
-    inherited => false::boolean);
-
--- error: attname doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
-    relation => 'stats_import.test'::regclass,
-    attname => 'nope'::name,
-    inherited => false::boolean);
+SELECT COUNT(*)
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
 
 DROP SCHEMA stats_import CASCADE;

base-commit: 62ec3e1f6786181431210643a2d427b9a98b8af8
-- 
2.48.1

