mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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:
		@@ -1815,6 +1815,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
 | 
				
			||||||
@@ -7492,6 +7512,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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -7503,12 +7524,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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -7521,6 +7542,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));
 | 
				
			||||||
@@ -7536,10 +7558,12 @@ getExtendedStatistics(Archive *fout)
 | 
				
			|||||||
			findNamespace(fout,
 | 
								findNamespace(fout,
 | 
				
			||||||
						  atooid(PQgetvalue(res, i, i_stxnamespace)));
 | 
											  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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -387,6 +387,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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2751,13 +2751,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' => {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user