> > +1, let's shorten those queries. The coast is probably pretty >> clear now if you want to go do that. > > > On it. >
The earlier conversion of pg_set_attribute_stats (which once had many not-null params) to pg_restore_* tests (where only the columns that identify the stat row are actually required) meant that a lot of parameters which were previously required were now inconsequential to the test. However, it is important to demonstrate cases where the rest of the restore operation completed after given bad statistic was encountered, but that can be adequately done by one "bystander" parameter rather than the whole fleet. Other notes: * organized the tests into roughly three groups: relation tests, attribute tests, and set-difference tests. * tests that raise an error bubble up to the top of their respective groups * tests that would have multiple warnings are reduced to having just one wherever possible * each test gets a comment about what is to be demonstrated * attention paid to parameter values to avoid coincidental values that could mislead someone into thinking the value was written somewhere when that just happened to be what was already there, etc. * the set difference tests remain, as they proved extremely useful in detecting undesirable side-effects during development
From f3087b04784d6853970bf41eb619281d72ce94bd Mon Sep 17 00:00:00 2001 From: Corey Huinker <corey.huin...@gmail.com> Date: Wed, 26 Feb 2025 21:02:44 -0500 Subject: [PATCH vTestReorg] Organize and deduplicate statistics import tests. Many changes, refactorings, and rebasings have taken their toll on the statistics import tests. Now that things appear more stable and the pg_set_* functions are gone in favor of using pg_restore_* in all cases, it's safe to remove duplicates, combine tests where possible, and make the test descriptions a bit more descriptive and uniform. --- src/test/regress/expected/stats_import.out | 672 +++++++++------------ src/test/regress/sql/stats_import.sql | 546 +++++++---------- 2 files changed, 500 insertions(+), 718 deletions(-) diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index 1f150f7b08d..eaa3fe0f812 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -13,17 +13,58 @@ CREATE TABLE stats_import.test( tags text[] ) WITH (autovacuum_enabled = false); CREATE INDEX test_i ON stats_import.test(id); +-- +-- relstats tests +-- +--- error: relation is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 0::oid, + 'relpages', 17::integer, + 'reltuples', 400.0::real, + 'relallvisible', 4::integer); +WARNING: argument "relation" has type "oid", expected type "regclass" +ERROR: "relation" cannot be NULL +-- error: relation not found +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 0::oid::regclass, + 'relpages', 17::integer, + 'reltuples', 400.0::real, + 'relallvisible', 4::integer); +ERROR: could not open relation with OID 0 +-- error: odd number of variadic arguments cannot be pairs +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + 'relpages', '17'::integer, + 'reltuples', 400::real, + 'relallvisible'); +ERROR: variadic arguments must be name/value pairs +HINT: Provide an even number of variadic arguments that can be divided into pairs. +-- error: argument name is NULL +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + NULL, '17'::integer, + 'relallvisible', 14::integer); +ERROR: name at variadic position 5 is NULL +-- error: argument name is not a text type +SELECT pg_restore_relation_stats( + 'relation', '0'::oid::regclass, + 'version', 150000::integer, + 17, '17'::integer, + 'relallvisible', 44::integer); +ERROR: name at variadic position 5 has type "integer", expected type "text" -- starting stats SELECT relpages, reltuples, relallvisible FROM pg_class -WHERE oid = 'stats_import.test'::regclass; +WHERE oid = 'stats_import.test_i'::regclass; relpages | reltuples | relallvisible ----------+-----------+--------------- - 0 | -1 | 0 + 1 | 0 | 0 (1 row) -BEGIN; -- regular indexes have special case locking rules +BEGIN; SELECT pg_catalog.pg_restore_relation_stats( 'relation', 'stats_import.test_i'::regclass, @@ -50,32 +91,6 @@ WHERE relation = 'stats_import.test_i'::regclass AND (1 row) COMMIT; -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.test_i'::regclass, - 'relpages', 19::integer ); - pg_restore_relation_stats ---------------------------- - t -(1 row) - --- clear -SELECT - pg_catalog.pg_clear_relation_stats( - 'stats_import.test'::regclass); - pg_clear_relation_stats -------------------------- - -(1 row) - -SELECT relpages, reltuples, relallvisible -FROM pg_class -WHERE oid = 'stats_import.test'::regclass; - relpages | reltuples | relallvisible -----------+-----------+--------------- - 0 | -1 | 0 -(1 row) - -- relpages may be -1 for partitioned tables CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i); CREATE TABLE stats_import.part_child_1 @@ -92,26 +107,6 @@ WHERE oid = 'stats_import.part_parent'::regclass; -1 (1 row) --- although partitioned tables have no storage, setting relpages to a --- positive value is still allowed -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, - 'relpages', 2::integer); - pg_restore_relation_stats ---------------------------- - t -(1 row) - -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent'::regclass, - 'relpages', 2::integer); - pg_restore_relation_stats ---------------------------- - t -(1 row) - -- -- Partitioned indexes aren't analyzed but it is possible to set -- stats. The locking rules are different from normal indexes due to @@ -145,30 +140,19 @@ WHERE relation = 'stats_import.part_parent_i'::regclass AND (1 row) COMMIT; -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, - 'relpages', 2::integer); - pg_restore_relation_stats ---------------------------- - t +SELECT relpages +FROM pg_class +WHERE oid = 'stats_import.part_parent_i'::regclass; + relpages +---------- + 2 (1 row) --- nothing stops us from setting it to -1 -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent'::regclass, - 'relpages', -1::integer); - pg_restore_relation_stats ---------------------------- - t -(1 row) - --- ok: set all stats +-- ok: set all stats, no bounds checking SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, - 'relpages', '17'::integer, + 'relpages', '-17'::integer, 'reltuples', 400::real, 'relallvisible', 4::integer); pg_restore_relation_stats @@ -181,10 +165,10 @@ FROM pg_class WHERE oid = 'stats_import.test'::regclass; relpages | reltuples | relallvisible ----------+-----------+--------------- - 17 | 400 | 4 + -17 | 400 | 4 (1 row) --- ok: just relpages +-- ok: set just relpages, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -202,7 +186,7 @@ WHERE oid = 'stats_import.test'::regclass; 16 | 400 | 4 (1 row) --- ok: just reltuples +-- ok: set just reltuples, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -220,7 +204,7 @@ WHERE oid = 'stats_import.test'::regclass; 16 | 500 | 4 (1 row) --- ok: just relallvisible +-- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -238,7 +222,7 @@ WHERE oid = 'stats_import.test'::regclass; 16 | 500 | 5 (1 row) --- warn: bad relpages type +-- warn: bad relpages type, rest updated SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -259,20 +243,136 @@ WHERE oid = 'stats_import.test'::regclass; 16 | 400 | 4 (1 row) +-- unrecognized argument name, rest ok +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + 'relpages', '171'::integer, + 'nope', 10::integer); +WARNING: unrecognized argument name: "nope" + pg_restore_relation_stats +--------------------------- + f +(1 row) + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + relpages | reltuples | relallvisible +----------+-----------+--------------- + 171 | 400 | 4 +(1 row) + +-- ok: clear stats +SELECT pg_catalog.pg_clear_relation_stats( + relation => 'stats_import.test'::regclass); + pg_clear_relation_stats +------------------------- + +(1 row) + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + relpages | reltuples | relallvisible +----------+-----------+--------------- + 0 | -1 | 0 +(1 row) + -- invalid relkinds for statistics CREATE SEQUENCE stats_import.testseq; -CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; -SELECT - pg_catalog.pg_clear_relation_stats( +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 'stats_import.testseq'::regclass); +ERROR: cannot modify statistics for relation "testseq" +DETAIL: This operation is not supported for sequences. +SELECT pg_catalog.pg_clear_relation_stats( 'stats_import.testseq'::regclass); ERROR: cannot modify statistics for relation "testseq" DETAIL: This operation is not supported for sequences. -SELECT - pg_catalog.pg_clear_relation_stats( +CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 'stats_import.testview'::regclass); +ERROR: cannot modify statistics for relation "testview" +DETAIL: This operation is not supported for views. +SELECT pg_catalog.pg_clear_relation_stats( 'stats_import.testview'::regclass); ERROR: cannot modify statistics for relation "testview" DETAIL: This operation is not supported for views. --- ok: no stakinds +-- +-- attribute stats +-- +-- error: object does not exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', '0'::oid::regclass, + 'attname', 'id'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: could not open relation with OID 0 +-- error: relation null +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', NULL::oid::regclass, + 'attname', 'id'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: "relation" cannot be NULL +-- error: NULL attname +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', NULL::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: must specify either attname or attnum +-- error: attname doesn't exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'nope'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real, + 'avg_width', 2::integer, + 'n_distinct', 0.3::real); +ERROR: column "nope" of relation "test" does not exist +-- error: both attname and attnum +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'id'::name, + 'attnum', 1::smallint, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: cannot specify both attname and attnum +-- error: neither attname nor attnum +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: must specify either attname or attnum +-- error: attribute is system column +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'xmin'::name, + 'inherited', false::boolean, + 'null_frac', 0.1::real); +ERROR: cannot modify statistics on system column "xmin" +-- error: inherited null +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'id'::name, + 'inherited', NULL::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); +ERROR: "inherited" cannot be NULL +-- error: attribute is system column +SELECT pg_catalog.pg_clear_attribute_stats( + relation => 'stats_import.test'::regclass, + attname => 'ctid'::name, + inherited => false::boolean); +ERROR: cannot clear statistics on system column "ctid" +-- ok: just the fixed values, no stakinds SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, @@ -297,15 +397,17 @@ AND attname = 'id'; stats_import | test | id | f | 0.2 | 5 | 0.6 | | | | | | | | | | (1 row) --- ok: restore by attnum +-- +-- ok: restore by attnum, we normally reserve this for +-- indexes, but there is no reason it shouldn't work +-- for any stat-having relation. +-- SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attnum', 1::smallint, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.4::real, - 'avg_width', 5::integer, - 'n_distinct', 0.6::real); + 'null_frac', 0.4::real); pg_restore_attribute_stats ---------------------------- t @@ -322,14 +424,13 @@ AND attname = 'id'; stats_import | test | id | f | 0.4 | 5 | 0.6 | | | | | | | | | | (1 row) --- warn: unrecognized argument name +-- warn: unrecognized argument name, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, 'null_frac', 0.2::real, - 'avg_width', NULL::integer, 'nope', 0.5::real); WARNING: unrecognized argument name: "nope" pg_restore_attribute_stats @@ -348,15 +449,13 @@ AND attname = 'id'; stats_import | test | id | f | 0.2 | 5 | 0.6 | | | | | | | | | | (1 row) --- warn: mcv / mcf null mismatch part 1 +-- warn: mcv / mcf null mismatch part 1, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.6::real, - 'avg_width', 7::integer, - 'n_distinct', -0.7::real, + 'null_frac', 0.21::real, 'most_common_freqs', '{0.1,0.2,0.3}'::real[] ); WARNING: "most_common_vals" must be specified when "most_common_freqs" is specified @@ -373,18 +472,16 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.6 | 7 | -0.7 | | | | | | | | | | + stats_import | test | id | f | 0.21 | 5 | 0.6 | | | | | | | | | | (1 row) --- warn: mcv / mcf null mismatch part 2 +-- warn: mcv / mcf null mismatch part 2, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.7::real, - 'avg_width', 8::integer, - 'n_distinct', -0.8::real, + 'null_frac', 0.21::real, 'most_common_vals', '{1,2,3}'::text ); WARNING: "most_common_freqs" must be specified when "most_common_vals" is specified @@ -401,18 +498,16 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.7 | 8 | -0.8 | | | | | | | | | | + stats_import | test | id | f | 0.21 | 5 | 0.6 | | | | | | | | | | (1 row) --- warn: mcv / mcf type mismatch +-- warn: mcf type mismatch, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.8::real, - 'avg_width', 9::integer, - 'n_distinct', -0.9::real, + 'null_frac', 0.22::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.2,0.1}'::double precision[] ); @@ -431,18 +526,16 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.8 | 9 | -0.9 | | | | | | | | | | + stats_import | test | id | f | 0.22 | 5 | 0.6 | | | | | | | | | | (1 row) --- warn: mcv cast failure +-- warn: mcv cast failure, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.9::real, - 'avg_width', 10::integer, - 'n_distinct', -0.4::real, + 'null_frac', 0.23::real, 'most_common_vals', '{2,four,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); @@ -460,7 +553,7 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.9 | 10 | -0.4 | | | | | | | | | | + stats_import | test | id | f | 0.23 | 5 | 0.6 | | | | | | | | | | (1 row) -- ok: mcv+mcf @@ -469,9 +562,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 1::integer, - 'n_distinct', -0.1::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); @@ -488,18 +578,16 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.1 | 1 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | + stats_import | test | id | f | 0.23 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | (1 row) --- warn: NULL in histogram array +-- warn: NULL in histogram array, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.2::real, - 'avg_width', 2::integer, - 'n_distinct', -0.2::real, + 'null_frac', 0.24::real, 'histogram_bounds', '{1,NULL,3,4}'::text ); WARNING: "histogram_bounds" array cannot contain NULL values @@ -516,7 +604,7 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.2 | 2 | -0.2 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | + stats_import | test | id | f | 0.24 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | | (1 row) -- ok: histogram_bounds @@ -525,10 +613,8 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.3::real, - 'avg_width', 3::integer, - 'n_distinct', -0.3::real, - 'histogram_bounds', '{1,2,3,4}'::text ); + 'histogram_bounds', '{1,2,3,4}'::text + ); pg_restore_attribute_stats ---------------------------- t @@ -542,19 +628,17 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.3 | 3 | -0.3 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | + stats_import | test | id | f | 0.24 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) --- warn: elem_count_histogram null element +-- warn: elem_count_histogram null element, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.4::real, - 'avg_width', 5::integer, - 'n_distinct', -0.4::real, - 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] + 'null_frac', 0.25::real, + 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] ); WARNING: "elem_count_histogram" array cannot contain NULL values pg_restore_attribute_stats @@ -570,7 +654,7 @@ AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | tags | f | 0.4 | 5 | -0.4 | | | | | | | | | | + stats_import | test | tags | f | 0.25 | 0 | 0 | | | | | | | | | | (1 row) -- ok: elem_count_histogram @@ -579,9 +663,7 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'tags'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.5::real, - 'avg_width', 6::integer, - 'n_distinct', -0.55::real, + 'null_frac', 0.26::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] ); pg_restore_attribute_stats @@ -597,18 +679,16 @@ AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ - stats_import | test | tags | f | 0.5 | 6 | -0.55 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | + stats_import | test | tags | f | 0.26 | 0 | 0 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) --- range stats on a scalar type +-- warn: range stats on a scalar type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.6::real, - 'avg_width', 7::integer, - 'n_distinct', -0.15::real, + 'null_frac', 0.27::real, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); @@ -627,18 +707,16 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.6 | 7 | -0.15 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | + stats_import | test | id | f | 0.27 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) --- warn: range_empty_frac range_length_hist null mismatch +-- warn: range_empty_frac range_length_hist null mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.7::real, - 'avg_width', 8::integer, - 'n_distinct', -0.25::real, + 'null_frac', 0.28::real, 'range_length_histogram', '{399,499,Infinity}'::text ); WARNING: "range_empty_frac" must be specified when "range_length_histogram" is specified @@ -655,18 +733,16 @@ AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | arange | f | 0.7 | 8 | -0.25 | | | | | | | | | | + stats_import | test | arange | f | 0.28 | 0 | 0 | | | | | | | | | | (1 row) --- warn: range_empty_frac range_length_hist null mismatch part 2 +-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.8::real, - 'avg_width', 9::integer, - 'n_distinct', -0.35::real, + 'null_frac', 0.29::real, 'range_empty_frac', 0.5::real ); WARNING: "range_length_histogram" must be specified when "range_empty_frac" is specified @@ -683,7 +759,7 @@ AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | arange | f | 0.8 | 9 | -0.35 | | | | | | | | | | + stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | | | (1 row) -- ok: range_empty_frac + range_length_hist @@ -692,9 +768,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.9::real, - 'avg_width', 1::integer, - 'n_distinct', -0.19::real, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); @@ -711,18 +784,16 @@ AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | arange | f | 0.9 | 1 | -0.19 | | | | | | | | {399,499,Infinity} | 0.5 | + stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | (1 row) --- warn: range bounds histogram on scalar +-- warn: range bounds histogram on scalar, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', -0.29::real, + 'null_frac', 0.31::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); WARNING: attribute "id" is not a range type @@ -740,7 +811,7 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.1 | 2 | -0.29 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | + stats_import | test | id | f | 0.31 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- ok: range_bounds_histogram @@ -749,9 +820,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.2::real, - 'avg_width', 3::integer, - 'n_distinct', -0.39::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); pg_restore_attribute_stats @@ -767,26 +835,17 @@ AND inherited = false AND attname = 'arange'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- - stats_import | test | arange | f | 0.2 | 3 | -0.39 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} + stats_import | test | arange | f | 0.29 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} (1 row) --- warn: cannot set most_common_elems for range type +-- warn: cannot set most_common_elems for range type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text, - 'most_common_freqs', '{0.3,0.25,0.05}'::real[], - 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text, - 'correlation', 1.1::real, + 'null_frac', 0.32::real, 'most_common_elems', '{3,1}'::text, - 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[], - 'range_empty_frac', -0.5::real, - 'range_length_histogram', '{399,499,Infinity}'::text, - 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); WARNING: unable to determine element type of attribute "arange" DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. @@ -801,19 +860,17 @@ WHERE schemaname = 'stats_import' AND tablename = 'test' AND inherited = false AND attname = 'arange'; - schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram ---------------+-----------+---------+-----------+-----------+-----------+------------+---------------------------+-------------------+-----------------------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- - stats_import | test | arange | f | 0.5 | 2 | -0.1 | {"[2,3)","[1,2)","[3,4)"} | {0.3,0.25,0.05} | {"[1,2)","[2,3)","[3,4)","[4,5)"} | 1.1 | | | | {399,499,Infinity} | -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} + schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram +--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- + stats_import | test | arange | f | 0.32 | 0 | 0 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} (1 row) --- warn: scalars can't have mcelem +-- warn: scalars can't have mcelem, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.33::real, 'most_common_elems', '{1,3}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); @@ -832,17 +889,15 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | + stats_import | test | id | f | 0.33 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) --- warn: mcelem / mcelem mismatch +-- warn: mcelem / mcelem mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.34::real, 'most_common_elems', '{one,two}'::text ); WARNING: "most_common_elem_freqs" must be specified when "most_common_elems" is specified @@ -859,17 +914,15 @@ AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ - stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | + stats_import | test | tags | f | 0.34 | 0 | 0 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) --- warn: mcelem / mcelem null mismatch part 2 +-- warn: mcelem / mcelem null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.35::real, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] ); WARNING: "most_common_elems" must be specified when "most_common_elem_freqs" is specified @@ -878,14 +931,22 @@ WARNING: "most_common_elems" must be specified when "most_common_elem_freqs" is f (1 row) +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram +--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ + stats_import | test | tags | f | 0.35 | 0 | 0 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | +(1 row) + -- ok: mcelem SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, 'most_common_elems', '{one,three}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); @@ -902,18 +963,16 @@ AND inherited = false AND attname = 'tags'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------ - stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | + stats_import | test | tags | f | 0.35 | 0 | 0 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | | (1 row) --- warn: scalars can't have elem_count_histogram +-- warn: scalars can't have elem_count_histogram, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] + 'null_frac', 0.36::real, + 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] ); WARNING: unable to determine element type of attribute "id" DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. @@ -930,43 +989,7 @@ AND inherited = false AND attname = 'id'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram --------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------ - stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | -(1 row) - --- warn: too many stat kinds -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'most_common_vals', '{"[2,3)","[1,3)","[3,9)"}'::text, - 'most_common_freqs', '{0.3,0.25,0.05}'::real[], - 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,)"}'::text, - 'correlation', 1.1::real, - 'most_common_elems', '{3,1}'::text, - 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[], - 'range_empty_frac', -0.5::real, - 'range_length_histogram', '{399,499,Infinity}'::text, - 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text); -WARNING: unable to determine element type of attribute "arange" -DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST. - pg_restore_attribute_stats ----------------------------- - f -(1 row) - -SELECT * -FROM pg_stats -WHERE schemaname = 'stats_import' -AND tablename = 'test' -AND inherited = false -AND attname = 'arange'; - schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram | range_length_histogram | range_empty_frac | range_bounds_histogram ---------------+-----------+---------+-----------+-----------+-----------+------------+---------------------------+-------------------+----------------------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+-------------------------------------- - stats_import | test | arange | f | 0.5 | 2 | -0.1 | {"[2,3)","[1,3)","[3,9)"} | {0.3,0.25,0.05} | {"[1,2)","[2,3)","[3,4)","[4,)"} | 1.1 | | | | {399,499,Infinity} | -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"} + stats_import | test | id | f | 0.36 | 5 | 0.6 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | | (1 row) -- @@ -986,19 +1009,6 @@ SELECT 3, 'tre', (3, 3.3, 'TRE', '2003-03-03', NULL)::stats_import.complex_type, UNION ALL SELECT 4, 'four', NULL, int4range(0,100), NULL; CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1)); --- restoring stats on index -SELECT * FROM pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.is_odd'::regclass, - 'version', '180000'::integer, - 'relpages', '11'::integer, - 'reltuples', '10000'::real, - 'relallvisible', '0'::integer -); - pg_restore_relation_stats ---------------------------- - t -(1 row) - -- Generate statistics on table with data ANALYZE stats_import.test; CREATE TABLE stats_import.test_clone ( LIKE stats_import.test ) @@ -1176,7 +1186,18 @@ WHERE s.starelid = 'stats_import.is_odd'::regclass; ---------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+----------- (0 rows) --- ok +-- attribute stats exist before a clear, but not after +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + count +------- + 1 +(1 row) + SELECT pg_catalog.pg_clear_attribute_stats( relation => 'stats_import.test'::regclass, attname => 'arange'::name, @@ -1186,154 +1207,17 @@ SELECT pg_catalog.pg_clear_attribute_stats( (1 row) --- --- Negative tests --- ---- error: relation is wrong type -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid, - 'relpages', 17::integer, - 'reltuples', 400.0::real, - 'relallvisible', 4::integer); -WARNING: argument "relation" has type "oid", expected type "regclass" -ERROR: "relation" cannot be NULL ---- error: relation not found -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::regclass, - 'relpages', 17::integer, - 'reltuples', 400.0::real, - 'relallvisible', 4::integer); -ERROR: could not open relation with OID 0 --- warn and error: unrecognized argument name -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'nope', 4::integer); -WARNING: unrecognized argument name: "nope" -ERROR: could not open relation with OID 0 --- error: argument name is NULL -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - NULL, '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); -ERROR: name at variadic position 5 is NULL --- error: argument name is an integer -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 17, '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); -ERROR: name at variadic position 5 has type "integer", expected type "text" --- error: odd number of variadic arguments cannot be pairs -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'relallvisible'); -ERROR: variadic arguments must be name/value pairs -HINT: Provide an even number of variadic arguments that can be divided into pairs. --- error: object doesn't exist -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); -ERROR: could not open relation with OID 0 --- error: object does not exist -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', '0'::oid::regclass, - 'attname', 'id'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: could not open relation with OID 0 --- error: relation null -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', NULL::oid, - 'attname', 'id'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: "relation" cannot be NULL --- error: missing attname -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', NULL::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: must specify either attname or attnum --- error: both attname and attnum -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, - 'attnum', 1::smallint, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: cannot specify both attname and attnum --- error: attname doesn't exist -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'nope'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: column "nope" of relation "test" does not exist --- error: attribute is system column -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'xmin'::name, - 'inherited', false::boolean, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: cannot modify statistics on system column "xmin" --- error: inherited null -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, - 'inherited', NULL::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); -ERROR: "inherited" cannot be NULL --- error: relation not found -SELECT pg_catalog.pg_clear_relation_stats( - relation => 'stats_import.nope'::regclass); -ERROR: relation "stats_import.nope" does not exist -LINE 2: relation => 'stats_import.nope'::regclass); - ^ --- error: attribute is system column -SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'ctid'::name, - inherited => false::boolean); -ERROR: cannot clear statistics on system column "ctid" --- error: attname doesn't exist -SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'nope'::name, - inherited => false::boolean); -ERROR: column "nope" of relation "test" does not exist +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + count +------- + 0 +(1 row) + DROP SCHEMA stats_import CASCADE; NOTICE: drop cascades to 6 other objects DETAIL: drop cascades to type stats_import.complex_type diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index 8c183bceb8a..69e6cc960de 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -17,13 +17,53 @@ CREATE TABLE stats_import.test( CREATE INDEX test_i ON stats_import.test(id); +-- +-- relstats tests +-- + +--- error: relation is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 0::oid, + 'relpages', 17::integer, + 'reltuples', 400.0::real, + 'relallvisible', 4::integer); + +-- error: relation not found +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 0::oid::regclass, + 'relpages', 17::integer, + 'reltuples', 400.0::real, + 'relallvisible', 4::integer); + +-- error: odd number of variadic arguments cannot be pairs +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + 'relpages', '17'::integer, + 'reltuples', 400::real, + 'relallvisible'); + +-- error: argument name is NULL +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + NULL, '17'::integer, + 'relallvisible', 14::integer); + +-- error: argument name is not a text type +SELECT pg_restore_relation_stats( + 'relation', '0'::oid::regclass, + 'version', 150000::integer, + 17, '17'::integer, + 'relallvisible', 44::integer); + -- starting stats SELECT relpages, reltuples, relallvisible FROM pg_class -WHERE oid = 'stats_import.test'::regclass; +WHERE oid = 'stats_import.test_i'::regclass; -BEGIN; -- regular indexes have special case locking rules +BEGIN; SELECT pg_catalog.pg_restore_relation_stats( 'relation', 'stats_import.test_i'::regclass, @@ -39,20 +79,6 @@ WHERE relation = 'stats_import.test_i'::regclass AND COMMIT; -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.test_i'::regclass, - 'relpages', 19::integer ); - --- clear -SELECT - pg_catalog.pg_clear_relation_stats( - 'stats_import.test'::regclass); - -SELECT relpages, reltuples, relallvisible -FROM pg_class -WHERE oid = 'stats_import.test'::regclass; - -- relpages may be -1 for partitioned tables CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i); CREATE TABLE stats_import.part_child_1 @@ -68,18 +94,6 @@ SELECT relpages FROM pg_class WHERE oid = 'stats_import.part_parent'::regclass; --- although partitioned tables have no storage, setting relpages to a --- positive value is still allowed -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, - 'relpages', 2::integer); - -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent'::regclass, - 'relpages', 2::integer); - -- -- Partitioned indexes aren't analyzed but it is possible to set -- stats. The locking rules are different from normal indexes due to @@ -103,22 +117,15 @@ WHERE relation = 'stats_import.part_parent_i'::regclass AND COMMIT; -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, - 'relpages', 2::integer); +SELECT relpages +FROM pg_class +WHERE oid = 'stats_import.part_parent_i'::regclass; --- nothing stops us from setting it to -1 -SELECT - pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent'::regclass, - 'relpages', -1::integer); - --- ok: set all stats +-- ok: set all stats, no bounds checking SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, - 'relpages', '17'::integer, + 'relpages', '-17'::integer, 'reltuples', 400::real, 'relallvisible', 4::integer); @@ -126,7 +133,7 @@ SELECT relpages, reltuples, relallvisible FROM pg_class WHERE oid = 'stats_import.test'::regclass; --- ok: just relpages +-- ok: set just relpages, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -136,7 +143,7 @@ SELECT relpages, reltuples, relallvisible FROM pg_class WHERE oid = 'stats_import.test'::regclass; --- ok: just reltuples +-- ok: set just reltuples, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -146,7 +153,7 @@ SELECT relpages, reltuples, relallvisible FROM pg_class WHERE oid = 'stats_import.test'::regclass; --- ok: just relallvisible +-- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -156,7 +163,7 @@ SELECT relpages, reltuples, relallvisible FROM pg_class WHERE oid = 'stats_import.test'::regclass; --- warn: bad relpages type +-- warn: bad relpages type, rest updated SELECT pg_restore_relation_stats( 'relation', 'stats_import.test'::regclass, 'version', 150000::integer, @@ -168,17 +175,118 @@ SELECT relpages, reltuples, relallvisible FROM pg_class WHERE oid = 'stats_import.test'::regclass; +-- unrecognized argument name, rest ok +SELECT pg_restore_relation_stats( + 'relation', 'stats_import.test'::regclass, + 'version', 150000::integer, + 'relpages', '171'::integer, + 'nope', 10::integer); + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +-- ok: clear stats +SELECT pg_catalog.pg_clear_relation_stats( + relation => 'stats_import.test'::regclass); + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + -- invalid relkinds for statistics CREATE SEQUENCE stats_import.testseq; -CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; -SELECT - pg_catalog.pg_clear_relation_stats( + +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 'stats_import.testseq'::regclass); + +SELECT pg_catalog.pg_clear_relation_stats( 'stats_import.testseq'::regclass); -SELECT - pg_catalog.pg_clear_relation_stats( + +CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; + +SELECT pg_catalog.pg_restore_relation_stats( + 'relation', 'stats_import.testview'::regclass); + +SELECT pg_catalog.pg_clear_relation_stats( 'stats_import.testview'::regclass); --- ok: no stakinds +-- +-- attribute stats +-- + +-- error: object does not exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', '0'::oid::regclass, + 'attname', 'id'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: relation null +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', NULL::oid::regclass, + 'attname', 'id'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: NULL attname +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', NULL::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: attname doesn't exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'nope'::name, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real, + 'avg_width', 2::integer, + 'n_distinct', 0.3::real); + +-- error: both attname and attnum +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'id'::name, + 'attnum', 1::smallint, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: neither attname nor attnum +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: attribute is system column +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'xmin'::name, + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +-- error: inherited null +SELECT pg_catalog.pg_restore_attribute_stats( + 'relation', 'stats_import.test'::regclass, + 'attname', 'id'::name, + 'inherited', NULL::boolean, + 'version', 150000::integer, + 'null_frac', 0.1::real); + +-- error: attribute is system column +SELECT pg_catalog.pg_clear_attribute_stats( + relation => 'stats_import.test'::regclass, + attname => 'ctid'::name, + inherited => false::boolean); + +-- ok: just the fixed values, no stakinds SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, @@ -195,15 +303,17 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- ok: restore by attnum +-- +-- ok: restore by attnum, we normally reserve this for +-- indexes, but there is no reason it shouldn't work +-- for any stat-having relation. +-- SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attnum', 1::smallint, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.4::real, - 'avg_width', 5::integer, - 'n_distinct', 0.6::real); + 'null_frac', 0.4::real); SELECT * FROM pg_stats @@ -212,14 +322,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: unrecognized argument name +-- warn: unrecognized argument name, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, 'null_frac', 0.2::real, - 'avg_width', NULL::integer, 'nope', 0.5::real); SELECT * @@ -229,15 +338,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: mcv / mcf null mismatch part 1 +-- warn: mcv / mcf null mismatch part 1, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.6::real, - 'avg_width', 7::integer, - 'n_distinct', -0.7::real, + 'null_frac', 0.21::real, 'most_common_freqs', '{0.1,0.2,0.3}'::real[] ); @@ -248,15 +355,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: mcv / mcf null mismatch part 2 +-- warn: mcv / mcf null mismatch part 2, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.7::real, - 'avg_width', 8::integer, - 'n_distinct', -0.8::real, + 'null_frac', 0.21::real, 'most_common_vals', '{1,2,3}'::text ); @@ -267,15 +372,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: mcv / mcf type mismatch +-- warn: mcf type mismatch, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.8::real, - 'avg_width', 9::integer, - 'n_distinct', -0.9::real, + 'null_frac', 0.22::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.2,0.1}'::double precision[] ); @@ -287,15 +390,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: mcv cast failure +-- warn: mcv cast failure, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.9::real, - 'avg_width', 10::integer, - 'n_distinct', -0.4::real, + 'null_frac', 0.23::real, 'most_common_vals', '{2,four,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); @@ -313,9 +414,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 1::integer, - 'n_distinct', -0.1::real, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] ); @@ -327,15 +425,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: NULL in histogram array +-- warn: NULL in histogram array, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.2::real, - 'avg_width', 2::integer, - 'n_distinct', -0.2::real, + 'null_frac', 0.24::real, 'histogram_bounds', '{1,NULL,3,4}'::text ); @@ -352,10 +448,8 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.3::real, - 'avg_width', 3::integer, - 'n_distinct', -0.3::real, - 'histogram_bounds', '{1,2,3,4}'::text ); + 'histogram_bounds', '{1,2,3,4}'::text + ); SELECT * FROM pg_stats @@ -364,16 +458,14 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: elem_count_histogram null element +-- warn: elem_count_histogram null element, rest get set SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.4::real, - 'avg_width', 5::integer, - 'n_distinct', -0.4::real, - 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] + 'null_frac', 0.25::real, + 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] ); SELECT * @@ -389,9 +481,7 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'tags'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.5::real, - 'avg_width', 6::integer, - 'n_distinct', -0.55::real, + 'null_frac', 0.26::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] ); @@ -402,15 +492,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'tags'; --- range stats on a scalar type +-- warn: range stats on a scalar type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.6::real, - 'avg_width', 7::integer, - 'n_distinct', -0.15::real, + 'null_frac', 0.27::real, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); @@ -422,15 +510,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: range_empty_frac range_length_hist null mismatch +-- warn: range_empty_frac range_length_hist null mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.7::real, - 'avg_width', 8::integer, - 'n_distinct', -0.25::real, + 'null_frac', 0.28::real, 'range_length_histogram', '{399,499,Infinity}'::text ); @@ -441,15 +527,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'arange'; --- warn: range_empty_frac range_length_hist null mismatch part 2 +-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.8::real, - 'avg_width', 9::integer, - 'n_distinct', -0.35::real, + 'null_frac', 0.29::real, 'range_empty_frac', 0.5::real ); @@ -466,9 +550,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.9::real, - 'avg_width', 1::integer, - 'n_distinct', -0.19::real, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text ); @@ -480,15 +561,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'arange'; --- warn: range bounds histogram on scalar +-- warn: range bounds histogram on scalar, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', -0.29::real, + 'null_frac', 0.31::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); @@ -505,9 +584,6 @@ SELECT pg_catalog.pg_restore_attribute_stats( 'attname', 'arange'::name, 'inherited', false::boolean, 'version', 150000::integer, - 'null_frac', 0.2::real, - 'avg_width', 3::integer, - 'n_distinct', -0.39::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); @@ -518,23 +594,14 @@ AND tablename = 'test' AND inherited = false AND attname = 'arange'; --- warn: cannot set most_common_elems for range type +-- warn: cannot set most_common_elems for range type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'arange'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text, - 'most_common_freqs', '{0.3,0.25,0.05}'::real[], - 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text, - 'correlation', 1.1::real, + 'null_frac', 0.32::real, 'most_common_elems', '{3,1}'::text, - 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[], - 'range_empty_frac', -0.5::real, - 'range_length_histogram', '{399,499,Infinity}'::text, - 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); SELECT * @@ -544,14 +611,12 @@ AND tablename = 'test' AND inherited = false AND attname = 'arange'; --- warn: scalars can't have mcelem +-- warn: scalars can't have mcelem, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.33::real, 'most_common_elems', '{1,3}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); @@ -563,14 +628,12 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: mcelem / mcelem mismatch +-- warn: mcelem / mcelem mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.34::real, 'most_common_elems', '{one,two}'::text ); @@ -581,25 +644,27 @@ AND tablename = 'test' AND inherited = false AND attname = 'tags'; --- warn: mcelem / mcelem null mismatch part 2 +-- warn: mcelem / mcelem null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, + 'null_frac', 0.35::real, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] ); +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + -- ok: mcelem SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'tags'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, 'most_common_elems', '{one,three}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] ); @@ -611,15 +676,13 @@ AND tablename = 'test' AND inherited = false AND attname = 'tags'; --- warn: scalars can't have elem_count_histogram +-- warn: scalars can't have elem_count_histogram, rest ok SELECT pg_catalog.pg_restore_attribute_stats( 'relation', 'stats_import.test'::regclass, 'attname', 'id'::name, 'inherited', false::boolean, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] + 'null_frac', 0.36::real, + 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] ); SELECT * @@ -629,32 +692,6 @@ AND tablename = 'test' AND inherited = false AND attname = 'id'; --- warn: too many stat kinds -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.5::real, - 'avg_width', 2::integer, - 'n_distinct', -0.1::real, - 'most_common_vals', '{"[2,3)","[1,3)","[3,9)"}'::text, - 'most_common_freqs', '{0.3,0.25,0.05}'::real[], - 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,)"}'::text, - 'correlation', 1.1::real, - 'most_common_elems', '{3,1}'::text, - 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[], - 'range_empty_frac', -0.5::real, - 'range_length_histogram', '{399,499,Infinity}'::text, - 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text); - -SELECT * -FROM pg_stats -WHERE schemaname = 'stats_import' -AND tablename = 'test' -AND inherited = false -AND attname = 'arange'; - -- -- Test the ability to exactly copy data from one table to an identical table, -- correctly reconstructing the stakind order as well as the staopN and @@ -674,15 +711,6 @@ SELECT 4, 'four', NULL, int4range(0,100), NULL; CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1)); --- restoring stats on index -SELECT * FROM pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.is_odd'::regclass, - 'version', '180000'::integer, - 'relpages', '11'::integer, - 'reltuples', '10000'::real, - 'relallvisible', '0'::integer -); - -- Generate statistics on table with data ANALYZE stats_import.test; @@ -835,154 +863,24 @@ FROM pg_statistic s JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum WHERE s.starelid = 'stats_import.is_odd'::regclass; --- ok +-- attribute stats exist before a clear, but not after +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + SELECT pg_catalog.pg_clear_attribute_stats( relation => 'stats_import.test'::regclass, attname => 'arange'::name, inherited => false::boolean); --- --- Negative tests --- - ---- error: relation is wrong type -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid, - 'relpages', 17::integer, - 'reltuples', 400.0::real, - 'relallvisible', 4::integer); - ---- error: relation not found -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::regclass, - 'relpages', 17::integer, - 'reltuples', 400.0::real, - 'relallvisible', 4::integer); - --- warn and error: unrecognized argument name -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'nope', 4::integer); - --- error: argument name is NULL -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - NULL, '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); - --- error: argument name is an integer -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 17, '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); - --- error: odd number of variadic arguments cannot be pairs -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'relallvisible'); - --- error: object doesn't exist -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 'version', 150000::integer, - 'relpages', '17'::integer, - 'reltuples', 400::real, - 'relallvisible', 4::integer); - --- error: object does not exist -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', '0'::oid::regclass, - 'attname', 'id'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: relation null -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', NULL::oid, - 'attname', 'id'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: missing attname -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', NULL::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: both attname and attnum -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, - 'attnum', 1::smallint, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: attname doesn't exist -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'nope'::name, - 'inherited', false::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: attribute is system column -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'xmin'::name, - 'inherited', false::boolean, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: inherited null -SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, - 'inherited', NULL::boolean, - 'version', 150000::integer, - 'null_frac', 0.1::real, - 'avg_width', 2::integer, - 'n_distinct', 0.3::real); - --- error: relation not found -SELECT pg_catalog.pg_clear_relation_stats( - relation => 'stats_import.nope'::regclass); - --- error: attribute is system column -SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'ctid'::name, - inherited => false::boolean); - --- error: attname doesn't exist -SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'nope'::name, - inherited => false::boolean); +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; DROP SCHEMA stats_import CASCADE; base-commit: 62ec3e1f6786181431210643a2d427b9a98b8af8 -- 2.48.1