Fix pg_stat_reset_single_table_counters() for shared relations
authorMichael Paquier
Mon, 21 Aug 2023 04:33:08 +0000 (13:33 +0900)
committerMichael Paquier
Mon, 21 Aug 2023 04:33:08 +0000 (13:33 +0900)
This commit fixes the function of $subject for shared relations.  This
feature has been added by e042678.  Unfortunately, this new behavior got
removed by 5891c7a when moving statistics to shared memory.

Reported-by: Mitsuru Hinata
Author: Masahiro Ikeda
Reviewed-by: Kyotaro Horiguchi, Masahiko Sawada
Discussion: https://postgr.es/m/7cc69f863d9b1bc677544e3accd0e4b4@oss.nttdata.com
Backpatch-through: 15

src/backend/utils/adt/pgstatfuncs.c
src/test/regress/expected/stats.out
src/test/regress/sql/stats.sql

index 83d2cdb57c80453320f33205b3b872b37030fe99..6ef7ead9cc062fa4df9e480d2a688439542b0b9c 100644 (file)
@@ -17,6 +17,7 @@
 #include "access/htup_details.h"
 #include "access/xlog.h"
 #include "access/xlogprefetcher.h"
+#include "catalog/catalog.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_type.h"
 #include "common/ip.h"
@@ -2117,13 +2118,17 @@ pg_stat_reset_shared(PG_FUNCTION_ARGS)
    PG_RETURN_VOID();
 }
 
-/* Reset a single counter in the current database */
+/*
+ * Reset a statistics for a single object, which may be of current
+ * database or shared across all databases in the cluster.
+ */
 Datum
 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
 {
    Oid         taboid = PG_GETARG_OID(0);
+   Oid         dboid = (IsSharedRelation(taboid) ? InvalidOid : MyDatabaseId);
 
-   pgstat_reset(PGSTAT_KIND_RELATION, MyDatabaseId, taboid);
+   pgstat_reset(PGSTAT_KIND_RELATION, dboid, taboid);
 
    PG_RETURN_VOID();
 }
index e5e8f070ecb86d5e9bbebc0c3777a63906a3cffa..ffcba3060679315754b0b2664fcba1abb050bdcd 100644 (file)
@@ -557,6 +557,52 @@ SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
 DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4;
 DROP TABLE prevstats;
 -----
+-- Test reset of some stats for shared table
+-----
+-- This updates the comment of the database currently in use in
+-- pg_shdescription with a fake value, then sets it back to its
+-- original value.
+SELECT shobj_description(d.oid, 'pg_database') as description_before
+  FROM pg_database d WHERE datname = current_database() \gset
+-- force some stats in pg_shdescription.
+BEGIN;
+SELECT current_database() as datname \gset
+COMMENT ON DATABASE :"datname" IS 'This is a test comment';
+SELECT pg_stat_force_next_flush();
+ pg_stat_force_next_flush 
+--------------------------
+(1 row)
+
+COMMIT;
+-- check that the stats are reset.
+SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables
+  WHERE relid = 'pg_shdescription'::regclass;
+ has_data 
+----------
+ t
+(1 row)
+
+SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass);
+ pg_stat_reset_single_table_counters 
+-------------------------------------
+(1 row)
+
+SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables
+  WHERE relid = 'pg_shdescription'::regclass;
+ has_data 
+----------
+ f
+(1 row)
+
+-- set back comment
+\if :{?description_before}
+  COMMENT ON DATABASE :"datname" IS :'description_before';
+\else
+  COMMENT ON DATABASE :"datname" IS NULL;
+\endif
+-----
 -- Test that various stats views are being properly populated
 -----
 -- Test that sessions is incremented when a new session is started in pg_stat_database
index 252d7161bde452211aadf33a4c37ab0ab5df93ea..73c8d38b15fa4d7b0752bdae928eac1dd754974e 100644 (file)
@@ -289,6 +289,36 @@ SELECT pg_stat_get_live_tuples(:drop_stats_test_subxact_oid);
 DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4;
 DROP TABLE prevstats;
 
+-----
+-- Test reset of some stats for shared table
+-----
+
+-- This updates the comment of the database currently in use in
+-- pg_shdescription with a fake value, then sets it back to its
+-- original value.
+SELECT shobj_description(d.oid, 'pg_database') as description_before
+  FROM pg_database d WHERE datname = current_database() \gset
+
+-- force some stats in pg_shdescription.
+BEGIN;
+SELECT current_database() as datname \gset
+COMMENT ON DATABASE :"datname" IS 'This is a test comment';
+SELECT pg_stat_force_next_flush();
+COMMIT;
+
+-- check that the stats are reset.
+SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables
+  WHERE relid = 'pg_shdescription'::regclass;
+SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass);
+SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables
+  WHERE relid = 'pg_shdescription'::regclass;
+
+-- set back comment
+\if :{?description_before}
+  COMMENT ON DATABASE :"datname" IS :'description_before';
+\else
+  COMMENT ON DATABASE :"datname" IS NULL;
+\endif
 
 -----
 -- Test that various stats views are being properly populated