From 4282d588294a9432203d26a768a0a22a9ec9584c Mon Sep 17 00:00:00 2001
From: Sami Imseih <samimseih@gmail.com>
Date: Wed, 15 Jul 2026 13:30:38 -0500
Subject: [PATCH v1 1/1] pgstat: add pgstat_prep_pending() for entry ref
 pending setup

Add pgstat_prep_pending(), which attaches pending data to an existing
PgStat_EntryRef.  This completes the pgstat_get_entry_ref() API by
allowing callers to obtain a reference and set up pending data in
separate steps.

Previously, the only way to get an entry ref with pending data ready
was pgstat_prep_pending_entry(), which bundles lookup, creation, and
pending setup in a single call.  Callers that need finer control over
entry creation (e.g., to check capacity before deciding to create)
had no public way to attach pending data to an already obtained ref.

pgstat_prep_pending_entry() is refactored to use pgstat_prep_pending()
internally.  All existing callers are unchanged.
---
 src/backend/utils/activity/pgstat.c | 53 ++++++++++++++++++-----------
 src/include/utils/pgstat_internal.h |  1 +
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 9234854b8b5..93f686a68a6 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -1311,29 +1311,10 @@ pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *creat
 {
 	PgStat_EntryRef *entry_ref;
 
-	/* need to be able to flush out */
-	Assert(pgstat_get_kind_info(kind)->flush_pending_cb != NULL);
-
-	if (unlikely(!pgStatPendingContext))
-	{
-		pgStatPendingContext =
-			AllocSetContextCreate(TopMemoryContext,
-								  "PgStat Pending",
-								  ALLOCSET_SMALL_SIZES);
-	}
-
 	entry_ref = pgstat_get_entry_ref(kind, dboid, objid,
 									 true, created_entry);
 
-	if (entry_ref->pending == NULL)
-	{
-		size_t		entrysize = pgstat_get_kind_info(kind)->pending_size;
-
-		Assert(entrysize != (size_t) -1);
-
-		entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
-		dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
-	}
+	pgstat_prep_pending(entry_ref);
 
 	return entry_ref;
 }
@@ -1377,6 +1358,38 @@ pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref)
 	dlist_delete(&entry_ref->pending_node);
 }
 
+/*
+ * Set up pending data for the given entry reference, allocating the pending
+ * buffer if not already done.  This allows callers that obtained an entry_ref
+ * via pgstat_get_entry_ref() to attach pending data.
+ */
+void
+pgstat_prep_pending(PgStat_EntryRef *entry_ref)
+{
+	PgStat_Kind kind = entry_ref->shared_entry->key.kind;
+
+	/* need to be able to flush out */
+	Assert(pgstat_get_kind_info(kind)->flush_pending_cb != NULL);
+
+	if (entry_ref->pending == NULL)
+	{
+		size_t		entrysize = pgstat_get_kind_info(kind)->pending_size;
+
+		Assert(entrysize != (size_t) -1);
+
+		if (unlikely(!pgStatPendingContext))
+		{
+			pgStatPendingContext =
+				AllocSetContextCreate(TopMemoryContext,
+									  "PgStat Pending",
+									  ALLOCSET_SMALL_SIZES);
+		}
+
+		entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
+		dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
+	}
+}
+
 /*
  * Flush out pending variable-numbered stats.
  */
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index e62122b883b..1cc2ec3893f 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -680,6 +680,7 @@ extern void pgstat_assert_is_up(void);
 #endif
 
 extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref);
+extern void pgstat_prep_pending(PgStat_EntryRef *entry_ref);
 extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid,
 												  uint64 objid,
 												  bool *created_entry);
-- 
2.50.1 (Apple Git-155)

