From fd01edc7fa34cb43b631e35324104cf629422ac1 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Tue, 16 Apr 2024 13:05:34 +1200
Subject: [PATCH v3] Add context type field to pg_backend_memory_contexts

---
 doc/src/sgml/system-views.sgml         |  9 +++++++
 src/backend/utils/adt/mcxtfuncs.c      | 35 ++++++++++++++++++++------
 src/include/catalog/pg_proc.dat        |  6 ++---
 src/test/regress/expected/rules.out    |  3 ++-
 src/test/regress/expected/sysviews.out | 16 ++++++------
 src/test/regress/sql/sysviews.sql      |  4 +--
 6 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 8c18bea902..bdc34cf94e 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -490,6 +490,15 @@
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>type</structfield> <type>text</type>
+      </para>
+      <para>
+       Type of the memory context
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>level</structfield> <type>int4</type>
diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c
index 4d4a70915b..1085941484 100644
--- a/src/backend/utils/adt/mcxtfuncs.c
+++ b/src/backend/utils/adt/mcxtfuncs.c
@@ -36,7 +36,7 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
 								 TupleDesc tupdesc, MemoryContext context,
 								 const char *parent, int level)
 {
-#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS	9
+#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS	10
 
 	Datum		values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
 	bool		nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
@@ -44,6 +44,7 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
 	MemoryContext child;
 	const char *name;
 	const char *ident;
+	const char *type;
 
 	Assert(MemoryContextIsValid(context));
 
@@ -96,12 +97,32 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
 	else
 		nulls[2] = true;
 
-	values[3] = Int32GetDatum(level);
-	values[4] = Int64GetDatum(stat.totalspace);
-	values[5] = Int64GetDatum(stat.nblocks);
-	values[6] = Int64GetDatum(stat.freespace);
-	values[7] = Int64GetDatum(stat.freechunks);
-	values[8] = Int64GetDatum(stat.totalspace - stat.freespace);
+	switch (context->type)
+	{
+		case T_AllocSetContext:
+			type = "AllocSet";
+			break;
+		case T_GenerationContext:
+			type = "Generation";
+			break;
+		case T_SlabContext:
+			type = "Slab";
+			break;
+		case T_BumpContext:
+			type = "Bump";
+			break;
+		default:
+			type = "???";
+			break;
+	}
+
+	values[3] = CStringGetTextDatum(type);
+	values[4] = Int32GetDatum(level);
+	values[5] = Int64GetDatum(stat.totalspace);
+	values[6] = Int64GetDatum(stat.nblocks);
+	values[7] = Int64GetDatum(stat.freespace);
+	values[8] = Int64GetDatum(stat.freechunks);
+	values[9] = Int64GetDatum(stat.totalspace - stat.freespace);
 	tuplestore_putvalues(tupstore, tupdesc, values, nulls);
 
 	for (child = context->firstchild; child != NULL; child = child->nextchild)
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6a5476d3c4..d4ac578ae6 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8279,9 +8279,9 @@
   proname => 'pg_get_backend_memory_contexts', prorows => '100',
   proretset => 't', provolatile => 'v', proparallel => 'r',
   prorettype => 'record', proargtypes => '',
-  proallargtypes => '{text,text,text,int4,int8,int8,int8,int8,int8}',
-  proargmodes => '{o,o,o,o,o,o,o,o,o}',
-  proargnames => '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}',
+  proallargtypes => '{text,text,text,text,int4,int8,int8,int8,int8,int8}',
+  proargmodes => '{o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{name, ident, parent, type, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}',
   prosrc => 'pg_get_backend_memory_contexts' },
 
 # logging memory contexts of the specified backend
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index ef658ad740..bed1d029f5 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1306,13 +1306,14 @@ pg_available_extensions| SELECT e.name,
 pg_backend_memory_contexts| SELECT name,
     ident,
     parent,
+    type,
     level,
     total_bytes,
     total_nblocks,
     free_bytes,
     free_chunks,
     used_bytes
-   FROM pg_get_backend_memory_contexts() pg_get_backend_memory_contexts(name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes);
+   FROM pg_get_backend_memory_contexts() pg_get_backend_memory_contexts(name, ident, parent, type, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes);
 pg_config| SELECT name,
     setting
    FROM pg_config() pg_config(name, setting);
diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out
index dbfd0c13d4..c8e3d3620c 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -21,11 +21,11 @@ select count(*) >= 0 as ok from pg_available_extensions;
 
 -- The entire output of pg_backend_memory_contexts is not stable,
 -- we test only the existence and basic condition of TopMemoryContext.
-select name, ident, parent, level, total_bytes >= free_bytes
+select type, name, ident, parent, level, total_bytes >= free_bytes
   from pg_backend_memory_contexts where level = 0;
-       name       | ident | parent | level | ?column? 
-------------------+-------+--------+-------+----------
- TopMemoryContext |       |        |     0 | t
+   type   |       name       | ident | parent | level | ?column? 
+----------+------------------+-------+--------+-------+----------
+ AllocSet | TopMemoryContext |       |        |     0 | t
 (1 row)
 
 -- We can exercise some MemoryContext type stats functions.  Most of the
@@ -43,11 +43,11 @@ fetch 1 from cur;
  bbbbbbbbbb | 2
 (1 row)
 
-select name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
+select type, name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
 from pg_backend_memory_contexts where name = 'Caller tuples';
-     name      |     parent     | ?column? | total_nblocks | ?column? | free_chunks 
----------------+----------------+----------+---------------+----------+-------------
- Caller tuples | TupleSort sort | t        |             2 | t        |           0
+ type |     name      |     parent     | ?column? | total_nblocks | ?column? | free_chunks 
+------+---------------+----------------+----------+---------------+----------+-------------
+ Bump | Caller tuples | TupleSort sort | t        |             2 | t        |           0
 (1 row)
 
 rollback;
diff --git a/src/test/regress/sql/sysviews.sql b/src/test/regress/sql/sysviews.sql
index c4f59ddc89..b899de174f 100644
--- a/src/test/regress/sql/sysviews.sql
+++ b/src/test/regress/sql/sysviews.sql
@@ -14,7 +14,7 @@ select count(*) >= 0 as ok from pg_available_extensions;
 
 -- The entire output of pg_backend_memory_contexts is not stable,
 -- we test only the existence and basic condition of TopMemoryContext.
-select name, ident, parent, level, total_bytes >= free_bytes
+select type, name, ident, parent, level, total_bytes >= free_bytes
   from pg_backend_memory_contexts where level = 0;
 
 -- We can exercise some MemoryContext type stats functions.  Most of the
@@ -28,7 +28,7 @@ declare cur cursor for select left(a,10), b
   from (values(repeat('a', 512 * 1024),1),(repeat('b', 512),2)) v(a,b)
   order by v.a desc;
 fetch 1 from cur;
-select name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
+select type, name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
 from pg_backend_memory_contexts where name = 'Caller tuples';
 rollback;
 
-- 
2.34.1

