From 12946dca2ebe3b59a69a66175ca0828ca0dd2001 Mon Sep 17 00:00:00 2001
From: dmitry <dmitry.fomin@adyen.com>
Date: Fri, 7 Mar 2025 16:04:04 +0100
Subject: [PATCH] add fields isregularbackend, databaseid, roleid to _current
 and  _history views

---
 collector.c                    |  3 ++
 pg_wait_sampling--1.1--1.2.sql | 73 ++++++++++++++++++++++++++++++++++
 pg_wait_sampling--1.2.sql      | 66 ++++++++++++++++++++++++++++++
 pg_wait_sampling.c             | 37 ++++++++++++++---
 pg_wait_sampling.control       |  2 +-
 pg_wait_sampling.h             |  3 ++
 6 files changed, 177 insertions(+), 7 deletions(-)
 create mode 100644 pg_wait_sampling--1.1--1.2.sql
 create mode 100644 pg_wait_sampling--1.2.sql

diff --git a/collector.c b/collector.c
index 721299f..27874c5 100644
--- a/collector.c
+++ b/collector.c
@@ -175,6 +175,9 @@ probe_waits(History *observations, HTAB *profile_hash,
 			item.queryId = 0;
 
 		item.ts = ts;
+		item.isRegularBackend = !(proc->isBackgroundWorker);
+		item.databaseId = proc->databaseId;
+		item.roleId = proc->roleId;		
 
 		/* Write to the history if needed */
 		if (write_history)
diff --git a/pg_wait_sampling--1.1--1.2.sql b/pg_wait_sampling--1.1--1.2.sql
new file mode 100644
index 0000000..7f37862
--- /dev/null
+++ b/pg_wait_sampling--1.1--1.2.sql
@@ -0,0 +1,73 @@
+/* contrib/pg_wait_sampling/pg_wait_sampling--1.0--1.1.sql */
+
+DROP FUNCTION pg_wait_sampling_get_current (
+	pid int4,
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text
+) CASCADE;
+
+DROP FUNCTION pg_wait_sampling_get_history (
+	OUT pid int4,
+	OUT ts timestamptz,
+	OUT event_type text,
+	OUT event text
+) CASCADE;
+
+DROP FUNCTION pg_wait_sampling_get_profile (
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text,
+	OUT count bigint
+) CASCADE;
+
+CREATE FUNCTION pg_wait_sampling_get_current (
+	pid int4,
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8,
+	OUT isregularbackend boolean,
+	OUT databaseid oid,
+	OUT roleid oid
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE CALLED ON NULL INPUT;
+
+CREATE VIEW pg_wait_sampling_current AS
+	SELECT * FROM pg_wait_sampling_get_current(NULL::integer);
+
+GRANT SELECT ON pg_wait_sampling_current TO PUBLIC;
+
+CREATE FUNCTION pg_wait_sampling_get_history (
+	OUT pid int4,
+	OUT ts timestamptz,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE VIEW pg_wait_sampling_history AS
+	SELECT * FROM pg_wait_sampling_get_history();
+
+GRANT SELECT ON pg_wait_sampling_history TO PUBLIC;
+
+CREATE FUNCTION pg_wait_sampling_get_profile (
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8,
+	OUT count int8
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE VIEW pg_wait_sampling_profile AS
+	SELECT * FROM pg_wait_sampling_get_profile();
+
+GRANT SELECT ON pg_wait_sampling_profile TO PUBLIC;
diff --git a/pg_wait_sampling--1.2.sql b/pg_wait_sampling--1.2.sql
new file mode 100644
index 0000000..bb6bac8
--- /dev/null
+++ b/pg_wait_sampling--1.2.sql
@@ -0,0 +1,66 @@
+/* contrib/pg_wait_sampling/setup.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pg_wait_sampling" to load this file. \quit
+
+CREATE FUNCTION pg_wait_sampling_get_current (
+	pid int4,
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8,
+	OUT isregularbackend boolean,
+	OUT databaseid oid,
+	OUT roleid oid
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE CALLED ON NULL INPUT;
+
+CREATE VIEW pg_wait_sampling_current AS
+	SELECT * FROM pg_wait_sampling_get_current(NULL::integer);
+
+GRANT SELECT ON pg_wait_sampling_current TO PUBLIC;
+
+CREATE FUNCTION pg_wait_sampling_get_history (
+	OUT pid int4,
+	OUT ts timestamptz,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8,
+	OUT isregularbackend boolean,
+	OUT databaseid oid,
+	OUT roleid oid	
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE VIEW pg_wait_sampling_history AS
+	SELECT * FROM pg_wait_sampling_get_history();
+
+GRANT SELECT ON pg_wait_sampling_history TO PUBLIC;
+
+CREATE FUNCTION pg_wait_sampling_get_profile (
+	OUT pid int4,
+	OUT event_type text,
+	OUT event text,
+	OUT queryid int8,
+	OUT count int8
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE VIEW pg_wait_sampling_profile AS
+	SELECT * FROM pg_wait_sampling_get_profile();
+
+GRANT SELECT ON pg_wait_sampling_profile TO PUBLIC;
+
+CREATE FUNCTION pg_wait_sampling_reset_profile()
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C VOLATILE STRICT;
+
+-- Don't want this to be available to non-superusers.
+REVOKE ALL ON FUNCTION pg_wait_sampling_reset_profile() FROM PUBLIC;
diff --git a/pg_wait_sampling.c b/pg_wait_sampling.c
index a35fb94..f9502f5 100644
--- a/pg_wait_sampling.c
+++ b/pg_wait_sampling.c
@@ -514,7 +514,7 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 		params->ts = GetCurrentTimestamp();
 
 		funcctx->user_fctx = params;
-		tupdesc = CreateTemplateTupleDesc(4);
+		tupdesc = CreateTemplateTupleDesc(7);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pid",
 						   INT4OID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "type",
@@ -523,6 +523,12 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "queryid",
 						   INT8OID, -1, 0);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "isregularbackend",
+						   BOOLOID, -1, 0);
+				TupleDescInitEntry(tupdesc, (AttrNumber) 6, "databaseid",
+						   OIDOID, -1, 0);
+				TupleDescInitEntry(tupdesc, (AttrNumber) 7, "roleid",
+						   OIDOID, -1, 0);
 
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 
@@ -540,6 +546,9 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 			item->pid = proc->pid;
 			item->wait_event_info = proc->wait_event_info;
 			item->queryId = pgws_proc_queryids[proc - ProcGlobal->allProcs];
+			item->isRegularBackend = !(proc->isBackgroundWorker);
+			item->databaseId = proc->databaseId;
+			item->roleId = proc->roleId;
 			funcctx->max_calls = 1;
 		}
 		else
@@ -562,6 +571,9 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 				params->items[j].pid = proc->pid;
 				params->items[j].wait_event_info = proc->wait_event_info;
 				params->items[j].queryId = pgws_proc_queryids[i];
+				params->items[j].isRegularBackend = !(proc->isBackgroundWorker);
+				params->items[j].databaseId = proc->databaseId;
+				params->items[j].roleId = proc->roleId;
 				j++;
 			}
 			funcctx->max_calls = j;
@@ -579,8 +591,8 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 	if (funcctx->call_cntr < funcctx->max_calls)
 	{
 		HeapTuple	tuple;
-		Datum		values[4];
-		bool		nulls[4];
+		Datum		values[7];
+		bool		nulls[7];
 		const char *event_type,
 				   *event;
 		HistoryItem *item;
@@ -604,6 +616,9 @@ pg_wait_sampling_get_current(PG_FUNCTION_ARGS)
 			nulls[2] = true;
 
 		values[3] = UInt64GetDatum(item->queryId);
+		values[4] = BoolGetDatum(item->isRegularBackend);
+		values[5] = ObjectIdGetDatum(item->databaseId);
+		values[6] = ObjectIdGetDatum(item->roleId);
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 
 		SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
@@ -858,7 +873,7 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
 		funcctx->max_calls = history->count;
 
 		/* Make tuple descriptor */
-		tupdesc = CreateTemplateTupleDesc(5);
+		tupdesc = CreateTemplateTupleDesc(8);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pid",
 						   INT4OID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "sample_ts",
@@ -869,6 +884,13 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "queryid",
 						   INT8OID, -1, 0);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 6, "isregularbackend",
+						   BOOLOID, -1, 0),
+		TupleDescInitEntry(tupdesc, (AttrNumber) 7, "databaseid",
+						   OIDOID, -1, 0),
+		TupleDescInitEntry(tupdesc, (AttrNumber) 8, "roleid",
+						   OIDOID, -1, 0);
+
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 
 		MemoryContextSwitchTo(oldcontext);
@@ -883,8 +905,8 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
 	{
 		HeapTuple	tuple;
 		HistoryItem *item;
-		Datum		values[5];
-		bool		nulls[5];
+		Datum		values[8];
+		bool		nulls[8];
 		const char *event_type,
 				   *event;
 
@@ -908,6 +930,9 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
 			nulls[3] = true;
 
 		values[4] = UInt64GetDatum(item->queryId);
+		values[5] = BoolGetDatum(item->isRegularBackend);
+		values[6] = ObjectIdGetDatum(item->databaseId);
+		values[7] = ObjectIdGetDatum(item->roleId);
 		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
 
 		history->index++;
diff --git a/pg_wait_sampling.control b/pg_wait_sampling.control
index 97d9a34..d2d0ffe 100644
--- a/pg_wait_sampling.control
+++ b/pg_wait_sampling.control
@@ -1,5 +1,5 @@
 # pg_wait_sampling extension
 comment = 'sampling based statistics of wait events'
-default_version = '1.1'
+default_version = '1.2'
 module_pathname = '$libdir/pg_wait_sampling'
 relocatable = true
diff --git a/pg_wait_sampling.h b/pg_wait_sampling.h
index dab773c..80215fc 100644
--- a/pg_wait_sampling.h
+++ b/pg_wait_sampling.h
@@ -34,6 +34,9 @@ typedef struct
 	int			pid;
 	uint32		wait_event_info;
 	uint64		queryId;
+	bool		isRegularBackend;
+	Oid			databaseId;
+	Oid			roleId;
 	TimestampTz ts;
 } HistoryItem;