Skip to content

Commit 50db596

Browse files
committed
Move codes for pg_backend_memory_contexts from mmgr/mcxt.c to adt/mcxtfuncs.c.
Previously the codes for pg_backend_memory_contexts were in src/backend/utils/mmgr/mcxt.c. This commit moves them to src/backend/utils/adt/mcxtfuncs.c so that mcxt.c basically includes only the low-level interface for memory contexts. Author: Atsushi Torikoshi Reviewed-by: Michael Paquier, Fujii Masao Discussion: https://postgr.es/m/20200819135545.GC19121@paquier.xyz
1 parent 29dd6d8 commit 50db596

File tree

3 files changed

+158
-137
lines changed

3 files changed

+158
-137
lines changed

src/backend/utils/adt/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ OBJS = \
5757
lockfuncs.o \
5858
mac.o \
5959
mac8.o \
60+
mcxtfuncs.o \
6061
misc.o \
6162
name.o \
6263
network.o \

src/backend/utils/adt/mcxtfuncs.c

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* mcxtfuncs.c
4+
* Functions to show backend memory context.
5+
*
6+
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
*
10+
* IDENTIFICATION
11+
* src/backend/utils/adt/mcxtfuncs.c
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
15+
16+
#include "postgres.h"
17+
18+
#include "funcapi.h"
19+
#include "miscadmin.h"
20+
#include "mb/pg_wchar.h"
21+
#include "utils/builtins.h"
22+
23+
/* ----------
24+
* The max bytes for showing identifiers of MemoryContext.
25+
* ----------
26+
*/
27+
#define MEMORY_CONTEXT_IDENT_DISPLAY_SIZE 1024
28+
29+
/*
30+
* PutMemoryContextsStatsTupleStore
31+
* One recursion level for pg_get_backend_memory_contexts.
32+
*/
33+
static void
34+
PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
35+
TupleDesc tupdesc, MemoryContext context,
36+
const char *parent, int level)
37+
{
38+
#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9
39+
40+
Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
41+
bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
42+
MemoryContextCounters stat;
43+
MemoryContext child;
44+
const char *name;
45+
const char *ident;
46+
47+
AssertArg(MemoryContextIsValid(context));
48+
49+
name = context->name;
50+
ident = context->ident;
51+
52+
/*
53+
* To be consistent with logging output, we label dynahash contexts
54+
* with just the hash table name as with MemoryContextStatsPrint().
55+
*/
56+
if (ident && strcmp(name, "dynahash") == 0)
57+
{
58+
name = ident;
59+
ident = NULL;
60+
}
61+
62+
/* Examine the context itself */
63+
memset(&stat, 0, sizeof(stat));
64+
(*context->methods->stats) (context, NULL, (void *) &level, &stat);
65+
66+
memset(values, 0, sizeof(values));
67+
memset(nulls, 0, sizeof(nulls));
68+
69+
if (name)
70+
values[0] = CStringGetTextDatum(name);
71+
else
72+
nulls[0] = true;
73+
74+
if (ident)
75+
{
76+
int idlen = strlen(ident);
77+
char clipped_ident[MEMORY_CONTEXT_IDENT_DISPLAY_SIZE];
78+
79+
/*
80+
* Some identifiers such as SQL query string can be very long,
81+
* truncate oversize identifiers.
82+
*/
83+
if (idlen >= MEMORY_CONTEXT_IDENT_DISPLAY_SIZE)
84+
idlen = pg_mbcliplen(ident, idlen, MEMORY_CONTEXT_IDENT_DISPLAY_SIZE - 1);
85+
86+
memcpy(clipped_ident, ident, idlen);
87+
clipped_ident[idlen] = '\0';
88+
values[1] = CStringGetTextDatum(clipped_ident);
89+
}
90+
else
91+
nulls[1] = true;
92+
93+
if (parent)
94+
values[2] = CStringGetTextDatum(parent);
95+
else
96+
nulls[2] = true;
97+
98+
values[3] = Int32GetDatum(level);
99+
values[4] = Int64GetDatum(stat.totalspace);
100+
values[5] = Int64GetDatum(stat.nblocks);
101+
values[6] = Int64GetDatum(stat.freespace);
102+
values[7] = Int64GetDatum(stat.freechunks);
103+
values[8] = Int64GetDatum(stat.totalspace - stat.freespace);
104+
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
105+
106+
for (child = context->firstchild; child != NULL; child = child->nextchild)
107+
{
108+
PutMemoryContextsStatsTupleStore(tupstore, tupdesc,
109+
child, name, level + 1);
110+
}
111+
}
112+
113+
/*
114+
* pg_get_backend_memory_contexts
115+
* SQL SRF showing backend memory context.
116+
*/
117+
Datum
118+
pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
119+
{
120+
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
121+
TupleDesc tupdesc;
122+
Tuplestorestate *tupstore;
123+
MemoryContext per_query_ctx;
124+
MemoryContext oldcontext;
125+
126+
/* check to see if caller supports us returning a tuplestore */
127+
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
128+
ereport(ERROR,
129+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
130+
errmsg("set-valued function called in context that cannot accept a set")));
131+
if (!(rsinfo->allowedModes & SFRM_Materialize))
132+
ereport(ERROR,
133+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
134+
errmsg("materialize mode required, but it is not allowed in this context")));
135+
136+
/* Build a tuple descriptor for our result type */
137+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
138+
elog(ERROR, "return type must be a row type");
139+
140+
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
141+
oldcontext = MemoryContextSwitchTo(per_query_ctx);
142+
143+
tupstore = tuplestore_begin_heap(true, false, work_mem);
144+
rsinfo->returnMode = SFRM_Materialize;
145+
rsinfo->setResult = tupstore;
146+
rsinfo->setDesc = tupdesc;
147+
148+
MemoryContextSwitchTo(oldcontext);
149+
150+
PutMemoryContextsStatsTupleStore(tupstore, tupdesc,
151+
TopMemoryContext, NULL, 0);
152+
153+
/* clean up and return the tuplestore */
154+
tuplestore_donestoring(tupstore);
155+
156+
return (Datum) 0;
157+
}

