From 48a6422875508ec49bf89d18f987126f24ced165 Mon Sep 17 00:00:00 2001
From: Shinya Kato <shinya11.kato@gmail.com>
Date: Fri, 2 May 2025 14:44:06 +0900
Subject: [PATCH v1 1/9] Make pg_stat_reset() return the reset time

---
 doc/src/sgml/monitoring.sgml            |  5 +++--
 src/backend/utils/activity/pgstat.c     |  4 +++-
 src/backend/utils/adt/pgstatfuncs.c     |  4 ++--
 src/include/catalog/pg_proc.dat         |  2 +-
 src/include/pgstat.h                    |  2 +-
 src/test/isolation/expected/stats.out   |  8 ++++----
 src/test/isolation/expected/stats_1.out |  8 ++++----
 src/test/isolation/specs/stats.spec     |  2 +-
 src/test/regress/expected/stats.out     | 16 ++++++++--------
 src/test/regress/sql/stats.sql          |  4 ++--
 10 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 3f4a27a736e..b72b840048b 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -5008,10 +5008,11 @@ description | Waiting for a newly initialized WAL file to reach durable storage
          <primary>pg_stat_reset</primary>
         </indexterm>
         <function>pg_stat_reset</function> ()
-        <returnvalue>void</returnvalue>
+        <returnvalue>timestamp with time zone</returnvalue>
        </para>
        <para>
-        Resets all statistics counters for the current database to zero.
+        Resets all statistics counters for the current database to zero, and
+        returns the time of the reset.
        </para>
        <para>
         This function is restricted to superusers by default, but other users
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 6bc91ce0dad..707d55abdb6 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -830,7 +830,7 @@ match_db_entries(PgStatShared_HashEntry *entry, Datum match_data)
  * Permission checking for this function is managed through the normal
  * GRANT system.
  */
-void
+TimestampTz
 pgstat_reset_counters(void)
 {
 	TimestampTz ts = GetCurrentTimestamp();
@@ -838,6 +838,8 @@ pgstat_reset_counters(void)
 	pgstat_reset_matching_entries(match_db_entries,
 								  ObjectIdGetDatum(MyDatabaseId),
 								  ts);
+
+	return ts;
 }
 
 /*
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index c756c2bebaa..56c5dc4efce 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1857,9 +1857,9 @@ pg_stat_force_next_flush(PG_FUNCTION_ARGS)
 Datum
 pg_stat_reset(PG_FUNCTION_ARGS)
 {
-	pgstat_reset_counters();
+	TimestampTz ts = pgstat_reset_counters();
 
-	PG_RETURN_VOID();
+	PG_RETURN_TIMESTAMPTZ(ts);
 }
 
 /*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 118d6da1ace..7f3b314875d 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6140,7 +6140,7 @@
 { oid => '2274',
   descr => 'statistics: reset collected statistics for current database',
   proname => 'pg_stat_reset', proisstrict => 'f', provolatile => 'v',
-  prorettype => 'void', proargtypes => '', prosrc => 'pg_stat_reset' },
+  prorettype => 'timestamptz', proargtypes => '', prosrc => 'pg_stat_reset' },
 { oid => '3775',
   descr => 'statistics: reset collected statistics shared across the cluster',
   proname => 'pg_stat_reset_shared', proisstrict => 'f', provolatile => 'v',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 202bd2d5ace..62a4db726df 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -524,7 +524,7 @@ extern void pgstat_initialize(void);
 extern long pgstat_report_stat(bool force);
 extern void pgstat_force_next_flush(void);
 
-extern void pgstat_reset_counters(void);
+extern TimestampTz pgstat_reset_counters(void);
 extern void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid);
 extern void pgstat_reset_of_kind(PgStat_Kind kind);
 
diff --git a/src/test/isolation/expected/stats.out b/src/test/isolation/expected/stats.out
index 8c7fe60217e..be9dc186fef 100644
--- a/src/test/isolation/expected/stats.out
+++ b/src/test/isolation/expected/stats.out
@@ -1295,10 +1295,10 @@ name          |pg_stat_get_function_calls|total_above_zero|self_above_zero
 test_stat_func|                         2|t               |t              
 (1 row)
 
-step s1_reset: SELECT pg_stat_reset();
-pg_stat_reset
--------------
-             
+step s1_reset: SELECT pg_stat_reset() IS NOT NULL AS t;
+t
+-
+t
 (1 row)
 
 step s1_func_stats: 
diff --git a/src/test/isolation/expected/stats_1.out b/src/test/isolation/expected/stats_1.out
index 6b965bb9553..3017c6f4619 100644
--- a/src/test/isolation/expected/stats_1.out
+++ b/src/test/isolation/expected/stats_1.out
@@ -1295,10 +1295,10 @@ name          |pg_stat_get_function_calls|total_above_zero|self_above_zero
 test_stat_func|                         2|t               |t              
 (1 row)
 
-step s1_reset: SELECT pg_stat_reset();
-pg_stat_reset
--------------
-             
+step s1_reset: SELECT pg_stat_reset() IS NOT NULL AS t;
+t
+-
+t
 (1 row)
 
 step s1_func_stats: 
diff --git a/src/test/isolation/specs/stats.spec b/src/test/isolation/specs/stats.spec
index 1d98ac785b8..22ef6d3206b 100644
--- a/src/test/isolation/specs/stats.spec
+++ b/src/test/isolation/specs/stats.spec
@@ -56,7 +56,7 @@ step s1_func_call { SELECT test_stat_func(); }
 step s1_func_drop { DROP FUNCTION test_stat_func(); }
 step s1_func_stats_reset { SELECT pg_stat_reset_single_function_counters('test_stat_func'::regproc); }
 step s1_func_stats_reset_nonexistent { SELECT pg_stat_reset_single_function_counters(12000); }
-step s1_reset { SELECT pg_stat_reset(); }
+step s1_reset { SELECT pg_stat_reset() IS NOT NULL AS t; }
 step s1_func_stats {
     SELECT
         tso.name,
diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out
index 605f5070376..5db2d81afb1 100644
--- a/src/test/regress/expected/stats.out
+++ b/src/test/regress/expected/stats.out
@@ -1102,17 +1102,17 @@ ERROR:  unrecognized reset target: "unknown"
 HINT:  Target must be "archiver", "bgwriter", "checkpointer", "io", "recovery_prefetch", "slru", or "wal".
 -- Test that reset works for pg_stat_database
 -- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to
-SELECT pg_stat_reset();
- pg_stat_reset 
----------------
- 
+SELECT pg_stat_reset() IS NOT NULL AS t;
+ t 
+---
+ t
 (1 row)
 
 SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset
-SELECT pg_stat_reset();
- pg_stat_reset 
----------------
- 
+SELECT pg_stat_reset() IS NOT NULL AS t;
+ t 
+---
+ t
 (1 row)
 
 SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database());
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index 54e72866344..5c77ccc1319 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -512,9 +512,9 @@ SELECT pg_stat_reset_shared('unknown');
 -- Test that reset works for pg_stat_database
 
 -- Since pg_stat_database stats_reset starts out as NULL, reset it once first so we have something to compare it to
-SELECT pg_stat_reset();
+SELECT pg_stat_reset() IS NOT NULL AS t;
 SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) \gset
-SELECT pg_stat_reset();
+SELECT pg_stat_reset() IS NOT NULL AS t;
 SELECT stats_reset > :'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database());
 
 
-- 
2.47.1

