From: Michael Paquier Date: Mon, 26 Jan 2026 23:20:13 +0000 (+0900) Subject: Add support for "dependencies" in pg_restore_extended_stats() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=302879bd68d1156fa27c38d29763ca9e4a1649c4;p=thirdparty%2Fpostgresql.git Add support for "dependencies" in pg_restore_extended_stats() This commit adds support for the restore of extended statistics of the kind "dependencies", for the following input data: [{"attributes": [2], "dependency": 3, "degree": 1.000000}, {"attributes": [3], "dependency": 2, "degree": 1.000000}] This relies on the existing routines of "dependencies" to cross-check the input data with the definition of the extended statistics objects for the attribute numbers. An input argument of type "pg_dependencies" is required for this new option. Thanks to the work done in 0e80f3f88dea for the restore function and e1405aa5e3ac for the input handling of data type pg_dependencies, this addition is straight-forward. This will be used so as it is possible to transfer these statistics across dumps and upgrades, removing the need for a post-operation ANALYZE for these kinds of statistics. Author: Corey Huinker Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CADkLM=dpz3KFnqP-dgJ-zvRvtjsa8UZv8wDAQdqho=qN3kX0Zg@mail.gmail.com --- diff --git a/doc/src/sgml/func/func-admin.sgml b/doc/src/sgml/func/func-admin.sgml index 3800cf3da09..ea42056bbc9 100644 --- a/doc/src/sgml/func/func-admin.sgml +++ b/doc/src/sgml/func/func-admin.sgml @@ -2194,9 +2194,8 @@ SELECT pg_restore_attribute_stats( - For example, to set the n_distinct, - dependencies, and exprs - values for the statistics object myschema.mystatsobj: + For example, to set some values for the statistics object + myschema.mystatsobj: SELECT pg_restore_extended_stats( 'schemaname', 'tab_schema'::name, @@ -2223,7 +2222,8 @@ SELECT pg_restore_attribute_stats( Other arguments are the names and values of statistics corresponding to columns in pg_stats_ext . - This function currently supports n_distinct. + This function currently supports n_distinct and + dependencies. Additionally, this function accepts argument name diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c index 48fa2efee76..18814093f50 100644 --- a/src/backend/statistics/extended_stats_funcs.c +++ b/src/backend/statistics/extended_stats_funcs.c @@ -45,6 +45,7 @@ enum extended_stats_argnum STATNAME_ARG, INHERITED_ARG, NDISTINCT_ARG, + DEPENDENCIES_ARG, NUM_EXTENDED_STATS_ARGS, }; @@ -60,6 +61,7 @@ static struct StatsArgInfo extarginfo[] = [STATNAME_ARG] = {"statistics_name", TEXTOID}, [INHERITED_ARG] = {"inherited", BOOLOID}, [NDISTINCT_ARG] = {"n_distinct", PG_NDISTINCTOID}, + [DEPENDENCIES_ARG] = {"dependencies", PG_DEPENDENCIESOID}, [NUM_EXTENDED_STATS_ARGS] = {0}, }; @@ -257,6 +259,7 @@ extended_statistics_update(FunctionCallInfo fcinfo) * were provided to the function. */ has.ndistinct = !PG_ARGISNULL(NDISTINCT_ARG); + has.dependencies = !PG_ARGISNULL(DEPENDENCIES_ARG); if (RecoveryInProgress()) { @@ -355,6 +358,23 @@ extended_statistics_update(FunctionCallInfo fcinfo) success = false; } + /* + * If the object cannot support dependencies, we should not have data for + * it. + */ + if (has.dependencies && !enabled.dependencies) + { + ereport(WARNING, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot specify parameter \"%s\".", + extarginfo[DEPENDENCIES_ARG].argname), + errhint("Extended statistics object \"%s\".\"%s\" does not support statistics of this type.", + quote_identifier(nspname), + quote_identifier(stxname))); + has.dependencies = false; + success = false; + } + /* * Populate the pg_statistic_ext_data result tuple. */ @@ -396,6 +416,24 @@ extended_statistics_update(FunctionCallInfo fcinfo) statext_ndistinct_free(ndistinct); } + if (has.dependencies) + { + Datum dependencies_datum = PG_GETARG_DATUM(DEPENDENCIES_ARG); + bytea *data = DatumGetByteaPP(dependencies_datum); + MVDependencies *dependencies = statext_dependencies_deserialize(data); + + if (statext_dependencies_validate(dependencies, &stxform->stxkeys, numexprs, WARNING)) + { + values[Anum_pg_statistic_ext_data_stxddependencies - 1] = dependencies_datum; + nulls[Anum_pg_statistic_ext_data_stxddependencies - 1] = false; + replaces[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; + } + else + success = false; + + statext_dependencies_free(dependencies); + } + upsert_pg_statistic_ext_data(values, nulls, replaces); cleanup: diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index 9c2362e70c6..b5664e5513c 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -1756,6 +1756,22 @@ HINT: Extended statistics object "stats_import"."test_stat_dependencies" does n 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', @@ -1769,6 +1785,35 @@ SELECT pg_catalog.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) + SELECT replace(e.n_distinct, '}, ', E'},\n') AS n_distinct FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index c9b1d9da2f7..3e70b817513 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -1258,6 +1258,15 @@ SELECT pg_catalog.pg_restore_extended_stats( 'statistics_name', 'test_stat_dependencies', 'inherited', false, 'n_distinct', '[{"attributes" : [1,3], "ndistinct" : 4}]'::pg_ndistinct); +-- 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); -- ok: ndistinct SELECT pg_catalog.pg_restore_extended_stats( @@ -1268,6 +1277,26 @@ SELECT pg_catalog.pg_restore_extended_stats( 'inherited', false, 'n_distinct', '[{"attributes" : [2,3], "ndistinct" : 4}]'::pg_ndistinct); +-- 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); + +-- 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); + SELECT replace(e.n_distinct, '}, ', E'},\n') AS n_distinct FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND