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 <corey.huinker@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CADkLM=dpz3KFnqP-dgJ-zvRvtjsa8UZv8wDAQdqho=qN3kX0Zg@mail.gmail.com
</programlisting>
</para>
<para>
- For example, to set the <structfield>n_distinct</structfield>,
- <structfield>dependencies</structfield>, and <structfield>exprs</structfield>
- values for the statistics object <structname>myschema.mystatsobj</structname>:
+ For example, to set some values for the statistics object
+ <structname>myschema.mystatsobj</structname>:
<programlisting>
SELECT pg_restore_extended_stats(
'schemaname', 'tab_schema'::name,
Other arguments are the names and values of statistics corresponding
to columns in <link linkend="view-pg-stats-ext"><structname>pg_stats_ext</structname>
</link>.
- This function currently supports <literal>n_distinct</literal>.
+ This function currently supports <literal>n_distinct</literal> and
+ <literal>dependencies</literal>.
</para>
<para>
Additionally, this function accepts argument name
STATNAME_ARG,
INHERITED_ARG,
NDISTINCT_ARG,
+ DEPENDENCIES_ARG,
NUM_EXTENDED_STATS_ARGS,
};
[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},
};
* were provided to the function.
*/
has.ndistinct = !PG_ARGISNULL(NDISTINCT_ARG);
+ has.dependencies = !PG_ARGISNULL(DEPENDENCIES_ARG);
if (RecoveryInProgress())
{
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.
*/
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:
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',
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
'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(
'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