diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 97a22feafa9..231be46fe97 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -16325,6 +16325,48 @@ getAttrName(int attrnum, const TableInfo *tblInfo) return NULL; /* keep compiler quiet */ } +/* + * appendIndexStatTargets + * append ALTER INDEX ... SET STATISTICS commands for the per-column + * statistics targets of an index (attstattarget), if any. + */ +static void +appendIndexStatTargets(PQExpBuffer q, const IndxInfo *indxinfo) +{ + char **indstatcolsarray = NULL; + char **indstatvalsarray = NULL; + int nstatcols = 0; + int nstatvals = 0; + + if (strlen(indxinfo->indstatcols) == 0 && + strlen(indxinfo->indstatvals) == 0) + return; + + 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 (int 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); +} + /* * dumpIndex * write out to fout a user-defined index @@ -16359,13 +16401,6 @@ dumpIndex(Archive *fout, const IndxInfo *indxinfo) */ if (!is_constraint) { - char *indstatcols = indxinfo->indstatcols; - char *indstatvals = indxinfo->indstatvals; - char **indstatcolsarray = NULL; - char **indstatvalsarray = NULL; - int nstatcols = 0; - int nstatvals = 0; - if (dopt->binary_upgrade) binary_upgrade_set_pg_class_oids(fout, q, indxinfo->dobj.catId.oid, true); @@ -16389,35 +16424,8 @@ dumpIndex(Archive *fout, const IndxInfo *indxinfo) qindxname); } - /* - * If the index has any statistics on some of its columns, generate - * the associated ALTER INDEX queries. - */ - if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0) - { - int j; - - if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols)) - pg_fatal("could not parse index statistic columns"); - if (!parsePGArray(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 ", qqindxname); - - /* - * 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]); - } - } + /* Per-column statistics targets, if any */ + appendIndexStatTargets(q, indxinfo); /* Indexes can depend on extensions */ append_depends_on_extension(fout, q, &indxinfo->dobj, @@ -16456,11 +16464,6 @@ dumpIndex(Archive *fout, const IndxInfo *indxinfo) .section = SECTION_POST_DATA, .createStmt = q->data, .dropStmt = delq->data)); - - if (indstatcolsarray) - free(indstatcolsarray); - if (indstatvalsarray) - free(indstatvalsarray); } /* Dump Index Comments */ @@ -16724,6 +16727,9 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo) fmtId(indxinfo->dobj.name)); } + /* Per-column statistics targets, if any */ + appendIndexStatTargets(q, indxinfo); + /* 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 bef145c3382..7c5028abc70 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3157,6 +3157,31 @@ my %tests = ( unlike => { exclude_dump_test_schema => 1, }, }, + 'CREATE TABLE table_with_constraint_stats' => { + create_order => 98, + create_sql => 'CREATE TABLE dump_test.table_constraint_stats ( + col1 int, + col2 int); + ALTER TABLE dump_test.table_constraint_stats + ADD CONSTRAINT ex_with_stats + EXCLUDE USING btree ((col1 + 1) WITH =, + col1 WITH =, (col2 + 1) WITH =); + ALTER INDEX dump_test.ex_with_stats + ALTER COLUMN 1 SET STATISTICS 100; + ALTER INDEX dump_test.ex_with_stats + ALTER COLUMN 3 SET STATISTICS 200;', + regexp => qr/^ + \QALTER INDEX dump_test.ex_with_stats ALTER COLUMN 1 SET STATISTICS 100;\E\n + \QALTER INDEX dump_test.ex_with_stats ALTER COLUMN 3 SET STATISTICS 200;\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 (