src/backend/utils/mmgr/mcxt.c

Lines changed: 0 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@
2121

2222
#include "postgres.h"
2323

24-
#include "funcapi.h"
2524
#include "mb/pg_wchar.h"
2625
#include "miscadmin.h"
27-
#include "utils/builtins.h"
2826
#include "utils/memdebug.h"
2927
#include "utils/memutils.h"
3028

@@ -69,11 +67,6 @@ static void MemoryContextStatsPrint(MemoryContext context, void *passthru,
6967
#define AssertNotInCriticalSection(context) \
7068
Assert(CritSectionCount == 0 || (context)->allowInCritSection)
7169

72-
/* ----------
73-
* The max bytes for showing identifiers of MemoryContext.
74-
* ----------
75-
*/
76-
#define MEMORY_CONTEXT_IDENT_DISPLAY_SIZE 1024
7770

7871
/*****************************************************************************
7972
* EXPORTED ROUTINES *
@@ -1228,133 +1221,3 @@ pchomp(const char *in)
12281221
n--;
12291222
return pnstrdup(in, n);
12301223
}
1231-
1232-
/*
1233-
* PutMemoryContextsStatsTupleStore
1234-
* One recursion level for pg_get_backend_memory_contexts.
1235-
*/
1236-
static void
1237-
PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore,
1238-
TupleDesc tupdesc, MemoryContext context,
1239-
const char *parent, int level)
1240-
{
1241-
#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9
1242-
1243-
Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
1244-
bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS];
1245-
MemoryContextCounters stat;
1246-
MemoryContext child;
1247-
const char *name;
1248-
const char *ident;
1249-
1250-
AssertArg(MemoryContextIsValid(context));
1251-
1252-
name = context->name;
1253-
ident = context->ident;
1254-
1255-
/*
1256-
* To be consistent with logging output, we label dynahash contexts
1257-
* with just the hash table name as with MemoryContextStatsPrint().
1258-
*/
1259-
if (ident && strcmp(name, "dynahash") == 0)
1260-
{
1261-
name = ident;
1262-
ident = NULL;
1263-
}
1264-
1265-
/* Examine the context itself */
1266-
memset(&stat, 0, sizeof(stat));
1267-
(*context->methods->stats) (context, NULL, (void *) &level, &stat);
1268-
1269-
memset(values, 0, sizeof(values));
1270-
memset(nulls, 0, sizeof(nulls));
1271-
1272-
if (name)
1273-
values[0] = CStringGetTextDatum(name);
1274-
else
1275-
nulls[0] = true;
1276-
1277-
if (ident)
1278-
{
1279-
int idlen = strlen(ident);
1280-
char clipped_ident[MEMORY_CONTEXT_IDENT_DISPLAY_SIZE];
1281-
1282-
/*
1283-
* Some identifiers such as SQL query string can be very long,
1284-
* truncate oversize identifiers.
1285-
*/
1286-
if (idlen >= MEMORY_CONTEXT_IDENT_DISPLAY_SIZE)
1287-
idlen = pg_mbcliplen(ident, idlen, MEMORY_CONTEXT_IDENT_DISPLAY_SIZE - 1);
1288-
1289-
memcpy(clipped_ident, ident, idlen);
1290-
clipped_ident[idlen] = '\0';
1291-
values[1] = CStringGetTextDatum(clipped_ident);
1292-
}
1293-
else
1294-
nulls[1] = true;
1295-
1296-
if (parent)
1297-
values[2] = CStringGetTextDatum(parent);
1298-
else
1299-
nulls[2] = true;
1300-
1301-
values[3] = Int32GetDatum(level);
1302-
values[4] = Int64GetDatum(stat.totalspace);
1303-
values[5] = Int64GetDatum(stat.nblocks);
1304-
values[6] = Int64GetDatum(stat.freespace);
1305-
values[7] = Int64GetDatum(stat.freechunks);
1306-
values[8] = Int64GetDatum(stat.totalspace - stat.freespace);
1307-
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
1308-
1309-
for (child = context->firstchild; child != NULL; child = child->nextchild)
1310-
{
1311-
PutMemoryContextsStatsTupleStore(tupstore, tupdesc,
1312-
child, name, level + 1);
1313-
}
1314-
}
1315-
1316-
/*
1317-
* pg_get_backend_memory_contexts
1318-
* SQL SRF showing backend memory context.
1319-
*/
1320-
Datum
1321-
pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
1322-
{
1323-
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1324-
TupleDesc tupdesc;
1325-
Tuplestorestate *tupstore;
1326-
MemoryContext per_query_ctx;
1327-
MemoryContext oldcontext;
1328-
1329-
/* check to see if caller supports us returning a tuplestore */
1330-
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1331-
ereport(ERROR,
1332-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1333-
errmsg("set-valued function called in context that cannot accept a set")));
1334-
if (!(rsinfo->allowedModes & SFRM_Materialize))
1335-
ereport(ERROR,
1336-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1337-
errmsg("materialize mode required, but it is not allowed in this context")));
1338-
1339-
/* Build a tuple descriptor for our result type */
1340-
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1341-
elog(ERROR, "return type must be a row type");
1342-
1343-
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
1344-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
1345-
1346-
tupstore = tuplestore_begin_heap(true, false, work_mem);
1347-
rsinfo->returnMode = SFRM_Materialize;
1348-
rsinfo->setResult = tupstore;
1349-
rsinfo->setDesc = tupdesc;
1350-
1351-
MemoryContextSwitchTo(oldcontext);
1352-
1353-
PutMemoryContextsStatsTupleStore(tupstore, tupdesc,
1354-
TopMemoryContext, NULL, 0);
1355-
1356-
/* clean up and return the tuplestore */
1357-
tuplestore_donestoring(tupstore);
1358-
1359-
return (Datum) 0;
1360-
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy