From dfe7d17e00665875639e905fa385231dacc57c4e Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 30 Jun 2026 16:24:34 +0900 Subject: [PATCH] Refactor pg_stat_get_lock() to use a helper function This commit extracts the tuple-building logic from pg_stat_get_lock() into a new static helper pg_stat_lock_build_tuples(). This is in preparation for a follow-up patch, to add support for backend-level lock stats, which will reuse the same helper. This change follows the pattern established by pg_stat_io_build_tuples() for IO stats and pg_stat_wal_build_tuple() for WAL stats. Author: Bertrand Drouvot Reviewed-by: Tatsuya Kawata Reviewed-by: Michael Paquier Reviewed-by: Tristan Partin Reviewed-by: Rui Zhao Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg --- src/backend/utils/adt/pgstatfuncs.c | 57 ++++++++++++++++++----------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 0c59df17901..1f9165f1616 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1737,10 +1737,43 @@ pg_stat_get_wal(PG_FUNCTION_ARGS) wal_stats->stat_reset_timestamp)); } +/* + * pg_stat_lock_build_tuples + * + * Helper routine for pg_stat_get_lock(), filling a result tuplestore with one + * tuple for each lock type. + */ +static void +pg_stat_lock_build_tuples(ReturnSetInfo *rsinfo, + PgStat_LockEntry *lock_stats, + TimestampTz stat_reset_timestamp) +{ +#define PG_STAT_LOCK_COLS 5 + for (int lcktype = 0; lcktype <= LOCKTAG_LAST_TYPE; lcktype++) + { + Datum values[PG_STAT_LOCK_COLS] = {0}; + bool nulls[PG_STAT_LOCK_COLS] = {0}; + PgStat_LockEntry *lck_stats = &lock_stats[lcktype]; + int i = 0; + + values[i++] = CStringGetTextDatum(LockTagTypeNames[lcktype]); + values[i++] = Int64GetDatum(lck_stats->waits); + values[i++] = Float8GetDatum(pg_stat_us_to_ms(lck_stats->wait_time)); + values[i++] = Int64GetDatum(lck_stats->fastpath_exceeded); + if (stat_reset_timestamp != 0) + values[i] = TimestampTzGetDatum(stat_reset_timestamp); + else + nulls[i] = true; + + Assert(i + 1 == PG_STAT_LOCK_COLS); + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + } +} + Datum pg_stat_get_lock(PG_FUNCTION_ARGS) { -#define PG_STAT_LOCK_COLS 5 ReturnSetInfo *rsinfo; PgStat_Lock *lock_stats; @@ -1749,26 +1782,8 @@ pg_stat_get_lock(PG_FUNCTION_ARGS) lock_stats = pgstat_fetch_stat_lock(); - for (int lcktype = 0; lcktype <= LOCKTAG_LAST_TYPE; lcktype++) - { - const char *locktypename; - Datum values[PG_STAT_LOCK_COLS] = {0}; - bool nulls[PG_STAT_LOCK_COLS] = {0}; - PgStat_LockEntry *lck_stats = &lock_stats->stats[lcktype]; - int i = 0; - - locktypename = LockTagTypeNames[lcktype]; - - values[i++] = CStringGetTextDatum(locktypename); - values[i++] = Int64GetDatum(lck_stats->waits); - values[i++] = Float8GetDatum(pg_stat_us_to_ms(lck_stats->wait_time)); - values[i++] = Int64GetDatum(lck_stats->fastpath_exceeded); - values[i] = TimestampTzGetDatum(lock_stats->stat_reset_timestamp); - - Assert(i + 1 == PG_STAT_LOCK_COLS); - - tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); - } + pg_stat_lock_build_tuples(rsinfo, lock_stats->stats, + lock_stats->stat_reset_timestamp); return (Datum) 0; }