From d7784344917035d197fcc3f66e724f4f28036bf7 Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Tue, 14 Jul 2026 12:26:12 +0000 Subject: [PATCH] Dump index column statistics for index-backed constraints dumpIndex emits ALTER INDEX ... SET STATISTICS, but the matching code was missing from dumpConstraint. Stats targets on exclusion constraint index expressions were silently lost on dump/restore and pg_upgrade. Add the same block to dumpConstraint. --- src/bin/pg_dump/pg_dump.c | 41 ++++++++++++++++++++++++++++++++ src/bin/pg_dump/t/002_pg_dump.pl | 20 ++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 4948e6d80c7..0a1423860ca 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -18939,6 +18939,47 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo) fmtId(indxinfo->dobj.name)); } + /* + * If the index has any statistics on some of its columns, generate + * the associated ALTER INDEX queries. + */ + if (strlen(indxinfo->indstatcols) != 0 || + strlen(indxinfo->indstatvals) != 0) + { + char **indstatcolsarray = NULL; + char **indstatvalsarray = NULL; + int nstatcols = 0; + int nstatvals = 0; + int j; + + if (!parsePGArray(indxinfo->indstatcols, &indstatcolsarray, + &nstatcols)) + pg_fatal("could not parse index statistic columns"); + if (!parsePGArray(indxinfo->indstatvals, &indstatvalsarray, + &nstatvals)) + pg_fatal("could not parse index statistic values"); + if (nstatcols != nstatvals) + pg_fatal("mismatched number of columns and values for index statistics"); + + for (j = 0; j < nstatcols; j++) + { + appendPQExpBuffer(q, "ALTER INDEX %s ", + fmtQualifiedDumpable(indxinfo)); + + /* + * Note that this is a column number, so no quotes should be + * used. + */ + appendPQExpBuffer(q, "ALTER COLUMN %s ", + indstatcolsarray[j]); + appendPQExpBuffer(q, "SET STATISTICS %s;\n", + indstatvalsarray[j]); + } + + free(indstatcolsarray); + free(indstatvalsarray); + } + /* If the index defines identity, we need to record that. */ if (indxinfo->indisreplident) { diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 9258948b583..bff7ca4b0ed 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3976,6 +3976,26 @@ my %tests = ( }, }, + 'CREATE TABLE table_with_constraint_stats' => { + create_order => 98, + create_sql => 'CREATE TABLE dump_test.table_constraint_stats ( + col1 int); + ALTER TABLE dump_test.table_constraint_stats + ADD CONSTRAINT ex_with_stats + EXCLUDE USING btree ((col1 + 1) WITH =); + ALTER INDEX dump_test.ex_with_stats + ALTER COLUMN 1 SET STATISTICS 100;', + regexp => qr/^ + \QALTER INDEX dump_test.ex_with_stats ALTER COLUMN 1 SET STATISTICS 100;\E\n + /xms, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { + exclude_dump_test_schema => 1, + only_dump_measurement => 1, + }, + }, + 'CREATE TABLE test_inheritance_parent' => { create_order => 90, create_sql => 'CREATE TABLE dump_test.test_inheritance_parent ( -- 2.54.0