summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-12-29 10:57:11 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-12-29 10:57:11 -0500
commit8d4e8b746815505c3b808ab96674ec2e140afc56 (patch)
tree082efc6e2c478161b38605020c0d7a7abd1d87e9
parentd2580bc312d9996b9caa525695fd7a4e75533f1b (diff)
In pg_dump, don't dump a stats object unless dumping underlying table.
If the underlying table isn't being dumped, it's useless to dump an extended statistics object; it'll just cause errors at restore. We have always applied similar policies to, say, indexes. (When and if we get cross-table stats objects, it might be profitable to think a little harder about what to do with them. But for now there seems no point in considering a stats object as anything but an appendage of its table.) Rian McGuire and Tom Lane, per report from Rian McGuire. Back-patch to supported branches. Discussion: https://postgr.es/m/7075d3aa-3f05-44a5-b68f-47dc6a8a0550@buildkite.com
-rw-r--r--src/bin/pg_dump/pg_dump.c30
-rw-r--r--src/bin/pg_dump/pg_dump.h1
-rw-r--r--src/bin/pg_dump/t/002_pg_dump.pl6
3 files changed, 31 insertions, 6 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c73a6df78cc..6576efaeeec 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1816,6 +1816,26 @@ selectDumpablePublicationTable(DumpableObject *dobj, Archive *fout)
}
/*
+ * selectDumpableStatisticsObject: policy-setting subroutine
+ * Mark an extended statistics object as to be dumped or not
+ *
+ * We dump an extended statistics object if the schema it's in and the table
+ * it's for are being dumped. (This'll need more thought if statistics
+ * objects ever support cross-table stats.)
+ */
+static void
+selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
+{
+ if (checkExtensionMembership(&sobj->dobj, fout))
+ return; /* extension membership overrides all else */
+
+ sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
+ if (sobj->stattable == NULL ||
+ !(sobj->stattable->dobj.dump & DUMP_COMPONENT_DEFINITION))
+ sobj->dobj.dump = DUMP_COMPONENT_NONE;
+}
+
+/*
* selectDumpableObject: policy-setting subroutine
* Mark a generic dumpable object as to be dumped or not
*
@@ -7492,6 +7512,7 @@ getExtendedStatistics(Archive *fout)
int i_stxname;
int i_stxnamespace;
int i_rolname;
+ int i_stxrelid;
int i_stattarget;
int i;
@@ -7503,12 +7524,12 @@ getExtendedStatistics(Archive *fout)
if (fout->remoteVersion < 130000)
appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
- "stxnamespace, (%s stxowner) AS rolname, (-1) AS stxstattarget "
+ "stxnamespace, (%s stxowner) AS rolname, stxrelid, (-1) AS stxstattarget "
"FROM pg_catalog.pg_statistic_ext",
username_subquery);
else
appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
- "stxnamespace, (%s stxowner) AS rolname, stxstattarget "
+ "stxnamespace, (%s stxowner) AS rolname, stxrelid, stxstattarget "
"FROM pg_catalog.pg_statistic_ext",
username_subquery);
@@ -7521,6 +7542,7 @@ getExtendedStatistics(Archive *fout)
i_stxname = PQfnumber(res, "stxname");
i_stxnamespace = PQfnumber(res, "stxnamespace");
i_rolname = PQfnumber(res, "rolname");
+ i_stxrelid = PQfnumber(res, "stxrelid");
i_stattarget = PQfnumber(res, "stxstattarget");
statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
@@ -7536,10 +7558,12 @@ getExtendedStatistics(Archive *fout)
findNamespace(fout,
atooid(PQgetvalue(res, i, i_stxnamespace)));
statsextinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+ statsextinfo[i].stattable =
+ findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
/* Decide whether we want to dump it */
- selectDumpableObject(&(statsextinfo[i].dobj), fout);
+ selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
/* Stats objects do not currently have ACLs. */
statsextinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 43095c25ddc..552e9e1da16 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -387,6 +387,7 @@ typedef struct _statsExtInfo
{
DumpableObject dobj;
char *rolname; /* name of owner, or empty string */
+ TableInfo *stattable; /* link to table the stats are for */
int stattarget; /* statistics target */
} StatsExtInfo;
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 04108bd6bcc..93193c0bd4b 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -2751,13 +2751,13 @@ my %tests = (
'CREATE STATISTICS extended_stats_no_options' => {
create_order => 97,
create_sql => 'CREATE STATISTICS dump_test.test_ext_stats_no_options
- ON col1, col2 FROM dump_test.test_fifth_table',
+ ON col1, col2 FROM dump_test.test_table',
regexp => qr/^
- \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_fifth_table;\E
+ \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_table;\E
/xms,
like =>
{ %full_runs, %dump_test_schema_runs, section_post_data => 1, },
- unlike => { exclude_dump_test_schema => 1, },
+ unlike => { exclude_dump_test_schema => 1, exclude_test_table => 1, },
},
'CREATE STATISTICS extended_stats_options' => {