From da05969a3260b44416a47f43fa29da9b56e4eada Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Mon, 2 Nov 2026 09:28:17 +0900
Subject: [PATCH v5 1/2] test_custom_stats: Add test for dropped stats

The former injection_points coverage exercised
pgstat_drop_matching_entries() with a non-NULL callback while
scanning all variable-numbered stats kinds.  That coverage was lost
when the stats tests were moved to test_custom_stats.

Add equivalent coverage here by dropping all custom variable-sized
stats entries through pgstat_drop_matching_entries(), while checking
that relation stats remain untouched.
---
 .../test_custom_stats/t/001_custom_stats.pl   | 15 ++++++++++++
 .../test_custom_var_stats--1.0.sql            |  5 ++++
 .../test_custom_stats/test_custom_var_stats.c | 23 +++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/src/test/modules/test_custom_stats/t/001_custom_stats.pl b/src/test/modules/test_custom_stats/t/001_custom_stats.pl
index ccda129c4ff..d49c02badba 100644
--- a/src/test/modules/test_custom_stats/t/001_custom_stats.pl
+++ b/src/test/modules/test_custom_stats/t/001_custom_stats.pl
@@ -172,6 +172,21 @@ foreach my $stats_kind (@var_stats_kinds)
 	is($result, "",
 		"variable-sized stats of entry2 lost after crash recovery for $kind_name"
 	);
+
+	# Test drop of all variable-sized stats.
+	$node->safe_psql(
+		'postgres',
+		q(create table if not exists test_drop_all (a int);
+		  insert into test_drop_all values (1);
+		  select test_custom_stats_var_create('entry5', 'Test entry 5')));
+	$node->safe_psql('postgres', q(select test_custom_stats_var_drop_all()));
+	$result = $node->safe_psql('postgres',
+		qq(select entry_count from pg_stat_kind_info where name = '$kind_name'));
+	is($result, "0", "no entries after drop for $kind_name");
+	$result = $node->safe_psql('postgres',
+		q(select n_tup_ins from pg_stat_user_tables
+		  where relname = 'test_drop_all'));
+	is($result, "1", "relation stats remain after drop for $kind_name");
 }
 
 # fixed-sized stats are updated 3 times, so the report below should match.
diff --git a/src/test/modules/test_custom_stats/test_custom_var_stats--1.0.sql b/src/test/modules/test_custom_stats/test_custom_var_stats--1.0.sql
index 2b92316679f..d758968b12c 100644
--- a/src/test/modules/test_custom_stats/test_custom_var_stats--1.0.sql
+++ b/src/test/modules/test_custom_stats/test_custom_var_stats--1.0.sql
@@ -18,6 +18,11 @@ RETURNS void
 AS 'MODULE_PATHNAME', 'test_custom_stats_var_drop'
 LANGUAGE C STRICT PARALLEL UNSAFE;
 
+CREATE FUNCTION test_custom_stats_var_drop_all()
+RETURNS void
+AS 'MODULE_PATHNAME', 'test_custom_stats_var_drop_all'
+LANGUAGE C STRICT PARALLEL UNSAFE;
+
 CREATE FUNCTION test_custom_stats_var_reset()
 RETURNS void
 AS 'MODULE_PATHNAME', 'test_custom_stats_var_reset'
diff --git a/src/test/modules/test_custom_stats/test_custom_var_stats.c b/src/test/modules/test_custom_stats/test_custom_var_stats.c
index ba6486fff6a..8be4abe2f82 100644
--- a/src/test/modules/test_custom_stats/test_custom_var_stats.c
+++ b/src/test/modules/test_custom_stats/test_custom_var_stats.c
@@ -655,6 +655,29 @@ test_custom_stats_var_drop(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
+/*
+ * Callback for pgstat_drop_matching_entries().
+ */
+static bool
+test_custom_stats_var_match_kind(PgStatShared_HashEntry *entry,
+								 Datum match_data)
+{
+	return entry->key.kind == PGSTAT_KIND_TEST_CUSTOM_VAR_STATS;
+}
+
+/*
+ * test_custom_stats_var_drop_all
+ *		Remove all custom statistic entries
+ */
+PG_FUNCTION_INFO_V1(test_custom_stats_var_drop_all);
+Datum
+test_custom_stats_var_drop_all(PG_FUNCTION_ARGS)
+{
+	pgstat_drop_matching_entries(test_custom_stats_var_match_kind, 0);
+
+	PG_RETURN_VOID();
+}
+
 /*
  * test_custom_stats_var_reset
  *		Reset all custom statistic entries
-- 
2.50.1

