In [1] Andres mentioned that there's no way to determine the memory
context type in pg_backend_memory_contexts. This is a bit annoying as
I'd like to add a test to exercise BumpStats().

Having the context type in the test's expected output helps ensure we
are exercising BumpStats() and any future changes to the choice of
context type in tuplesort.c gets flagged up by the test breaking.

It's probably too late for PG17, but I'll leave this here for the July CF.

David

[1] 
https://www.postgresql.org/message-id/20240415225749.xg7uq2hwuq2qm...@awork3.anarazel.de
From 0a58697a4b88bc3ac80f09ed78b56ebe903a2aae Mon Sep 17 00:00:00 2001
From: David Rowley <dgrow...@gmail.com>
Date: Tue, 16 Apr 2024 13:05:34 +1200
Subject: [PATCH v1] Add context type field to pg_backend_memory_contexts

---
 doc/src/sgml/system-views.sgml         |  9 +++++
 src/backend/utils/adt/mcxtfuncs.c      | 50 ++++++++++++++++++--------
 src/include/catalog/pg_proc.dat        |  6 ++--
 src/test/regress/expected/rules.out    |  5 +--
 src/test/regress/expected/sysviews.out |  8 ++---
 src/test/regress/sql/sysviews.sql      |  2 +-
 6 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 7ed617170f..18ae5b9138 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -463,6 +463,15 @@
     </thead>
 
     <tbody>
+     <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>name</structfield> <type>text</type>
diff --git a/src/backend/utils/adt/mcxtfuncs.c 
b/src/backend/utils/adt/mcxtfuncs.c
index 4d4a70915b..fe52d57fd4 100644
--- a/src/backend/utils/adt/mcxtfuncs.c
+++ b/src/backend/utils/adt/mcxtfuncs.c
@@ -36,12 +36,13 @@ 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];
        MemoryContextCounters stat;
        MemoryContext child;
+       const char *type;
        const char *name;
        const char *ident;
 
@@ -67,10 +68,31 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
        memset(values, 0, sizeof(values));
        memset(nulls, 0, sizeof(nulls));
 
+       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[0] = CStringGetTextDatum(type);
+
        if (name)
-               values[0] = CStringGetTextDatum(name);
+               values[1] = CStringGetTextDatum(name);
        else
-               nulls[0] = true;
+               nulls[1] = true;
 
        if (ident)
        {
@@ -86,22 +108,22 @@ PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
 
                memcpy(clipped_ident, ident, idlen);
                clipped_ident[idlen] = '\0';
-               values[1] = CStringGetTextDatum(clipped_ident);
+               values[2] = CStringGetTextDatum(clipped_ident);
        }
        else
-               nulls[1] = true;
+               nulls[2] = true;
 
        if (parent)
-               values[2] = CStringGetTextDatum(parent);
+               values[3] = CStringGetTextDatum(parent);
        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);
+               nulls[3] = true;
+
+       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 134e3b22fd..adda675887 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8277,9 +8277,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 => '{type, name, ident, parent, 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 f4a0f36377..a8ac58201d 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1303,7 +1303,8 @@ pg_available_extensions| SELECT e.name,
     e.comment
    FROM (pg_available_extensions() e(name, default_version, comment)
      LEFT JOIN pg_extension x ON ((e.name = x.extname)));
-pg_backend_memory_contexts| SELECT name,
+pg_backend_memory_contexts| SELECT type,
+    name,
     ident,
     parent,
     level,
@@ -1312,7 +1313,7 @@ pg_backend_memory_contexts| SELECT name,
     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(type, 
name, ident, parent, 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 9be7aca2b8..85585facdc 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)
 
 -- At introduction, pg_config had 23 entries; it may grow
diff --git a/src/test/regress/sql/sysviews.sql 
b/src/test/regress/sql/sysviews.sql
index 6b4e24601d..eb4bbf01b2 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;
 
 -- At introduction, pg_config had 23 entries; it may grow
-- 
2.40.1.windows.1

Reply via email to