From d76f2bbdc5d03c69c3ca2fd519231c4a6571e338 Mon Sep 17 00:00:00 2001 From: shihao zhong Date: Mon, 12 Oct 2026 03:13:07 -0400 Subject: [PATCH v1 3/3] Test pg_restore_extended_stats with shifted attribute numbers. Restore n_distinct and dependencies for a table with a dropped column using stxkeys and stxkeynames. Also test a bad number and a bad name. --- src/test/regress/expected/stats_import.out | 68 +++++++++++++++++++++- src/test/regress/sql/stats_import.sql | 44 ++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index 87b0e032197..079be715fd1 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -4149,8 +4149,73 @@ SELECT COUNT(*) FROM stats_import.test_range_expr_null 19 (1 row) +-- Extended statistics restored from a table with different attribute +-- numbers. The source numbers are translated by column name. +CREATE TABLE stats_import.test_attnum_map (junk int, a int, b int, c int); +ALTER TABLE stats_import.test_attnum_map DROP COLUMN junk; +CREATE STATISTICS stats_import.stat_attnum_map (ndistinct, dependencies) + ON a, b, c FROM stats_import.test_attnum_map; +-- ok: in the source, a, b, c were attributes 1, 2, 3, now they are 2, 3, 4 +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,c}'::text[], + 'n_distinct', '[{"attributes": [1, 2], "ndistinct": 4}, + {"attributes": [1, 3], "ndistinct": 5}, + {"attributes": [2, 3], "ndistinct": 6}, + {"attributes": [1, 2, 3], "ndistinct": 7}]'::pg_ndistinct, + 'dependencies', '[{"attributes": [1], "dependency": 3, "degree": 0.5}]'::pg_dependencies); + pg_restore_extended_stats +--------------------------- + t +(1 row) + +SELECT n_distinct, dependencies FROM pg_stats_ext + WHERE statistics_schemaname = 'stats_import' + AND statistics_name = 'stat_attnum_map'; + n_distinct | dependencies +---------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------ + [{"attributes": [2, 3], "ndistinct": 4}, {"attributes": [2, 4], "ndistinct": 5}, {"attributes": [3, 4], "ndistinct": 6}, {"attributes": [2, 3, 4], "ndistinct": 7}] | [{"attributes": [2], "dependency": 4, "degree": 0.500000}] +(1 row) + +-- warn: attribute 4 is not one of the source keys +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,c}'::text[], + 'n_distinct', '[{"attributes": [1, 4], "ndistinct": 4}]'::pg_ndistinct); +WARNING: could not validate "pg_ndistinct" object: invalid attribute number 4 found + pg_restore_extended_stats +--------------------------- + f +(1 row) + +-- warn: a source column name that does not exist here +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,zzz}'::text[], + 'n_distinct', '[{"attributes": [1, 2], "ndistinct": 4}]'::pg_ndistinct); +WARNING: could not use "stxkeys" and "stxkeynames": they do not match extended statistics object "stats_import.stat_attnum_map" + pg_restore_extended_stats +--------------------------- + f +(1 row) + DROP SCHEMA stats_import CASCADE; -NOTICE: drop cascades to 27 other objects +NOTICE: drop cascades to 28 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) @@ -4178,3 +4243,4 @@ drop cascades to table stats_import.test_dom_ts_clone 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 +drop cascades to table stats_import.test_attnum_map diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index f24da5bf681..52548cb0aed 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -2898,4 +2898,48 @@ SELECT * FROM stats_import.test_range_expr_null SELECT COUNT(*) FROM stats_import.test_range_expr_null WHERE (rng * int4range(50, 150)) && '[60,70)'::int4range; +-- Extended statistics restored from a table with different attribute +-- numbers. The source numbers are translated by column name. +CREATE TABLE stats_import.test_attnum_map (junk int, a int, b int, c int); +ALTER TABLE stats_import.test_attnum_map DROP COLUMN junk; +CREATE STATISTICS stats_import.stat_attnum_map (ndistinct, dependencies) + ON a, b, c FROM stats_import.test_attnum_map; +-- ok: in the source, a, b, c were attributes 1, 2, 3, now they are 2, 3, 4 +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,c}'::text[], + 'n_distinct', '[{"attributes": [1, 2], "ndistinct": 4}, + {"attributes": [1, 3], "ndistinct": 5}, + {"attributes": [2, 3], "ndistinct": 6}, + {"attributes": [1, 2, 3], "ndistinct": 7}]'::pg_ndistinct, + 'dependencies', '[{"attributes": [1], "dependency": 3, "degree": 0.5}]'::pg_dependencies); +SELECT n_distinct, dependencies FROM pg_stats_ext + WHERE statistics_schemaname = 'stats_import' + AND statistics_name = 'stat_attnum_map'; +-- warn: attribute 4 is not one of the source keys +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,c}'::text[], + 'n_distinct', '[{"attributes": [1, 4], "ndistinct": 4}]'::pg_ndistinct); +-- warn: a source column name that does not exist here +SELECT pg_catalog.pg_restore_extended_stats( + 'schemaname', 'stats_import', + 'relname', 'test_attnum_map', + 'statistics_schemaname', 'stats_import', + 'statistics_name', 'stat_attnum_map', + 'inherited', false, + 'stxkeys', '{1,2,3}'::smallint[], + 'stxkeynames', '{a,b,zzz}'::text[], + 'n_distinct', '[{"attributes": [1, 2], "ndistinct": 4}]'::pg_ndistinct); + DROP SCHEMA stats_import CASCADE; -- 2.37.1 (Apple Git-137.1)