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
This commit is contained in:
parent
020e4a17f0
commit
aa2e323eed
|
@ -1957,6 +1957,26 @@ selectDumpablePublicationTable(DumpableObject *dobj, Archive *fout)
|
||||||
DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
|
DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* selectDumpableObject: policy-setting subroutine
|
||||||
* Mark a generic dumpable object as to be dumped or not
|
* Mark a generic dumpable object as to be dumped or not
|
||||||
|
@ -7683,6 +7703,7 @@ getExtendedStatistics(Archive *fout)
|
||||||
int i_stxname;
|
int i_stxname;
|
||||||
int i_stxnamespace;
|
int i_stxnamespace;
|
||||||
int i_rolname;
|
int i_rolname;
|
||||||
|
int i_stxrelid;
|
||||||
int i_stattarget;
|
int i_stattarget;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -7694,12 +7715,12 @@ getExtendedStatistics(Archive *fout)
|
||||||
|
|
||||||
if (fout->remoteVersion < 130000)
|
if (fout->remoteVersion < 130000)
|
||||||
appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
|
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",
|
"FROM pg_catalog.pg_statistic_ext",
|
||||||
username_subquery);
|
username_subquery);
|
||||||
else
|
else
|
||||||
appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, "
|
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",
|
"FROM pg_catalog.pg_statistic_ext",
|
||||||
username_subquery);
|
username_subquery);
|
||||||
|
|
||||||
|
@ -7712,6 +7733,7 @@ getExtendedStatistics(Archive *fout)
|
||||||
i_stxname = PQfnumber(res, "stxname");
|
i_stxname = PQfnumber(res, "stxname");
|
||||||
i_stxnamespace = PQfnumber(res, "stxnamespace");
|
i_stxnamespace = PQfnumber(res, "stxnamespace");
|
||||||
i_rolname = PQfnumber(res, "rolname");
|
i_rolname = PQfnumber(res, "rolname");
|
||||||
|
i_stxrelid = PQfnumber(res, "stxrelid");
|
||||||
i_stattarget = PQfnumber(res, "stxstattarget");
|
i_stattarget = PQfnumber(res, "stxstattarget");
|
||||||
|
|
||||||
statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
|
statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
|
||||||
|
@ -7726,10 +7748,12 @@ getExtendedStatistics(Archive *fout)
|
||||||
statsextinfo[i].dobj.namespace =
|
statsextinfo[i].dobj.namespace =
|
||||||
findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
|
findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
|
||||||
statsextinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
|
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));
|
statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
|
||||||
|
|
||||||
/* Decide whether we want to dump it */
|
/* Decide whether we want to dump it */
|
||||||
selectDumpableObject(&(statsextinfo[i].dobj), fout);
|
selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
|
||||||
|
|
||||||
/* Stats objects do not currently have ACLs. */
|
/* Stats objects do not currently have ACLs. */
|
||||||
statsextinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
|
statsextinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
|
||||||
|
|
|
@ -398,6 +398,7 @@ typedef struct _statsExtInfo
|
||||||
{
|
{
|
||||||
DumpableObject dobj;
|
DumpableObject dobj;
|
||||||
char *rolname; /* name of owner, or empty string */
|
char *rolname; /* name of owner, or empty string */
|
||||||
|
TableInfo *stattable; /* link to table the stats are for */
|
||||||
int stattarget; /* statistics target */
|
int stattarget; /* statistics target */
|
||||||
} StatsExtInfo;
|
} StatsExtInfo;
|
||||||
|
|
||||||
|
|
|
@ -2855,13 +2855,13 @@ my %tests = (
|
||||||
'CREATE STATISTICS extended_stats_no_options' => {
|
'CREATE STATISTICS extended_stats_no_options' => {
|
||||||
create_order => 97,
|
create_order => 97,
|
||||||
create_sql => 'CREATE STATISTICS dump_test.test_ext_stats_no_options
|
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/^
|
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,
|
/xms,
|
||||||
like =>
|
like =>
|
||||||
{ %full_runs, %dump_test_schema_runs, section_post_data => 1, },
|
{ %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' => {
|
'CREATE STATISTICS extended_stats_options' => {
|
||||||
|
|
Loading…
Reference in New Issue