From fd8ab7b6845a2c56aa2c8d9c60f404f6b3407338 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Wed, 21 Aug 2024 15:16:06 +0900
Subject: [PATCH 2/3] injection_point: Add injection_points.stats

This GUC controls if statistics should be used or not in the module.
Custom statistics require the module to be loaded with
shared_preload_libraries, hence this GUC is made PGC_POSTMASTER.  By
default, stats are disabled.

This will be used by an upcoming change in a test where stats should not
be used, as the test has a dependency on a critical section.
---
 .../modules/injection_points/injection_points.c | 17 +++++++++++++++++
 .../modules/injection_points/injection_stats.c  |  8 ++++----
 .../modules/injection_points/injection_stats.h  |  3 +++
 .../injection_points/injection_stats_fixed.c    |  4 ++--
 .../modules/injection_points/t/001_stats.pl     |  6 ++++--
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index 8d83d8c401..fb5eb3b586 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -28,6 +28,7 @@
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
 #include "utils/builtins.h"
+#include "utils/guc.h"
 #include "utils/injection_point.h"
 #include "utils/memutils.h"
 #include "utils/wait_event.h"
@@ -102,6 +103,9 @@ extern PGDLLEXPORT void injection_wait(const char *name,
 /* track if injection points attached in this process are linked to it */
 static bool injection_point_local = false;
 
+/* GUC variable */
+bool inj_stats_enabled = false;
+
 /* Shared memory init callbacks */
 static shmem_request_hook_type prev_shmem_request_hook = NULL;
 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
@@ -516,6 +520,19 @@ _PG_init(void)
 	if (!process_shared_preload_libraries_in_progress)
 		return;
 
+	DefineCustomBoolVariable("injection_points.stats",
+							 "Enables statistics for injection points.",
+							 NULL,
+							 &inj_stats_enabled,
+							 false,
+							 PGC_POSTMASTER,
+							 0,
+							 NULL,
+							 NULL,
+							 NULL);
+
+	MarkGUCPrefixReserved("injection_points");
+
 	/* Shared memory initialization */
 	prev_shmem_request_hook = shmem_request_hook;
 	shmem_request_hook = injection_shmem_request;
diff --git a/src/test/modules/injection_points/injection_stats.c b/src/test/modules/injection_points/injection_stats.c
index 78042074ff..582686a0a8 100644
--- a/src/test/modules/injection_points/injection_stats.c
+++ b/src/test/modules/injection_points/injection_stats.c
@@ -91,7 +91,7 @@ pgstat_fetch_stat_injentry(const char *name)
 {
 	PgStat_StatInjEntry *entry = NULL;
 
-	if (!inj_stats_loaded)
+	if (!inj_stats_loaded || !inj_stats_enabled)
 		return NULL;
 
 	/* Compile the lookup key as a hash of the point name */
@@ -123,7 +123,7 @@ pgstat_create_inj(const char *name)
 	PgStatShared_InjectionPoint *shstatent;
 
 	/* leave if disabled */
-	if (!inj_stats_loaded)
+	if (!inj_stats_loaded || !inj_stats_enabled)
 		return;
 
 	entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_INJECTION, InvalidOid,
@@ -142,7 +142,7 @@ void
 pgstat_drop_inj(const char *name)
 {
 	/* leave if disabled */
-	if (!inj_stats_loaded)
+	if (!inj_stats_loaded || !inj_stats_enabled)
 		return;
 
 	if (!pgstat_drop_entry(PGSTAT_KIND_INJECTION, InvalidOid,
@@ -164,7 +164,7 @@ pgstat_report_inj(const char *name)
 	PgStat_StatInjEntry *statent;
 
 	/* leave if disabled */
-	if (!inj_stats_loaded)
+	if (!inj_stats_loaded || !inj_stats_enabled)
 		return;
 
 	entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_INJECTION, InvalidOid,
diff --git a/src/test/modules/injection_points/injection_stats.h b/src/test/modules/injection_points/injection_stats.h
index 126c110169..c48d533b4b 100644
--- a/src/test/modules/injection_points/injection_stats.h
+++ b/src/test/modules/injection_points/injection_stats.h
@@ -15,6 +15,9 @@
 #ifndef INJECTION_STATS
 #define INJECTION_STATS
 
+/* GUC variable */
+extern bool inj_stats_enabled;
+
 /* injection_stats.c */
 extern void pgstat_register_inj(void);
 extern void pgstat_create_inj(const char *name);
diff --git a/src/test/modules/injection_points/injection_stats_fixed.c b/src/test/modules/injection_points/injection_stats_fixed.c
index 82b07e5332..2fed178b7a 100644
--- a/src/test/modules/injection_points/injection_stats_fixed.c
+++ b/src/test/modules/injection_points/injection_stats_fixed.c
@@ -146,7 +146,7 @@ pgstat_report_inj_fixed(uint32 numattach,
 	PgStatShared_InjectionPointFixed *stats_shmem;
 
 	/* leave if disabled */
-	if (!inj_fixed_loaded)
+	if (!inj_fixed_loaded || !inj_stats_enabled)
 		return;
 
 	stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
@@ -172,7 +172,7 @@ injection_points_stats_fixed(PG_FUNCTION_ARGS)
 	bool		nulls[5] = {0};
 	PgStat_StatInjFixedEntry *stats;
 
-	if (!inj_fixed_loaded)
+	if (!inj_fixed_loaded || !inj_stats_enabled)
 		PG_RETURN_NULL();
 
 	pgstat_snapshot_fixed(PGSTAT_KIND_INJECTION_FIXED);
diff --git a/src/test/modules/injection_points/t/001_stats.pl b/src/test/modules/injection_points/t/001_stats.pl
index 0d72cd86df..9df79b5168 100644
--- a/src/test/modules/injection_points/t/001_stats.pl
+++ b/src/test/modules/injection_points/t/001_stats.pl
@@ -20,8 +20,10 @@ if ($ENV{enable_injection_points} ne 'yes')
 # Node initialization
 my $node = PostgreSQL::Test::Cluster->new('master');
 $node->init;
-$node->append_conf('postgresql.conf',
-	"shared_preload_libraries = 'injection_points'");
+$node->append_conf('postgresql.conf', qq(
+shared_preload_libraries = 'injection_points'
+injection_points.stats = true
+));
 $node->start;
 $node->safe_psql('postgres', 'CREATE EXTENSION injection_points;');
 
-- 
2.45.2

