From 4282d588294a9432203d26a768a0a22a9ec9584c Mon Sep 17 00:00:00 2001 From: Sami Imseih 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)