From 29213be9dc11cbff3e6f2d046a7df45e7a01ba18 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sun, 27 Mar 2022 22:05:53 -0700
Subject: [PATCH v69 20/28] pgstat: test: extend replication slot stat tests

---
 contrib/test_decoding/expected/stats.out | 117 +++++++++++++++++------
 contrib/test_decoding/sql/stats.sql      |  32 +++++--
 2 files changed, 111 insertions(+), 38 deletions(-)

diff --git a/contrib/test_decoding/expected/stats.out b/contrib/test_decoding/expected/stats.out
index 5dd1926176c..800c727d6e1 100644
--- a/contrib/test_decoding/expected/stats.out
+++ b/contrib/test_decoding/expected/stats.out
@@ -1,6 +1,9 @@
 -- predictability
 SET synchronous_commit = on;
-SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_stats', 'test_decoding');
+SELECT 'init' FROM
+    pg_create_logical_replication_slot('regression_slot_stats1', 'test_decoding') s1,
+    pg_create_logical_replication_slot('regression_slot_stats2', 'test_decoding') s2,
+    pg_create_logical_replication_slot('regression_slot_stats3', 'test_decoding') s3;
  ?column? 
 ----------
  init
@@ -10,7 +13,19 @@ CREATE TABLE stats_test(data text);
 -- non-spilled xact
 SET logical_decoding_work_mem to '64MB';
 INSERT INTO stats_test values(1);
-SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1');
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats2', NULL, NULL, 'skip-empty-xacts', '1');
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats3', NULL, NULL, 'skip-empty-xacts', '1');
  count 
 -------
      3
@@ -22,31 +37,65 @@ SELECT pg_stat_force_next_flush();
  
 (1 row)
 
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots;
-       slot_name       | spill_txns | spill_count | total_txns | total_bytes 
------------------------+------------+-------------+------------+-------------
- regression_slot_stats | t          | t           | t          | t
-(1 row)
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+       slot_name        | spill_txns | spill_count | total_txns | total_bytes 
+------------------------+------------+-------------+------------+-------------
+ regression_slot_stats1 | t          | t           | t          | t
+ regression_slot_stats2 | t          | t           | t          | t
+ regression_slot_stats3 | t          | t           | t          | t
+(3 rows)
 
 RESET logical_decoding_work_mem;
--- reset the slot stats
-SELECT pg_stat_reset_replication_slot('regression_slot_stats');
+-- reset stats for one slot, others should be unaffected
+SELECT pg_stat_reset_replication_slot('regression_slot_stats1');
  pg_stat_reset_replication_slot 
 --------------------------------
  
 (1 row)
 
-SELECT slot_name, spill_txns, spill_count, total_txns, total_bytes FROM pg_stat_replication_slots;
-       slot_name       | spill_txns | spill_count | total_txns | total_bytes 
------------------------+------------+-------------+------------+-------------
- regression_slot_stats |          0 |           0 |          0 |           0
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+       slot_name        | spill_txns | spill_count | total_txns | total_bytes 
+------------------------+------------+-------------+------------+-------------
+ regression_slot_stats1 | t          | t           | f          | f
+ regression_slot_stats2 | t          | t           | t          | t
+ regression_slot_stats3 | t          | t           | t          | t
+(3 rows)
+
+-- reset stats for all slots
+SELECT pg_stat_reset_replication_slot(NULL);
+ pg_stat_reset_replication_slot 
+--------------------------------
+ 
+(1 row)
+
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+       slot_name        | spill_txns | spill_count | total_txns | total_bytes 
+------------------------+------------+-------------+------------+-------------
+ regression_slot_stats1 | t          | t           | f          | f
+ regression_slot_stats2 | t          | t           | f          | f
+ regression_slot_stats3 | t          | t           | f          | f
+(3 rows)
+
+-- verify accessing/resetting stats for non-existent slot does something reasonable
+SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
+  slot_name   | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_txns | total_bytes | stats_reset 
+--------------+------------+-------------+-------------+-------------+--------------+--------------+------------+-------------+-------------
+ do-not-exist |          0 |           0 |           0 |           0 |            0 |            0 |          0 |           0 | 
+(1 row)
+
+SELECT pg_stat_reset_replication_slot('do-not-exist');
+ERROR:  replication slot "do-not-exist" does not exist
+SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
+  slot_name   | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_txns | total_bytes | stats_reset 
+--------------+------------+-------------+-------------+-------------+--------------+--------------+------------+-------------+-------------
+ do-not-exist |          0 |           0 |           0 |           0 |            0 |            0 |          0 |           0 | 
 (1 row)
 
 -- spilling the xact
 BEGIN;
 INSERT INTO stats_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i);
 COMMIT;
-SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1');
  count 
 -------
   5002
@@ -62,32 +111,40 @@ SELECT pg_stat_force_next_flush();
 (1 row)
 
 SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count FROM pg_stat_replication_slots;
-       slot_name       | spill_txns | spill_count 
------------------------+------------+-------------
- regression_slot_stats | t          | t
-(1 row)
+       slot_name        | spill_txns | spill_count 
+------------------------+------------+-------------
+ regression_slot_stats1 | t          | t
+ regression_slot_stats2 | f          | f
+ regression_slot_stats3 | f          | f
+(3 rows)
 
 -- Ensure stats can be repeatedly accessed using the same stats snapshot. See
 -- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de
 BEGIN;
 SET LOCAL stats_fetch_consistency = snapshot;
 SELECT slot_name FROM pg_stat_replication_slots;
-       slot_name       
------------------------
- regression_slot_stats
-(1 row)
+       slot_name        
+------------------------
+ regression_slot_stats1
+ regression_slot_stats2
+ regression_slot_stats3
+(3 rows)
 
 SELECT slot_name FROM pg_stat_replication_slots;
-       slot_name       
------------------------
- regression_slot_stats
-(1 row)
+       slot_name        
+------------------------
+ regression_slot_stats1
+ regression_slot_stats2
+ regression_slot_stats3
+(3 rows)
 
 COMMIT;
 DROP TABLE stats_test;
-SELECT pg_drop_replication_slot('regression_slot_stats');
- pg_drop_replication_slot 
---------------------------
- 
+SELECT pg_drop_replication_slot('regression_slot_stats1'),
+    pg_drop_replication_slot('regression_slot_stats2'),
+    pg_drop_replication_slot('regression_slot_stats3');
+ pg_drop_replication_slot | pg_drop_replication_slot | pg_drop_replication_slot 
+--------------------------+--------------------------+--------------------------
+                          |                          | 
 (1 row)
 
diff --git a/contrib/test_decoding/sql/stats.sql b/contrib/test_decoding/sql/stats.sql
index 464b9cd1fe3..3c2d26138d6 100644
--- a/contrib/test_decoding/sql/stats.sql
+++ b/contrib/test_decoding/sql/stats.sql
@@ -1,27 +1,41 @@
 -- predictability
 SET synchronous_commit = on;
 
-SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_stats', 'test_decoding');
+SELECT 'init' FROM
+    pg_create_logical_replication_slot('regression_slot_stats1', 'test_decoding') s1,
+    pg_create_logical_replication_slot('regression_slot_stats2', 'test_decoding') s2,
+    pg_create_logical_replication_slot('regression_slot_stats3', 'test_decoding') s3;
 
 CREATE TABLE stats_test(data text);
 
 -- non-spilled xact
 SET logical_decoding_work_mem to '64MB';
 INSERT INTO stats_test values(1);
-SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats2', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats3', NULL, NULL, 'skip-empty-xacts', '1');
 SELECT pg_stat_force_next_flush();
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots;
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
 RESET logical_decoding_work_mem;
 
--- reset the slot stats
-SELECT pg_stat_reset_replication_slot('regression_slot_stats');
-SELECT slot_name, spill_txns, spill_count, total_txns, total_bytes FROM pg_stat_replication_slots;
+-- reset stats for one slot, others should be unaffected
+SELECT pg_stat_reset_replication_slot('regression_slot_stats1');
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+
+-- reset stats for all slots
+SELECT pg_stat_reset_replication_slot(NULL);
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+
+-- verify accessing/resetting stats for non-existent slot does something reasonable
+SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
+SELECT pg_stat_reset_replication_slot('do-not-exist');
+SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
 
 -- spilling the xact
 BEGIN;
 INSERT INTO stats_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i);
 COMMIT;
-SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1');
+SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1');
 
 -- Check stats. We can't test the exact stats count as that can vary if any
 -- background transaction (say by autovacuum) happens in parallel to the main
@@ -38,4 +52,6 @@ SELECT slot_name FROM pg_stat_replication_slots;
 COMMIT;
 
 DROP TABLE stats_test;
-SELECT pg_drop_replication_slot('regression_slot_stats');
+SELECT pg_drop_replication_slot('regression_slot_stats1'),
+    pg_drop_replication_slot('regression_slot_stats2'),
+    pg_drop_replication_slot('regression_slot_stats3');
-- 
2.35.1.677.gabf474a5dd

