/
githubmirror
/
postgres
Обзор
Документация
Войти
/
githubmirror
/
postgres
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/test/regress/expected/stats_import.out
3 713 строк
149 KB
Michael Paquier
Fix multirange type handling in pg_restore_attribute_stats()
10 авг 2026, 16:37
10 авг 2026, 16:37
5783593
Код
Авторство
О чём код?
CREATE SCHEMA stats_import; -- -- Convenience view for columns of pg_stats that are stable across test runs. -- CREATE VIEW stats_import.pg_stats_stable AS SELECT schemaname, tablename, attname, inherited, null_frac, avg_width, n_distinct, most_common_vals::text as most_common_vals, most_common_freqs, histogram_bounds::text AS histogram_bounds, correlation, most_common_elems::text AS most_common_elems, most_common_elem_freqs, elem_count_histogram, range_length_histogram::text AS range_length_histogram, range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram FROM pg_stats; -- -- Setup functions for set-difference convenience functions -- -- Test to detect any new columns added to pg_statistic. If any columns -- are added, we may need to update pg_statistic_flat() and the facilities -- we are testing. SELECT COUNT(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_statistic'::regclass AND attnum > 0; count ------- 31 (1 row) -- Create a view that is used purely for the type based on pg_statistic. CREATE VIEW stats_import.pg_statistic_flat_t AS SELECT a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, s.stavalues5::text AS sv5 FROM pg_statistic s JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum WHERE FALSE; -- Function to retrieve data used for diff comparisons between two -- relations based on the contents of pg_statistic. CREATE FUNCTION stats_import.pg_statistic_flat(p_relname text) RETURNS SETOF stats_import.pg_statistic_flat_t BEGIN ATOMIC SELECT a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, s.stavalues1::text, s.stavalues2::text, s.stavalues3::text, s.stavalues4::text, s.stavalues5::text FROM pg_statistic s JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum JOIN pg_class c ON c.oid = a.attrelid WHERE c.relnamespace = 'stats_import'::regnamespace AND c.relname = p_relname; END; -- Comparison function for pg_statistic. The two relations defined by -- the function caller are compared. CREATE FUNCTION stats_import.pg_statistic_get_difference(a text, b text) RETURNS TABLE (relname text, stats stats_import.pg_statistic_flat_t) BEGIN ATOMIC WITH aset AS (SELECT * FROM stats_import.pg_statistic_flat(a)), bset AS (SELECT * FROM stats_import.pg_statistic_flat(b)) SELECT a AS relname, a_minus_b::stats_import.pg_statistic_flat_t FROM (TABLE aset EXCEPT TABLE bset) AS a_minus_b UNION ALL SELECT b AS relname, b_minus_a::stats_import.pg_statistic_flat_t FROM (TABLE bset EXCEPT TABLE aset) AS b_minus_a; END; -- Test to detect any new columns added to pg_stats_ext. If any columns -- are added, we may need to update pg_stats_ext_flat() and the facilities -- we are testing. SELECT COUNT(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_stats_ext'::regclass AND attnum > 0; count ------- 17 (1 row) -- Create a view that is used purely for the type based on pg_stats_ext. CREATE VIEW stats_import.pg_stats_ext_flat_t AS SELECT inherited, n_distinct, dependencies, most_common_vals, most_common_freqs, most_common_base_freqs FROM pg_stats_ext WHERE FALSE; -- Function to retrieve data used for diff comparisons between two -- relations based on the contents of pg_stats_ext. CREATE FUNCTION stats_import.pg_stats_ext_flat(p_statname text) RETURNS SETOF stats_import.pg_stats_ext_flat_t BEGIN ATOMIC SELECT inherited, n_distinct, dependencies, most_common_vals, most_common_freqs, most_common_base_freqs FROM pg_stats_ext WHERE statistics_schemaname = 'stats_import' AND statistics_name = p_statname; END; -- Comparison function for pg_stats_ext. The two relations defined by -- the function caller are compared. CREATE FUNCTION stats_import.pg_stats_ext_get_difference(a text, b text) RETURNS TABLE (statname text, stats stats_import.pg_stats_ext_flat_t) BEGIN ATOMIC WITH aset AS (SELECT * FROM stats_import.pg_stats_ext_flat(a)), bset AS (SELECT * FROM stats_import.pg_stats_ext_flat(b)) SELECT a AS relname, a_minus_b::stats_import.pg_stats_ext_flat_t FROM (TABLE aset EXCEPT TABLE bset) AS a_minus_b UNION ALL SELECT b AS relname, b_minus_a::stats_import.pg_stats_ext_flat_t FROM (TABLE bset EXCEPT TABLE aset) AS b_minus_a; END; -- Test to detect any new columns added to pg_stats_ext_exprs. If any columns -- are added, we may need to update pg_stats_ext_exprs_flat() and the facilities -- we are testing. SELECT COUNT(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_stats_ext_exprs'::regclass AND attnum > 0; count ------- 22 (1 row) -- Create a view that is used purely for the type based on pg_stats_ext_exprs. CREATE VIEW stats_import.pg_stats_ext_exprs_flat_t AS SELECT inherited, null_frac, avg_width, n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs, histogram_bounds::text AS histogram_bounds, correlation, most_common_elems::text AS most_common_elems, most_common_elem_freqs, elem_count_histogram, range_length_histogram::text AS range_length_histogram, range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram FROM pg_stats_ext_exprs AS n WHERE FALSE; -- Function to retrieve data used for diff comparisons between two -- relations based on the contents of pg_stats_ext_exprs. CREATE FUNCTION stats_import.pg_stats_ext_exprs_flat(p_statname text) RETURNS SETOF stats_import.pg_stats_ext_exprs_flat_t BEGIN ATOMIC SELECT inherited, null_frac, avg_width, n_distinct, most_common_vals::text AS most_common_vals, most_common_freqs, histogram_bounds::text AS histogram_bounds, correlation, most_common_elems::text AS most_common_elems, most_common_elem_freqs, elem_count_histogram, range_length_histogram::text AS range_length_histogram, range_empty_frac, range_bounds_histogram::text AS range_bounds_histogram FROM pg_stats_ext_exprs AS n WHERE n.statistics_schemaname = 'stats_import' AND n.statistics_name = p_statname; END; -- Comparison function for pg_stats_ext_exprs. The two relations defined by -- the function caller are compared. CREATE FUNCTION stats_import.pg_stats_ext_exprs_get_difference(a text, b text) RETURNS TABLE (statname text, stats stats_import.pg_stats_ext_exprs_flat_t) BEGIN ATOMIC WITH aset AS (SELECT * FROM stats_import.pg_stats_ext_exprs_flat(a)), bset AS (SELECT * FROM stats_import.pg_stats_ext_exprs_flat(b)) SELECT a AS relname, a_minus_b::stats_import.pg_stats_ext_exprs_flat_t FROM (TABLE aset EXCEPT TABLE bset) AS a_minus_b UNION ALL SELECT b AS relname, b_minus_a::stats_import.pg_stats_ext_exprs_flat_t FROM (TABLE bset EXCEPT TABLE aset) AS b_minus_a; END; -- -- Schema setup. -- CREATE TYPE stats_import.complex_type AS ( a integer, b real, c text, d date, e jsonb); CREATE TABLE stats_import.test( id INTEGER PRIMARY KEY, name text, comp stats_import.complex_type, arange int4range, tags text[] ) WITH (autovacuum_enabled = false); CREATE TABLE stats_import.test_mr( id INTEGER PRIMARY KEY, name text, mrange int4multirange ) WITH (autovacuum_enabled = false); SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'relpages', 18::integer, 'reltuples', 21::real, 'relallvisible', 24::integer, 'relallfrozen', 27::integer); pg_restore_relation_stats --------------------------- t (1 row) -- CREATE INDEX on a table with autovac disabled should not overwrite -- stats CREATE INDEX test_i ON stats_import.test(id); SELECT relname, relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass ORDER BY relname; relname | relpages | reltuples | relallvisible | relallfrozen ---------+----------+-----------+---------------+-------------- test | 18 | 21 | 24 | 27 (1 row) SELECT pg_clear_relation_stats('stats_import', 'test'); pg_clear_relation_stats ------------------------- (1 row) -- -- relstats tests -- -- error: schemaname missing SELECT pg_catalog.pg_restore_relation_stats( 'relname', 'test', 'relpages', 17::integer); ERROR: argument "schemaname" must not be null -- error: relname missing SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relpages', 17::integer); ERROR: argument "relname" must not be null --- error: schemaname is wrong type SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 3.6::float, 'relname', 'test', 'relpages', 17::integer); WARNING: argument "schemaname" has type double precision, expected type text ERROR: argument "schemaname" must not be null --- error: relname is wrong type SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 0::oid, 'relpages', 17::integer); WARNING: argument "relname" has type oid, expected type text ERROR: argument "relname" must not be null -- error: relation not found SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'nope', 'relpages', 17::integer); ERROR: relation "stats_import.nope" does not exist -- error: odd number of variadic arguments cannot be pairs SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', '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( 'schemaname', 'stats_import', 'relname', 'test', NULL, '17'::integer); ERROR: name at variadic position 5 is null -- starting stats SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test_i'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 1 | 0 | 0 | 0 (1 row) -- regular indexes have special case locking rules BEGIN; SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test_i', 'relpages', 18::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT mode FROM pg_locks WHERE relation = 'stats_import.test'::regclass AND pid = pg_backend_pid() AND granted; mode -------------------------- ShareUpdateExclusiveLock (1 row) SELECT mode FROM pg_locks WHERE relation = 'stats_import.test_i'::regclass AND pid = pg_backend_pid() AND granted; mode -------------------------- ShareUpdateExclusiveLock (1 row) COMMIT; -- 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 PARTITION OF stats_import.part_parent FOR VALUES FROM (0) TO (10) WITH (autovacuum_enabled = false); -- This ensures the presence of extended statistics marked with -- inherited = true. CREATE STATISTICS stats_import.part_parent_stat ON i, (i % 2) FROM stats_import.part_parent; CREATE INDEX part_parent_i ON stats_import.part_parent(i); INSERT INTO stats_import.part_parent SELECT g.g FROM generate_series(0,9) AS g(g); SELECT COUNT(*) FROM stats_import.part_parent; count ------- 10 (1 row) SELECT COUNT(*) FROM stats_import.part_child_1; count ------- 10 (1 row) ANALYZE stats_import.part_parent; SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'part_parent_stat' GROUP BY e.inherited; count | inherited -------+----------- 1 | t (1 row) SELECT relpages FROM pg_class WHERE oid = 'stats_import.part_parent'::regclass; relpages ---------- -1 (1 row) -- -- Partitioned indexes aren't analyzed but it is possible to set -- stats. The locking rules are different from normal indexes due to -- the rules for in-place updates: both the partitioned table and the -- partitioned index are locked in ShareUpdateExclusive mode. -- BEGIN; SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'part_parent_i', 'relpages', 2::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT mode FROM pg_locks WHERE relation = 'stats_import.part_parent'::regclass AND pid = pg_backend_pid() AND granted; mode -------------------------- ShareUpdateExclusiveLock (1 row) SELECT mode FROM pg_locks WHERE relation = 'stats_import.part_parent_i'::regclass AND pid = pg_backend_pid() AND granted; mode -------------------------- ShareUpdateExclusiveLock (1 row) COMMIT; SELECT relpages FROM pg_class WHERE oid = 'stats_import.part_parent_i'::regclass; relpages ---------- 2 (1 row) -- ok: set all relstats, with version, no bounds checking SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'version', 150000::integer, 'relpages', '-17'::integer, 'reltuples', 400::real, 'relallvisible', 4::integer, 'relallfrozen', 2::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- -17 | 400 | 4 | 2 (1 row) -- ok: set just relpages, rest stay same SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'relpages', '16'::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 400 | 4 | 2 (1 row) -- ok: set just reltuples, rest stay same SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', '500'::real); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 500 | 4 | 2 (1 row) -- error: reltuples must be finite (rejected with WARNING, returns false) SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', 'Infinity'::real); WARNING: argument "reltuples" must be a finite value pg_restore_relation_stats --------------------------- f (1 row) SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', '-Infinity'::real); WARNING: argument "reltuples" must be a finite value pg_restore_relation_stats --------------------------- f (1 row) SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', 'NaN'::real); WARNING: argument "reltuples" must be a finite value pg_restore_relation_stats --------------------------- f (1 row) -- error: reltuples must not be less than -1.0 (rejected with WARNING, returns false) SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', '-5'::real); WARNING: argument "reltuples" must not be less than -1.0 pg_restore_relation_stats --------------------------- f (1 row) -- reltuples is unchanged (still 500) after the rejected values above SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 500 | 4 | 2 (1 row) -- ok: -1 (the "unknown" sentinel) is still accepted SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', '-1'::real); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | -1 | 4 | 2 (1 row) -- restore reltuples to 500 for the following tests SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'reltuples', '500'::real); pg_restore_relation_stats --------------------------- t (1 row) -- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'relallvisible', 5::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 500 | 5 | 2 (1 row) -- ok: just relallfrozen SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'version', 150000::integer, 'relallfrozen', 3::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 500 | 5 | 3 (1 row) -- warn: bad relpages type, rest updated SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', 'relpages', 'nope'::text, 'reltuples', 400.0::real, 'relallvisible', 4::integer, 'relallfrozen', 3::integer); WARNING: argument "relpages" has type text, expected type integer pg_restore_relation_stats --------------------------- f (1 row) SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible | relallfrozen ----------+-----------+---------------+-------------- 16 | 400 | 4 | 3 (1 row) -- unrecognized argument name, rest ok SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'test', '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(schemaname => 'stats_import', relname => 'test'); 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; SELECT pg_catalog.pg_restore_relation_stats( 'schemaname', 'stats_import', 'relname', 'testseq'); ERROR: cannot modify statistics for relation "testseq" DETAIL: This operation is not supported for sequences. SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq'); ERROR: cannot modify statistics for relation "testseq" DETAIL: This operation is not supported for sequences. CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview'); ERROR: cannot modify statistics for relation "testview" DETAIL: This operation is not supported for views. -- -- attribute stats -- -- error: schemaname missing SELECT pg_catalog.pg_restore_attribute_stats( 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: argument "schemaname" must not be null -- error: schema does not exist SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'nope', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: schema "nope" does not exist -- error: relname missing SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: argument "relname" must not be null -- error: relname does not exist SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'nope', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: relation "stats_import.nope" does not exist -- error: relname null SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', NULL, 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: argument "relname" must not be null -- error: NULL attname SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', NULL, 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: must specify either "attname" or "attnum" -- error: attname doesn't exist SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'nope', 'inherited', false::boolean, '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( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: cannot specify both "attname" and "attnum" -- error: neither attname nor attnum SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: must specify either "attname" or "attnum" -- error: attribute is system column SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'xmin', '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( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', NULL::boolean, 'null_frac', 0.1::real); ERROR: argument "inherited" must not be null -- ok: just the fixed values, with version, no stakinds SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'version', 150000::integer, 'null_frac', 0.2::real, 'avg_width', 5::integer, 'n_distinct', 0.6::real); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.2 | 5 | 0.6 | | | | | | | | | | (1 row) -- -- 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( 'schemaname', 'stats_import', 'relname', 'test', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.4::real); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.4 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: unrecognized argument name, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.2::real, 'nope', 0.5::real); WARNING: unrecognized argument name: "nope" pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.2 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcv / mcf null mismatch part 1, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_freqs', '{0.1,0.2,0.3}'::real[] ); WARNING: argument "most_common_vals" must be specified when argument "most_common_freqs" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.21 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcv / mcf null mismatch part 2, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_vals', '{1,2,3}'::text ); WARNING: argument "most_common_freqs" must be specified when argument "most_common_vals" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.21 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcf type mismatch, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.22::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.2,0.1}'::double precision[] ); WARNING: argument "most_common_freqs" has type double precision[], expected type real[] WARNING: argument "most_common_freqs" must be specified when argument "most_common_vals" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.22 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcv cast failure, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.23::real, 'most_common_vals', '{2,four,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); WARNING: invalid input syntax for type integer: "four" pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.23 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcv / mcf array length mismatch (more vals), mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.24::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25}'::real[] ); WARNING: could not parse "most_common_vals": incorrect number of elements (same as "most_common_freqs" required) pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.24 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: mcv / mcf array length mismatch (more freqs), mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.25::real, 'most_common_vals', '{2,1}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); WARNING: could not parse "most_common_vals": incorrect number of elements (same as "most_common_freqs" required) pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.25 | 5 | 0.6 | | | | | | | | | | (1 row) -- warn: most_common_vals is multi-dimensional, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.26::real, 'most_common_vals', '{{2,1},{3,4}}'::text, 'most_common_freqs', '{0.3,0.25,0.05,0.04}'::real[] ); WARNING: "most_common_vals" must be a one-dimensional array pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.26 | 5 | 0.6 | | | | | | | | | | (1 row) -- ok: mcv+mcf SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.26 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | (1 row) -- warn: NULL in histogram array, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.24::real, 'histogram_bounds', '{1,NULL,3,4}'::text ); WARNING: "histogram_bounds" array must not contain null values pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.24 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | (1 row) -- ok: histogram_bounds SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'histogram_bounds', '{1,2,3,4}'::text ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.24 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- warn: elem_count_histogram null element, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.25::real, 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] ); WARNING: argument "elem_count_histogram" array must not contain null values pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | tags | f | 0.25 | 0 | 0 | | | | | | | | | | (1 row) -- ok: elem_count_histogram SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'tags', 'inherited', false::boolean, '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 ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ stats_import | test | tags | f | 0.26 | 0 | 0 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) -- warn: range stats on a scalar type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.27::real, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); WARNING: column "id" is not a range type DETAIL: Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM. pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.27 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- warn: range_empty_frac range_length_hist null mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.28::real, 'range_length_histogram', '{399,499,Infinity}'::text ); WARNING: argument "range_empty_frac" must be specified when argument "range_length_histogram" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | arange | f | 0.28 | 0 | 0 | | | | | | | | | | (1 row) -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.29::real, 'range_empty_frac', 0.5::real ); WARNING: argument "range_length_histogram" must be specified when argument "range_empty_frac" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | | | (1 row) -- ok: range_empty_frac + range_length_hist SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | (1 row) -- warn: range bounds histogram on scalar, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.31::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); WARNING: column "id" is not a range type DETAIL: Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM. pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.31 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- ok: range_bounds_histogram SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} (1 row) -- warn: range bounds histogram with unsorted elements SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'range_bounds_histogram', '{"[50,60)","[1,2)","[90,100)","[5,6)"}'::text ); WARNING: "range_bounds_histogram" must have its lower and upper bounds sorted in ascending order pg_restore_attribute_stats ---------------------------- f (1 row) -- warn: range bounds histogram with empty range SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, 'range_bounds_histogram', '{empty,"[1,2)","[3,4)"}'::text ); WARNING: "range_bounds_histogram" must not contain empty ranges pg_restore_attribute_stats ---------------------------- f (1 row) -- warn: cannot set most_common_elems for range type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'arange', 'inherited', false::boolean, '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[] ); WARNING: could not determine element type of column "arange" DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- stats_import | test | arange | f | 0.32 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} (1 row) -- warn: scalars can't have mcelem, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, '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[] ); WARNING: could not determine element type of column "id" DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.33 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- warn: mcelem / mcelem mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.34::real, 'most_common_elems', '{one,two}'::text ); WARNING: argument "most_common_elem_freqs" must be specified when argument "most_common_elems" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ stats_import | test | tags | f | 0.34 | 0 | 0 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) -- warn: mcelem / mcelem null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.35::real, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] ); WARNING: argument "most_common_elems" must be specified when argument "most_common_elem_freqs" is specified pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable 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( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'tags', 'inherited', false::boolean, 'most_common_elems', '{one,three}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ stats_import | test | tags | f | 0.35 | 0 | 0 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) -- warn: scalars can't have elem_count_histogram, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test', 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.36::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] ); WARNING: could not determine element type of column "id" DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. pg_restore_attribute_stats ---------------------------- f (1 row) SELECT * FROM stats_import.pg_stats_stable WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ stats_import | test | id | f | 0.36 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- test for multiranges INSERT INTO stats_import.test_mr VALUES (1, 'red', '{[1,3),[5,9),[20,30)}'::int4multirange), (2, 'red', '{[11,13),[15,19),[20,30)}'::int4multirange), (3, 'red', '{[21,23),[25,29),[120,130)}'::int4multirange); -- warn: reject range values as ordinary multirange statistics SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'attname', 'mrange', 'inherited', false, 'most_common_vals', ARRAY['[1,3)']::text, 'most_common_freqs', ARRAY[1.0]::real[] ); WARNING: malformed multirange literal: "[1,3)" DETAIL: Missing left brace. pg_restore_attribute_stats ---------------------------- f (1 row) -- ensure that we set attribute stats for a multirange -- MCVs and histograms retain the multirange type. SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'attname', 'mrange', 'inherited', false, 'most_common_vals', ARRAY['{[1,3),[5,9)}', '{[11,13),[15,19)}']::text, 'most_common_freqs', ARRAY[0.6, 0.4]::real[], 'histogram_bounds', ARRAY['{[1,3)}', '{[11,13)}', '{[21,23)}']::text, 'range_length_histogram', '{19,29,109}'::text, 'range_empty_frac', '0'::real, 'range_bounds_histogram', '{"[1,30)","[11,30)","[21,130)"}'::text ); pg_restore_attribute_stats ---------------------------- t (1 row) -- -- 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 -- stacollN values. Because oids are not stable across databases, we can only -- test this when the source and destination are on the same database -- instance. For that reason, we borrow and adapt a query found in fe_utils -- and used by pg_dump/pg_upgrade. -- INSERT INTO stats_import.test SELECT 1, 'one', (1, 1.1, 'ONE', '2001-01-01', '{ "xkey": "xval" }')::stats_import.complex_type, int4range(1,4), array['red','green'] UNION ALL SELECT 2, 'two', (2, 2.2, 'TWO', '2002-02-02', '[true, 4, "six"]')::stats_import.complex_type, int4range(1,4), array['blue','yellow'] UNION ALL SELECT 3, 'tre', (3, 3.3, 'TRE', '2003-03-03', NULL)::stats_import.complex_type, int4range(-1,1), array['"orange"', 'purple', 'cyan'] UNION ALL SELECT 4, 'four', NULL, int4range(0,100), NULL; CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1)); CREATE STATISTICS stats_import.test_stat ON name, comp, lower(arange), array_length(tags,1) FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_ndistinct (ndistinct) ON name, comp FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_dependencies (dependencies) ON name, comp FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_mcv (mcv) ON name, comp FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_ndistinct_exprs (ndistinct) ON lower(name), upper(name) FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_dependencies_exprs (dependencies) ON lower(name), upper(name) FROM stats_import.test; CREATE STATISTICS stats_import.test_stat_mcv_exprs (mcv) ON lower(name), upper(name) FROM stats_import.test; -- Generate statistics on table with data ANALYZE stats_import.test; CREATE TABLE stats_import.test_clone ( LIKE stats_import.test ) WITH (autovacuum_enabled = false); CREATE INDEX is_odd_clone ON stats_import.test_clone(((comp).a % 2 = 1)); CREATE STATISTICS stats_import.test_stat_clone ON name, comp, lower(arange), array_length(tags,1) FROM stats_import.test_clone; -- -- Copy stats from test to test_clone, and is_odd to is_odd_clone -- SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.* FROM pg_catalog.pg_stats AS s CROSS JOIN LATERAL pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', s.tablename::text || '_clone', 'attname', s.attname::text, 'inherited', s.inherited, 'version', 150000, 'null_frac', s.null_frac, 'avg_width', s.avg_width, 'n_distinct', s.n_distinct, 'most_common_vals', s.most_common_vals::text, 'most_common_freqs', s.most_common_freqs, 'histogram_bounds', s.histogram_bounds::text, 'correlation', s.correlation, 'most_common_elems', s.most_common_elems::text, 'most_common_elem_freqs', s.most_common_elem_freqs, 'elem_count_histogram', s.elem_count_histogram, 'range_bounds_histogram', s.range_bounds_histogram::text, 'range_empty_frac', s.range_empty_frac, 'range_length_histogram', s.range_length_histogram::text) AS r WHERE s.schemaname = 'stats_import' AND s.tablename IN ('test', 'is_odd') ORDER BY s.tablename, s.attname, s.inherited; schemaname | tablename | attname | inherited | r --------------+-----------+----------+-----------+--- stats_import | is_odd | comp_2_1 | f | t stats_import | test | arange | f | t stats_import | test | comp | f | t stats_import | test | id | f | t stats_import | test | name | f | t stats_import | test | tags | f | t (6 rows) SELECT c.relname, COUNT(*) AS num_stats FROM pg_class AS c JOIN pg_statistic s ON s.starelid = c.oid WHERE c.relnamespace = 'stats_import'::regnamespace AND c.relname IN ('test', 'test_clone', 'is_odd', 'is_odd_clone') GROUP BY c.relname ORDER BY c.relname; relname | num_stats --------------+----------- is_odd | 1 is_odd_clone | 1 test | 5 test_clone | 5 (4 rows) SELECT relname, (stats).* FROM stats_import.pg_statistic_get_difference('test', 'test_clone') \gx (0 rows) SELECT relname, (stats).* FROM stats_import.pg_statistic_get_difference('is_odd', 'is_odd_clone') \gx (0 rows) -- 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( schemaname => 'stats_import', relname => 'test', attname => 'arange', inherited => false); pg_clear_attribute_stats -------------------------- (1 row) SELECT COUNT(*) FROM pg_stats WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; count ------- 0 (1 row) -- temp tables CREATE TEMP TABLE stats_temp(i int); SELECT pg_restore_relation_stats( 'schemaname', 'pg_temp', 'relname', 'stats_temp', 'relpages', '-19'::integer, 'reltuples', 401::real, 'relallvisible', 5::integer, 'relallfrozen', 3::integer); pg_restore_relation_stats --------------------------- t (1 row) SELECT relname, relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'pg_temp.stats_temp'::regclass ORDER BY relname; relname | relpages | reltuples | relallvisible | relallfrozen ------------+----------+-----------+---------------+-------------- stats_temp | -19 | 401 | 5 | 3 (1 row) SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'pg_temp', 'relname', 'stats_temp', 'attname', 'i', 'inherited', false::boolean, 'null_frac', 0.0123::real ); pg_restore_attribute_stats ---------------------------- t (1 row) SELECT tablename, null_frac FROM pg_stats WHERE schemaname like 'pg_temp%' AND tablename = 'stats_temp' AND inherited = false AND attname = 'i'; tablename | null_frac ------------+----------- stats_temp | 0.0123 (1 row) DROP TABLE stats_temp; -- Tests for pg_clear_extended_stats(). -- Invalid argument values. SELECT pg_clear_extended_stats(schemaname => NULL, relname => 'rel_foo', statistics_schemaname => 'schema_foo', statistics_name => 'stat_bar', inherited => false); ERROR: argument "schemaname" must not be null SELECT pg_clear_extended_stats(schemaname => 'schema_foo', relname => NULL, statistics_schemaname => 'schema_foo', statistics_name => 'stat_bar', inherited => false); ERROR: argument "relname" must not be null SELECT pg_clear_extended_stats(schemaname => 'schema_foo', relname => 'rel_foo', statistics_schemaname => NULL, statistics_name => 'stat_bar', inherited => false); ERROR: argument "statistics_schemaname" must not be null SELECT pg_clear_extended_stats(schemaname => 'schema_foo', relname => 'rel_foo', statistics_schemaname => 'schema_foo', statistics_name => NULL, inherited => false); ERROR: argument "statistics_name" must not be null SELECT pg_clear_extended_stats(schemaname => 'schema_foo', relname => 'rel_foo', statistics_schemaname => 'schema_foo', statistics_name => 'stat_bar', inherited => NULL); ERROR: argument "inherited" must not be null -- Missing objects SELECT pg_clear_extended_stats(schemaname => 'schema_not_exist', relname => 'test', statistics_schemaname => 'schema_not_exist', statistics_name => 'test_stat', inherited => false); ERROR: schema "schema_not_exist" does not exist SELECT pg_clear_extended_stats(schemaname => 'stats_import', relname => 'table_not_exist', statistics_schemaname => 'stats_import', statistics_name => 'test_stat', inherited => false); ERROR: relation "stats_import.table_not_exist" does not exist SELECT pg_clear_extended_stats(schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'schema_not_exist', statistics_name => 'test_stat', inherited => false); WARNING: could not find schema "schema_not_exist" pg_clear_extended_stats ------------------------- (1 row) SELECT pg_clear_extended_stats(schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'stats_import', statistics_name => 'ext_stats_not_exist', inherited => false); WARNING: could not find extended statistics object "stats_import.ext_stats_not_exist" pg_clear_extended_stats ------------------------- (1 row) -- Incorrect relation/extended stats combination SELECT pg_clear_extended_stats(schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'stats_import', statistics_name => 'test_stat_clone', inherited => false); WARNING: could not clear extended statistics object "stats_import.test_stat_clone": incorrect relation "stats_import.test" specified pg_clear_extended_stats ------------------------- (1 row) -- Check that records are removed after a valid clear call. SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat' GROUP BY e.inherited; count | inherited -------+----------- 1 | f (1 row) SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat' GROUP BY e.inherited; count | inherited -------+----------- 2 | f (1 row) BEGIN; SELECT pg_catalog.pg_clear_extended_stats( schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'stats_import', statistics_name => 'test_stat', inherited => false); pg_clear_extended_stats ------------------------- (1 row) SELECT mode FROM pg_locks WHERE locktype = 'relation' AND relation = 'stats_import.test'::regclass AND pid = pg_backend_pid(); mode -------------------------- ShareUpdateExclusiveLock (1 row) COMMIT; SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat' GROUP BY e.inherited; count | inherited -------+----------- (0 rows) SELECT COUNT(*), e.inherited FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat' GROUP BY e.inherited; count | inherited -------+----------- 2 | (1 row) -- And before/after on inherited stats SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'part_parent_stat' GROUP BY e.inherited; count | inherited -------+----------- 1 | t (1 row) SELECT pg_catalog.pg_clear_extended_stats( schemaname => 'stats_import', relname => 'part_parent', statistics_schemaname => 'stats_import', statistics_name => 'part_parent_stat', inherited => true); pg_clear_extended_stats ------------------------- (1 row) SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'part_parent_stat' GROUP BY e.inherited; count | inherited -------+----------- (0 rows) -- Check that MAINTAIN is required when clearing statistics. CREATE ROLE regress_test_extstat_clear; GRANT ALL ON SCHEMA stats_import TO regress_test_extstat_clear; SET ROLE regress_test_extstat_clear; SELECT pg_catalog.pg_clear_extended_stats( schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'stats_import', statistics_name => 'test_stat', inherited => false); ERROR: permission denied for table test RESET ROLE; GRANT MAINTAIN ON stats_import.test TO regress_test_extstat_clear; SET ROLE regress_test_extstat_clear; SELECT pg_catalog.pg_clear_extended_stats( schemaname => 'stats_import', relname => 'test', statistics_schemaname => 'stats_import', statistics_name => 'test_stat', inherited => false); pg_clear_extended_stats ------------------------- (1 row) RESET ROLE; REVOKE MAINTAIN ON stats_import.test FROM regress_test_extstat_clear; REVOKE ALL ON SCHEMA stats_import FROM regress_test_extstat_clear; DROP ROLE regress_test_extstat_clear; -- Tests for pg_restore_extended_stats(). -- Invalid argument values. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', NULL, 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: argument "schemaname" must not be null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', NULL, 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: argument "relname" must not be null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', NULL, 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: argument "statistics_schemaname" must not be null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', NULL, 'inherited', false); ERROR: argument "statistics_name" must not be null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', NULL); ERROR: argument "inherited" must not be null -- Missing objects SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'schema_not_exist', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: schema "schema_not_exist" does not exist SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'table_not_exist', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: relation "stats_import.table_not_exist" does not exist SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'schema_not_exist', 'statistics_name', 'test_stat_clone', 'inherited', false); WARNING: could not find schema "schema_not_exist" pg_restore_extended_stats --------------------------- f (1 row) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'ext_stats_not_exist', 'inherited', false); WARNING: could not find extended statistics object "stats_import.ext_stats_not_exist" pg_restore_extended_stats --------------------------- f (1 row) -- Incorrect relation/extended stats combination SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); WARNING: could not restore extended statistics object "stats_import.test_stat_clone": incorrect relation "stats_import.test" specified pg_restore_extended_stats --------------------------- f (1 row) -- Check that MAINTAIN is required when restoring statistics. CREATE ROLE regress_test_extstat_restore; GRANT ALL ON SCHEMA stats_import TO regress_test_extstat_restore; SET ROLE regress_test_extstat_restore; -- No data to restore; this fails on a permission failure. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false); ERROR: permission denied for table test_clone RESET ROLE; GRANT MAINTAIN ON stats_import.test_clone TO regress_test_extstat_restore; SET ROLE regress_test_extstat_restore; -- This works, check the lock on the relation while on it. BEGIN; SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'n_distinct', '[{"attributes" : [2,3], "ndistinct" : 4}]'::pg_ndistinct); pg_restore_extended_stats --------------------------- t (1 row) SELECT mode FROM pg_locks WHERE locktype = 'relation' AND relation = 'stats_import.test_clone'::regclass AND pid = pg_backend_pid(); mode -------------------------- ShareUpdateExclusiveLock (1 row) COMMIT; RESET ROLE; REVOKE MAINTAIN ON stats_import.test_clone FROM regress_test_extstat_restore; REVOKE ALL ON SCHEMA stats_import FROM regress_test_extstat_restore; DROP ROLE regress_test_extstat_restore; -- ndistinct value doesn't match object definition SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct', 'inherited', false, 'n_distinct', '[{"attributes" : [1,3], "ndistinct" : 4}]'::pg_ndistinct); WARNING: could not validate "pg_ndistinct" object: invalid attribute number 1 found pg_restore_extended_stats --------------------------- f (1 row) -- Incorrect extended stats kind, ndistinct not supported SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies', 'inherited', false, 'n_distinct', '[{"attributes" : [1,3], "ndistinct" : 4}]'::pg_ndistinct); WARNING: cannot specify parameter "n_distinct" HINT: Extended statistics object "stats_import.test_stat_dependencies" does not support statistics of this type. pg_restore_extended_stats --------------------------- f (1 row) -- Incorrect extended stats kind, dependencies not supported SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct', 'inherited', false, 'dependencies', '[{"attributes": [2], "dependency": 3, "degree": 1.000000}, {"attributes": [3], "dependency": 2, "degree": 1.000000}]'::pg_dependencies); WARNING: cannot specify parameter "dependencies" HINT: Extended statistics object "stats_import.test_stat_ndistinct" does not support statistics of this type. pg_restore_extended_stats --------------------------- f (1 row) -- ok: ndistinct SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct', 'inherited', false, 'n_distinct', '[{"attributes" : [2,3], "ndistinct" : 4}]'::pg_ndistinct); pg_restore_extended_stats --------------------------- t (1 row) -- dependencies value doesn't match definition SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies', 'inherited', false, 'dependencies', '[{"attributes": [1], "dependency": 3, "degree": 1.000000}, {"attributes": [3], "dependency": 1, "degree": 1.000000}]'::pg_dependencies); WARNING: could not validate "pg_dependencies" object: invalid attribute number 1 found pg_restore_extended_stats --------------------------- f (1 row) -- ok: dependencies SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies', 'inherited', false, 'dependencies', '[{"attributes": [2], "dependency": 3, "degree": 1.000000}, {"attributes": [3], "dependency": 2, "degree": 1.000000}]'::pg_dependencies); pg_restore_extended_stats --------------------------- t (1 row) -- ndistinct with expressions, invalid attributes. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct_exprs', 'inherited', false, 'n_distinct', '[{"attributes" : [1,-1], "ndistinct" : 4}]'::pg_ndistinct); WARNING: could not validate "pg_ndistinct" object: invalid attribute number 1 found pg_restore_extended_stats --------------------------- f (1 row) -- ok: ndistinct with expressions. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct_exprs', 'inherited', false, 'n_distinct', '[{"attributes" : [-1,-2], "ndistinct" : 4}]'::pg_ndistinct); pg_restore_extended_stats --------------------------- t (1 row) -- dependencies with expressions, invalid attributes. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies_exprs', 'inherited', false, 'dependencies', '[{"attributes": [-1], "dependency": 1, "degree": 1.000000}, {"attributes": [1], "dependency": -1, "degree": 1.000000}]'::pg_dependencies); WARNING: could not validate "pg_dependencies" object: invalid attribute number 1 found pg_restore_extended_stats --------------------------- f (1 row) -- ok: dependencies with expressions SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies_exprs', 'inherited', false, 'dependencies', '[{"attributes": [-1], "dependency": -2, "degree": 1.000000}, {"attributes": [-2], "dependency": -1, "degree": 1.000000}]'::pg_dependencies); pg_restore_extended_stats --------------------------- t (1 row) -- ok: MCV with expressions SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv_exprs', 'inherited', false, 'most_common_vals', '{{four,FOUR},{one,NULL},{NULL,TRE},{two,TWO}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.99}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.023,0.087}'::double precision[]); pg_restore_extended_stats --------------------------- t (1 row) -- Check the presence of the restored stats, for each object. SELECT replace(e.n_distinct, '}, ', E'},\n') AS n_distinct FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_ndistinct' AND e.inherited = false; n_distinct ------------------------------------------ [{"attributes": [2, 3], "ndistinct": 4}] (1 row) SELECT replace(e.dependencies, '}, ', E'},\n') AS dependencies FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_dependencies' AND e.inherited = false; dependencies ------------------------------------------------------------ [{"attributes": [2], "dependency": 3, "degree": 1.000000},+ {"attributes": [3], "dependency": 2, "degree": 1.000000}] (1 row) SELECT replace(e.n_distinct, '}, ', E'},\n') AS n_distinct FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_ndistinct_exprs' AND e.inherited = false; n_distinct -------------------------------------------- [{"attributes": [-1, -2], "ndistinct": 4}] (1 row) SELECT replace(e.dependencies, '}, ', E'},\n') AS dependencies FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_dependencies_exprs' AND e.inherited = false; dependencies -------------------------------------------------------------- [{"attributes": [-1], "dependency": -2, "degree": 1.000000},+ {"attributes": [-2], "dependency": -1, "degree": 1.000000}] (1 row) SELECT e.most_common_vals, e.most_common_val_nulls, e.most_common_freqs, e.most_common_base_freqs FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_mcv_exprs' AND e.inherited = false \gx -[ RECORD 1 ]----------+---------------------------------------------- most_common_vals | {{four,FOUR},{one,NULL},{NULL,TRE},{two,TWO}} most_common_val_nulls | {{f,f},{f,t},{t,f},{f,f}} most_common_freqs | {0.25,0.25,0.25,0.99} most_common_base_freqs | {0.0625,0.0625,0.023,0.087} -- Incorrect extended stats kind, mcv not supported SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_dependencies', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); WARNING: cannot specify parameters "most_common_vals", "most_common_freqs", or "most_common_base_freqs" HINT: Extended statistics object "stats_import.test_stat_dependencies" does not support statistics of this type. pg_restore_extended_stats --------------------------- f (1 row) -- MCV requires all three parameters SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); WARNING: could not use "most_common_vals", "most_common_freqs", and "most_common_base_freqs": missing one or more parameters pg_restore_extended_stats --------------------------- f (1 row) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); WARNING: could not use "most_common_vals", "most_common_freqs", and "most_common_base_freqs": missing one or more parameters pg_restore_extended_stats --------------------------- f (1 row) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[]); WARNING: could not use "most_common_vals", "most_common_freqs", and "most_common_base_freqs": missing one or more parameters pg_restore_extended_stats --------------------------- f (1 row) -- most_common_vals that is not 2-D SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{four,NULL}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); WARNING: could not parse array "most_common_vals": incorrect number of dimensions (2 required) pg_restore_extended_stats --------------------------- f (1 row) -- most_common_freqs with length not matching with most_common_vals. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); WARNING: could not parse array "most_common_freqs": incorrect number of elements (same as "most_common_vals" required) pg_restore_extended_stats --------------------------- f (1 row) -- most_common_base_freqs with length not matching most_common_vals. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625}'::double precision[]); WARNING: could not parse array "most_common_base_freqs": incorrect number of elements (same as "most_common_vals" required) pg_restore_extended_stats --------------------------- f (1 row) -- mcv attributes not matching object definition SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL,0,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")",1,2}, {tre,"(3,3.3,TRE,03-03-2003,)",-1,3}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")",1,2}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.00390625,0.015625,0.00390625,0.015625}'::double precision[]); WARNING: could not parse array "most_common_vals": found 4 attributes but expected 2 pg_restore_extended_stats --------------------------- f (1 row) -- warn: more MCV items than can be handled. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', (SELECT array_agg(ARRAY[g::text, g::text]) FROM generate_series(1, 10001) g), 'most_common_freqs', (SELECT array_agg((1.0 / 10001)::double precision) FROM generate_series(1, 10001) g), 'most_common_base_freqs', (SELECT array_agg((1.0 / 10001)::double precision) FROM generate_series(1, 10001) g)); WARNING: could not parse array "most_common_vals": number of items (10001) exceeds maximum (10000) pg_restore_extended_stats --------------------------- f (1 row) -- ok: mcv SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcv', 'inherited', false, 'most_common_vals', '{{four,NULL}, {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"}, {tre,"(3,3.3,TRE,03-03-2003,)"}, {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}}'::text[], 'most_common_freqs', '{0.25,0.25,0.25,0.25}'::double precision[], 'most_common_base_freqs', '{0.0625,0.0625,0.0625,0.0625}'::double precision[]); pg_restore_extended_stats --------------------------- t (1 row) SELECT replace(e.most_common_vals::text, '},', E'},\n ') AS mcvs, e.most_common_val_nulls, e.most_common_freqs, e.most_common_base_freqs FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_mcv' AND e.inherited = false \gx -[ RECORD 1 ]----------+------------------------------------------------------------------ mcvs | {{four,NULL}, + | {one,"(1,1.1,ONE,01-01-2001,\"{\"\"xkey\"\": \"\"xval\"\"}\")"},+ | {tre,"(3,3.3,TRE,03-03-2003,)"}, + | {two,"(2,2.2,TWO,02-02-2002,\"[true, 4, \"\"six\"\"]\")"}} most_common_val_nulls | {{f,t},{f,f},{f,f},{f,f}} most_common_freqs | {0.25,0.25,0.25,0.25} most_common_base_freqs | {0.0625,0.0625,0.0625,0.0625} -- Check import of all kinds for multirange. CREATE STATISTICS stats_import.test_mr_stat ON name, mrange, ( mrange + '{[10000,10200)}'::int4multirange) FROM stats_import.test_mr; CREATE TABLE stats_import.test_mr_clone ( LIKE stats_import.test_mr ) WITH (autovacuum_enabled = false); CREATE STATISTICS stats_import.test_mr_stat_clone ON name, mrange, ( mrange + '{[10000,10200)}'::int4multirange) FROM stats_import.test_mr_clone; -- Check for invalid value combinations for range types. -- Only range_bounds_histogram (other two missing) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_bounds_histogram": "{\"[1,10200)\",\"[11,10200)\"}"}]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "range_length_histogram", "range_empty_frac", and "range_bounds_histogram" must be all either strings or all nulls. pg_restore_extended_stats --------------------------- f (1 row) -- Only range_length_histogram and range_empty_frac -- (range_bounds_histogram missing) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_length_histogram": "{10179,10189}", "range_empty_frac": "0"}]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "range_length_histogram", "range_empty_frac", and "range_bounds_histogram" must be all either strings or all nulls. pg_restore_extended_stats --------------------------- f (1 row) -- Only range_bounds_histogram and range_empty_frac -- (range_length_histogram missing) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_bounds_histogram": "{\"[1,10200)\"}", "range_empty_frac": "0"}]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "range_length_histogram", "range_empty_frac", and "range_bounds_histogram" must be all either strings or all nulls. pg_restore_extended_stats --------------------------- f (1 row) -- Only range_bounds_histogram and range_length_histogram -- (range_empty_frac missing) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_bounds_histogram": "{\"[1,10200)\"}", "range_length_histogram": "{10179}"}]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "range_length_histogram", "range_empty_frac", and "range_bounds_histogram" must be all either strings or all nulls. pg_restore_extended_stats --------------------------- f (1 row) -- warn: range bounds histogram with unsorted elements SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_length_histogram": "{10179,10189,10199}", "range_empty_frac": "0", "range_bounds_histogram": "{\"[50,60)\",\"[1,2)\",\"[90,100)\"}"}]'::jsonb); WARNING: "range_bounds_histogram" must have its lower and upper bounds sorted in ascending order pg_restore_extended_stats --------------------------- f (1 row) -- warn: range bounds histogram with empty range SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'exprs', '[{"range_length_histogram": "{10179,10189,10199}", "range_empty_frac": "0", "range_bounds_histogram": "{empty,\"[1,2)\",\"[3,4)\"}"}]'::jsonb); WARNING: "range_bounds_histogram" must not contain empty ranges pg_restore_extended_stats --------------------------- f (1 row) -- ok: multirange stats SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_mr_stat', 'inherited', false, 'n_distinct', '[{"attributes": [2, 3], "ndistinct": 3}, {"attributes": [2, -1], "ndistinct": 3}, {"attributes": [3, -1], "ndistinct": 3}, {"attributes": [2, 3, -1], "ndistinct": 3}]'::pg_catalog.pg_ndistinct, 'dependencies', '[{"attributes": [3], "dependency": 2, "degree": 1.000000}, {"attributes": [3], "dependency": -1, "degree": 1.000000}, {"attributes": [-1], "dependency": 2, "degree": 1.000000}, {"attributes": [-1], "dependency": 3, "degree": 1.000000}, {"attributes": [2, 3], "dependency": -1, "degree": 1.000000}, {"attributes": [2, -1], "dependency": 3, "degree": 1.000000}, {"attributes": [3, -1], "dependency": 2, "degree": 1.000000}]'::pg_catalog.pg_dependencies, 'most_common_vals', '{{red,"{[1,3),[5,9),[20,30)}","{[1,3),[5,9),[20,30),[10000,10200)}"}, {red,"{[11,13),[15,19),[20,30)}","{[11,13),[15,19),[20,30),[10000,10200)}"}, {red,"{[21,23),[25,29),[120,130)}","{[21,23),[25,29),[120,130),[10000,10200)}"}}'::text[], 'most_common_freqs', '{0.3333333333333333,0.3333333333333333,0.3333333333333333}'::double precision[], 'most_common_base_freqs', '{0.1111111111111111,0.1111111111111111,0.1111111111111111}'::double precision[], 'exprs', '[{ "avg_width": "60", "null_frac": "0", "n_distinct": "-1", "range_length_histogram": "{10179,10189,10199}", "range_empty_frac": "0", "range_bounds_histogram": "{\"[1,10200)\",\"[11,10200)\",\"[21,10200)\"}" }]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT replace(e.n_distinct, '}, ', E'},\n') AS n_distinct, replace(e.dependencies, '}, ', E'},\n') AS dependencies, replace(e.most_common_vals::text, '},', E'},\n ') AS mcvs, e.most_common_val_nulls, e.most_common_freqs, e.most_common_base_freqs FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_mr_stat' AND e.inherited = false \gx -[ RECORD 1 ]----------+---------------------------------------------------------------------------------- n_distinct | [{"attributes": [2, 3], "ndistinct": 3}, + | {"attributes": [2, -1], "ndistinct": 3}, + | {"attributes": [3, -1], "ndistinct": 3}, + | {"attributes": [2, 3, -1], "ndistinct": 3}] dependencies | [{"attributes": [3], "dependency": 2, "degree": 1.000000}, + | {"attributes": [3], "dependency": -1, "degree": 1.000000}, + | {"attributes": [-1], "dependency": 2, "degree": 1.000000}, + | {"attributes": [-1], "dependency": 3, "degree": 1.000000}, + | {"attributes": [2, 3], "dependency": -1, "degree": 1.000000}, + | {"attributes": [2, -1], "dependency": 3, "degree": 1.000000}, + | {"attributes": [3, -1], "dependency": 2, "degree": 1.000000}] mcvs | {{red,"{[1,3),[5,9),[20,30)}","{[1,3),[5,9),[20,30),[10000,10200)}"}, + | {red,"{[11,13),[15,19),[20,30)}","{[11,13),[15,19),[20,30),[10000,10200)}"}, + | {red,"{[21,23),[25,29),[120,130)}","{[21,23),[25,29),[120,130),[10000,10200)}"}} most_common_val_nulls | {{f,f,f},{f,f,f},{f,f,f}} most_common_freqs | {0.3333333333333333,0.3333333333333333,0.3333333333333333} most_common_base_freqs | {0.1111111111111111,0.1111111111111111,0.1111111111111111} SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram, e.range_length_histogram, e.range_empty_frac, e.range_bounds_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_mr_stat' AND e.inherited = false \gx -[ RECORD 1 ]----------+--------------------------------------------- expr | (mrange + '{[10000,10200)}'::int4multirange) null_frac | 0 avg_width | 60 n_distinct | -1 most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | {10179,10189,10199} range_empty_frac | 0 range_bounds_histogram | {"[1,10200)","[11,10200)","[21,10200)"} -- Incorrect extended stats kind, exprs not supported SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_ndistinct', 'inherited', false, 'exprs', '[ { "avg_width": "4" } ]'::jsonb); WARNING: cannot specify parameter "exprs" HINT: Extended statistics object "stats_import.test_stat_ndistinct" does not support statistics of this type. pg_restore_extended_stats --------------------------- f (1 row) -- Invalid exprs, not an array SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '{ "avg_width": "4", "null_frac": "0" }'::jsonb); WARNING: could not parse "exprs": root-level array required pg_restore_extended_stats --------------------------- f (1 row) -- wrong number of exprs, too few SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "4" } ]'::jsonb); WARNING: could not parse "exprs": incorrect number of elements (2 required) pg_restore_extended_stats --------------------------- f (1 row) -- wrong number of exprs, too many SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "4" }, { "avg_width": "4" }, { "avg_width": "4" } ]'::jsonb); WARNING: could not parse "exprs": incorrect number of elements (2 required) pg_restore_extended_stats --------------------------- f (1 row) -- incorrect type of value: should be a string or a NULL. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "null_frac": 1 }, { "null_frac": "0.25" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: Value of element "null_frac" must be a null or a string. pg_restore_extended_stats --------------------------- f (1 row) -- exprs null_frac not a float SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "null_frac": "BADNULLFRAC" }, { "null_frac": "0.25" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADNULLFRAC" HINT: Element "null_frac" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs avg_width not an integer SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "BADAVGWIDTH" }, { "avg_width": "4" } ]'::jsonb); WARNING: invalid input syntax for type integer: "BADAVGWIDTH" HINT: Element "avg_width" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs n_dinstinct not a float SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "n_distinct": "BADNDISTINCT" }, { "n_distinct": "-0.5" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADNDISTINCT" HINT: Element "n_distinct" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- MCV not null, MCF null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": "{1}", "most_common_elems": null }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_vals" and "most_common_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCV not null, MCF missing SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": "{1}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_vals" and "most_common_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCV null, MCF not null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": null, "most_common_freqs": "{0.5}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_vals" and "most_common_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCV missing, MCF not null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_freqs": "{0.5}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_vals" and "most_common_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_vals is multi-dimensional SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": "{{1,2},{3,4}}", "most_common_freqs": "{0.3,0.25,0.05,0.04}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not import element "most_common_vals" in expression -1: must be a one-dimensional array pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_vals element wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "4", "null_frac": "0", "n_distinct": "-0.75", "correlation": "-0.6", "histogram_bounds": "{-1,0}", "most_common_vals": "{BADMCV}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null }, { "avg_width": "4", "null_frac": "0.25", "n_distinct": "-0.5", "correlation": "1", "histogram_bounds": null, "most_common_vals": "{2}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null } ]'::jsonb); WARNING: invalid input syntax for type integer: "BADMCV" HINT: Element "most_common_vals" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_freqs element wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": "{1}", "most_common_freqs": "{BADMCF}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADMCF" HINT: Element "most_common_freqs" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_vals / most_common_freqs array length mismatch SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "most_common_vals": "{1,3}", "most_common_freqs": "{0.5}" }, { "most_common_vals": "{2}", "most_common_freqs": "{0.5}" } ]'::jsonb); WARNING: could not parse "most_common_vals": incorrect number of elements (same as "most_common_freqs" required) pg_restore_extended_stats --------------------------- f (1 row) -- exprs histogram wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "histogram_bounds": "{BADHIST,0}" }, { "histogram_bounds": null } ]'::jsonb); WARNING: invalid input syntax for type integer: "BADHIST" HINT: Element "histogram_bounds" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs correlation wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "correlation": "BADCORR" }, { "correlation": "1" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADCORR" HINT: Element "correlation" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- invalid element type in array SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[1, null]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 pg_restore_extended_stats --------------------------- f (1 row) -- invalid element in array, as valid jbvBinary. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[null, [{"avg_width" : [1]}]]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -2 pg_restore_extended_stats --------------------------- f (1 row) -- only range types can have range_length_histogram, range_empty_frac -- or range_bounds_histogram. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ null, { "range_length_histogram": "{10179,10189,10199}", "range_empty_frac": "0", "range_bounds_histogram": "{10200,10200,10200}" } ]'::jsonb); WARNING: could not parse "exprs": invalid data in expression -2 HINT: "range_length_histogram", "range_empty_frac", and "range_bounds_histogram" can only be set for a range type. pg_restore_extended_stats --------------------------- f (1 row) -- only array types can have most_common_elems or elem_count_histogram. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ null, { "most_common_elems": "{1,2,3}", "most_common_elem_freqs": "{0.3,0.3,0.4}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element type in expression -2 pg_restore_extended_stats --------------------------- f (1 row) SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ null, { "elem_count_histogram": "{1,2,3,4,5}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element type in expression -2 pg_restore_extended_stats --------------------------- f (1 row) -- ok: exprs first null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ null, { "avg_width": "4", "null_frac": "0.25", "n_distinct": "-0.5", "correlation": "1", "histogram_bounds": null, "most_common_vals": "{2}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null } ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram, e.range_length_histogram, e.range_empty_frac, e.range_bounds_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_clone' AND e.inherited = false \gx -[ RECORD 1 ]----------+---------------------- expr | lower(arange) null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram | -[ RECORD 2 ]----------+---------------------- expr | array_length(tags, 1) null_frac | 0.25 avg_width | 4 n_distinct | -0.5 most_common_vals | {2} most_common_freqs | {0.5} histogram_bounds | correlation | 1 most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram | -- ok: exprs last null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "4", "null_frac": "0", "n_distinct": "-0.75", "correlation": "-0.6", "histogram_bounds": "{-1,0}", "most_common_vals": "{1}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null }, null ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_clone' AND e.inherited = false \gx -[ RECORD 1 ]----------+---------------------- expr | lower(arange) null_frac | 0 avg_width | 4 n_distinct | -0.75 most_common_vals | {1} most_common_freqs | {0.5} histogram_bounds | {-1,0} correlation | -0.6 most_common_elems | most_common_elem_freqs | elem_count_histogram | -[ RECORD 2 ]----------+---------------------- expr | array_length(tags, 1) null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | -- ok: both exprs SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_clone', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_clone', 'inherited', false, 'exprs', '[ { "avg_width": "4", "null_frac": "0", "n_distinct": "-0.75", "correlation": "-0.6", "histogram_bounds": "{-1,0}", "most_common_vals": "{1}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null }, { "avg_width": "4", "null_frac": "0.25", "n_distinct": "-0.5", "correlation": "1", "histogram_bounds": null, "most_common_vals": "{2}", "most_common_elems": null, "most_common_freqs": "{0.5}", "elem_count_histogram": null, "most_common_elem_freqs": null } ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_clone' AND e.inherited = false \gx -[ RECORD 1 ]----------+---------------------- expr | lower(arange) null_frac | 0 avg_width | 4 n_distinct | -0.75 most_common_vals | {1} most_common_freqs | {0.5} histogram_bounds | {-1,0} correlation | -0.6 most_common_elems | most_common_elem_freqs | elem_count_histogram | -[ RECORD 2 ]----------+---------------------- expr | array_length(tags, 1) null_frac | 0.25 avg_width | 4 n_distinct | -0.5 most_common_vals | {2} most_common_freqs | {0.5} histogram_bounds | correlation | 1 most_common_elems | most_common_elem_freqs | elem_count_histogram | -- A statistics object for testing MCELEM values in expressions CREATE STATISTICS stats_import.test_stat_mcelem ON name, (ARRAY[(comp).a, lower(arange)]) FROM stats_import.test; -- MCEV not null, MCEF null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elems": "{-1,0,1,2,3}", "most_common_elem_freqs": null } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_elems" and "most_common_elem_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCEV not null, MCEF missing SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elems": "{-1,0,1,2,3}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_elems" and "most_common_elem_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCEV null, MCEF not null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elems": null, "most_common_elem_freqs": "{0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_elems" and "most_common_elem_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- MCEV missing, MCEF not null SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elem_freqs": "{0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25}" } ]'::jsonb); WARNING: could not parse "exprs": invalid element in expression -1 HINT: "most_common_elems" and "most_common_elem_freqs" must be both either strings or nulls. pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_elems element wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elems": "{-1,BADELEM,1,2,3}", "most_common_elem_freqs": "{0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25}" } ]'::jsonb); WARNING: invalid input syntax for type integer: "BADELEM" HINT: Element "most_common_elems" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs most_common_elem_freqs element wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "most_common_elems": "{-1,0,1,2,3}", "most_common_elem_freqs": "{BADELEMFREQ,0.25,0.5,0.25,0.25,0.25,0.5,0.25}" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADELEMFREQ" HINT: Element "most_common_elem_freqs" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- exprs histogram bounds element wrong type SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "elem_count_histogram": "{BADELEMHIST,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1.5}" } ]'::jsonb); WARNING: invalid input syntax for type real: "BADELEMHIST" HINT: Element "elem_count_histogram" in expression -1 could not be parsed. pg_restore_extended_stats --------------------------- f (1 row) -- ok: exprs mcelem SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "avg_width": "33", "null_frac": "0", "n_distinct": "-1", "correlation": "1", "histogram_bounds": "{\"{1,1}\",\"{2,1}\",\"{3,-1}\",\"{NULL,0}\"}", "most_common_vals": null, "most_common_elems": "{-1,0,1,2,3}", "most_common_freqs": null, "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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1.5}", "most_common_elem_freqs": "{0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25}" } ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_mcelem' AND e.inherited = false \gx -[ RECORD 1 ]----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- expr | ARRAY[(comp).a, lower(arange)] null_frac | 0 avg_width | 33 n_distinct | -1 most_common_vals | most_common_freqs | histogram_bounds | {"{1,1}","{2,1}","{3,-1}","{NULL,0}"} correlation | 1 most_common_elems | {-1,0,1,2,3} most_common_elem_freqs | {0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25} 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1.5} -- ok, with warning: extra exprs param SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[ { "avg_width": "33", "null_frac": "0", "n_distinct": "-1", "correlation": "1", "histogram_bounds": "{\"{1,1}\",\"{2,1}\",\"{3,-1}\",\"{NULL,0}\"}", "most_common_vals": null, "most_common_elems": "{-1,0,1,2,3}", "most_common_freqs": null, "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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1.5}", "most_common_elem_freqs": "{0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25}", "bad_param": "text no one will ever parse" } ]'::jsonb); WARNING: could not import element in expression -1: invalid key name pg_restore_extended_stats --------------------------- f (1 row) SELECT e.expr, e.null_frac, e.avg_width, e.n_distinct, e.most_common_vals, e.most_common_freqs, e.histogram_bounds, e.correlation, e.most_common_elems, e.most_common_elem_freqs, e.elem_count_histogram FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_mcelem' AND e.inherited = false \gx -[ RECORD 1 ]----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- expr | ARRAY[(comp).a, lower(arange)] null_frac | 0 avg_width | 33 n_distinct | -1 most_common_vals | most_common_freqs | histogram_bounds | {"{1,1}","{2,1}","{3,-1}","{NULL,0}"} correlation | 1 most_common_elems | {-1,0,1,2,3} most_common_elem_freqs | {0.25,0.25,0.5,0.25,0.25,0.25,0.5,0.25} 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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1.5} -- bad: exprs param which is a prefix of a valid key name SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_mcelem', 'inherited', false, 'exprs', '[{ "n": "-1" }]'::jsonb); WARNING: could not import element in expression -1: invalid key name pg_restore_extended_stats --------------------------- f (1 row) -- ok: tsvector exceptions, test just the collation exceptions CREATE STATISTICS stats_import.test_stat_tsvec ON (length(name)), (to_tsvector(name)) FROM stats_import.test; SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test', 'statistics_schemaname', 'stats_import', 'statistics_name', 'test_stat_tsvec', 'inherited', false, 'exprs', '[null, { "most_common_elems": "{one,tre,two,four}", "most_common_elem_freqs": "{0.25,0.25,0.25,0.25,0.25,0.25}" } ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) SELECT e.expr, e.most_common_elems, e.most_common_elem_freqs FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat_tsvec' AND e.inherited = false \gx -[ RECORD 1 ]----------+-------------------------------- expr | length(name) most_common_elems | most_common_elem_freqs | -[ RECORD 2 ]----------+-------------------------------- expr | to_tsvector(name) most_common_elems | {one,tre,two,four} most_common_elem_freqs | {0.25,0.25,0.25,0.25,0.25,0.25} -- Test the ability of pg_restore_extended_stats() to import all of the -- statistic values from an extended statistic object that has been -- populated via a regular ANALYZE. This checks after the statistics -- kinds supported by pg_restore_extended_stats(). -- -- Note: Keep this test at the bottom of the file, so as the amount of -- statistics data handled is maximized. ANALYZE stats_import.test; -- Copy stats from test_stat to test_stat_clone SELECT e.statistics_name, pg_catalog.pg_restore_extended_stats( 'schemaname', e.statistics_schemaname::text, 'relname', 'test_clone', 'statistics_schemaname', e.statistics_schemaname::text, 'statistics_name', 'test_stat_clone', 'inherited', e.inherited, 'n_distinct', e.n_distinct, 'dependencies', e.dependencies, 'most_common_vals', e.most_common_vals, 'most_common_freqs', e.most_common_freqs, 'most_common_base_freqs', e.most_common_base_freqs, 'exprs', x.exprs) FROM pg_stats_ext AS e CROSS JOIN LATERAL ( SELECT jsonb_agg(jsonb_strip_nulls(jsonb_build_object( 'null_frac', ee.null_frac::text, 'avg_width', ee.avg_width::text, 'n_distinct', ee.n_distinct::text, 'most_common_vals', ee.most_common_vals::text, 'most_common_freqs', ee.most_common_freqs::text, 'histogram_bounds', ee.histogram_bounds::text, 'correlation', ee.correlation::text, 'most_common_elems', ee.most_common_elems::text, 'most_common_elem_freqs', ee.most_common_elem_freqs::text, 'elem_count_histogram', ee.elem_count_histogram::text, 'range_length_histogram', ee.range_length_histogram::text, 'range_empty_frac', ee.range_empty_frac::text, 'range_bounds_histogram', ee.range_bounds_histogram::text))) FROM pg_stats_ext_exprs AS ee WHERE ee.statistics_schemaname = e.statistics_schemaname AND ee.statistics_name = e.statistics_name AND ee.inherited = e.inherited ) AS x(exprs) WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_stat'; statistics_name | pg_restore_extended_stats -----------------+--------------------------- test_stat | t (1 row) SELECT statname, (stats).* FROM stats_import.pg_stats_ext_get_difference('test_stat', 'test_stat_clone') \gx (0 rows) SELECT statname, (stats).* FROM stats_import.pg_stats_ext_exprs_get_difference('test_stat', 'test_stat_clone') \gx (0 rows) ANALYZE stats_import.test_mr; -- Copy stats from test_mr_stat to test_mr_stat_clone SELECT e.statistics_name, pg_catalog.pg_restore_extended_stats( 'schemaname', e.statistics_schemaname::text, 'relname', 'test_mr_clone', 'statistics_schemaname', e.statistics_schemaname::text, 'statistics_name', 'test_mr_stat_clone', 'inherited', e.inherited, 'n_distinct', e.n_distinct, 'dependencies', e.dependencies, 'most_common_vals', e.most_common_vals, 'most_common_freqs', e.most_common_freqs, 'most_common_base_freqs', e.most_common_base_freqs, 'exprs', x.exprs) FROM pg_stats_ext AS e CROSS JOIN LATERAL ( SELECT jsonb_agg(jsonb_strip_nulls(jsonb_build_object( 'null_frac', ee.null_frac::text, 'avg_width', ee.avg_width::text, 'n_distinct', ee.n_distinct::text, 'most_common_vals', ee.most_common_vals::text, 'most_common_freqs', ee.most_common_freqs::text, 'histogram_bounds', ee.histogram_bounds::text, 'correlation', ee.correlation::text, 'most_common_elems', ee.most_common_elems::text, 'most_common_elem_freqs', ee.most_common_elem_freqs::text, 'elem_count_histogram', ee.elem_count_histogram::text, 'range_length_histogram', ee.range_length_histogram::text, 'range_empty_frac', ee.range_empty_frac::text, 'range_bounds_histogram', ee.range_bounds_histogram::text))) FROM pg_stats_ext_exprs AS ee WHERE ee.statistics_schemaname = e.statistics_schemaname AND ee.statistics_name = e.statistics_name AND ee.inherited = e.inherited ) AS x(exprs) WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'test_mr_stat'; statistics_name | pg_restore_extended_stats -----------------+--------------------------- test_mr_stat | t (1 row) SELECT statname, (stats).* FROM stats_import.pg_stats_ext_get_difference('test_mr_stat', 'test_mr_stat_clone') \gx (0 rows) SELECT statname, (stats).* FROM stats_import.pg_stats_ext_exprs_get_difference('test_mr_stat', 'test_mr_stat_clone') \gx (0 rows) -- range_length_histogram, range_empty_frac, and range_bounds_histogram -- have been added to pg_stats_ext_exprs in PostgreSQL 19. When dumping -- expression statistics in a cluster with an older version, these fields -- are dumped as NULL, pg_restore_extended_stats() authorizing the partial -- restore state of the extended statistics data. This test emulates such -- a case by calling pg_restore_extended_stats() with NULL values for all -- the three range fields, then checks the statistics loaded with some -- queries. CREATE TABLE stats_import.test_range_expr_null( id INTEGER PRIMARY KEY, name TEXT, rng int4range NOT NULL ); INSERT INTO stats_import.test_range_expr_null SELECT i, 'name_' || (i % 10), int4range(i, i + 10) FROM generate_series(1, 100) i; -- Create statistics with a range expression CREATE STATISTICS stats_import.stat_range_expr_null ON name, (rng * int4range(50, 150)) FROM stats_import.test_range_expr_null; ANALYZE stats_import.test_range_expr_null; -- Verify range statistics were created SELECT e.expr, e.range_length_histogram IS NOT NULL AS has_range_len, e.range_empty_frac IS NOT NULL AS has_range_empty, e.range_bounds_histogram IS NOT NULL AS has_range_bounds FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'stat_range_expr_null'; expr | has_range_len | has_range_empty | has_range_bounds ----------------------------+---------------+-----------------+------------------ (rng * int4range(50, 150)) | t | t | t (1 row) -- Import statistics with NULL range fields, simulating dump from -- older version. SELECT pg_catalog.pg_restore_extended_stats( 'schemaname', 'stats_import', 'relname', 'test_range_expr_null', 'statistics_schemaname', 'stats_import', 'statistics_name', 'stat_range_expr_null', 'inherited', false, 'exprs', '[ { "avg_width": "14", "null_frac": "0", "n_distinct": "-1" } ]'::jsonb); pg_restore_extended_stats --------------------------- t (1 row) -- Verify that range fields are now NULL. SELECT e.expr, e.null_frac, e.range_length_histogram IS NOT NULL AS has_range_len, e.range_empty_frac IS NOT NULL AS has_range_empty, e.range_bounds_histogram IS NOT NULL AS has_range_bounds FROM pg_stats_ext_exprs AS e WHERE e.statistics_schemaname = 'stats_import' AND e.statistics_name = 'stat_range_expr_null'; expr | null_frac | has_range_len | has_range_empty | has_range_bounds ----------------------------+-----------+---------------+-----------------+------------------ (rng * int4range(50, 150)) | 0 | f | f | f (1 row) -- Trigger statistics loading through some queries. EXPLAIN (COSTS OFF) SELECT * FROM stats_import.test_range_expr_null WHERE (rng * int4range(50, 150)) && '[60,70)'::int4range; QUERY PLAN ------------------------------------------------------------------- Seq Scan on test_range_expr_null Filter: ((rng * '[50,150)'::int4range) && '[60,70)'::int4range) (2 rows) SELECT COUNT(*) FROM stats_import.test_range_expr_null WHERE (rng * int4range(50, 150)) && '[60,70)'::int4range; count ------- 19 (1 row) DROP SCHEMA stats_import CASCADE; NOTICE: drop cascades to 19 other objects DETAIL: drop cascades to view stats_import.pg_stats_stable drop cascades to view stats_import.pg_statistic_flat_t drop cascades to function stats_import.pg_statistic_flat(text) drop cascades to function stats_import.pg_statistic_get_difference(text,text) drop cascades to view stats_import.pg_stats_ext_flat_t drop cascades to function stats_import.pg_stats_ext_flat(text) drop cascades to function stats_import.pg_stats_ext_get_difference(text,text) drop cascades to view stats_import.pg_stats_ext_exprs_flat_t drop cascades to function stats_import.pg_stats_ext_exprs_flat(text) drop cascades to function stats_import.pg_stats_ext_exprs_get_difference(text,text) drop cascades to type stats_import.complex_type drop cascades to table stats_import.test drop cascades to table stats_import.test_mr drop cascades to table stats_import.part_parent drop cascades to sequence stats_import.testseq drop cascades to view stats_import.testview drop cascades to table stats_import.test_clone drop cascades to table stats_import.test_mr_clone drop cascades to table stats_import.test_range_expr_null