Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cf25b45

Browse files
author
Commitfest Bot
committed
[CF 5696] v5 - Add pg_get_injection_points() for information of injection points
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5696 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/aDVmZ-U83JYytz7a@paquier.xyz Author(s): Michael Paquier
2 parents b006bcd + 330e996 commit cf25b45

File tree

10 files changed

+204
-0
lines changed

10 files changed

+204
-0
lines changed

doc/src/sgml/func.sgml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28496,6 +28496,54 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres}
2849628496

2849728497
</sect2>
2849828498

28499+
<sect2 id="functions-info-injection-points">
28500+
<title>Injection Points Information Functions</title>
28501+
28502+
<para>
28503+
The functions shown in <xref linkend="functions-info-injection-points"/>
28504+
print information about the injection points.
28505+
See <xref linkend="xfunc-addin-injection-points" />.
28506+
</para>
28507+
28508+
<table id="functions-injection-points">
28509+
<title>WAL Summarization Information Functions</title>
28510+
<tgroup cols="1">
28511+
<thead>
28512+
<row>
28513+
<entry role="func_table_entry"><para role="func_signature">
28514+
Function
28515+
</para>
28516+
<para>
28517+
Description
28518+
</para></entry>
28519+
</row>
28520+
</thead>
28521+
28522+
<tbody>
28523+
<row>
28524+
<entry role="func_table_entry"><para role="func_signature">
28525+
<indexterm>
28526+
<primary>pg_get_injection_points</primary>
28527+
</indexterm>
28528+
<function>pg_get_injection_points</function> ()
28529+
<returnvalue>setof record</returnvalue>
28530+
( <parameter>name</parameter> <type>text</type>,
28531+
<parameter>library</parameter> <type>text</type>,
28532+
<parameter>function</parameter> <type>text</type> )
28533+
</para>
28534+
<para>
28535+
Returns information about the injection points currently attached
28536+
to the cluster, if the server was built with the configure option
28537+
<option>--enable-injection-points</option>; otherwise throws
28538+
an error.
28539+
</para></entry>
28540+
</row>
28541+
</tbody>
28542+
28543+
</tgroup>
28544+
</table>
28545+
</sect2>
28546+
2849928547
</sect1>
2850028548

2850128549
<sect1 id="functions-admin">

src/backend/utils/misc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ OBJS = \
2222
guc_tables.o \
2323
help_config.o \
2424
injection_point.o \
25+
injection_point_funcs.o \
2526
pg_config.o \
2627
pg_controldata.o \
2728
pg_rusage.o \

src/backend/utils/misc/injection_point.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,3 +584,49 @@ IsInjectionPointAttached(const char *name)
584584
return false; /* silence compiler */
585585
#endif
586586
}
587+
588+
/*
589+
* Retrieve a list of all the injection points currently attached.
590+
*
591+
* This list is palloc'd in the current memory context.
592+
*/
593+
List *
594+
InjectionPointList(void)
595+
{
596+
#ifdef USE_INJECTION_POINTS
597+
List *inj_points = NIL;
598+
uint32 max_inuse;
599+
600+
LWLockAcquire(InjectionPointLock, LW_SHARED);
601+
602+
max_inuse = pg_atomic_read_u32(&ActiveInjectionPoints->max_inuse);
603+
604+
for (uint32 idx = 0; idx < max_inuse; idx++)
605+
{
606+
InjectionPointEntry *entry;
607+
InjectionPointData *inj_point;
608+
uint64 generation;
609+
610+
entry = &ActiveInjectionPoints->entries[idx];
611+
generation = pg_atomic_read_u64(&entry->generation);
612+
613+
/* skip free slots */
614+
if (generation % 2 == 0)
615+
continue;
616+
617+
inj_point = (InjectionPointData *) palloc0(sizeof(InjectionPointData));
618+
inj_point->name = pstrdup(entry->name);
619+
inj_point->library = pstrdup(entry->library);
620+
inj_point->function = pstrdup(entry->function);
621+
inj_points = lappend(inj_points, inj_point);
622+
}
623+
624+
LWLockRelease(InjectionPointLock);
625+
626+
return inj_points;
627+
628+
#else
629+
elog(ERROR, "Injection points are not supported by this build");
630+
return NIL; /* keep compiler quiet */
631+
#endif
632+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* injection_point_funcs.c
4+
*
5+
* SQL commands and SQL-accessible functions related to injection points.
6+
*
7+
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
*
11+
* IDENTIFICATION
12+
* src/backend/utils/misc/injection_point_funcs.c
13+
*
14+
*-------------------------------------------------------------------------
15+
*/
16+
#include "postgres.h"
17+
18+
#include "funcapi.h"
19+
#include "utils/builtins.h"
20+
#include "utils/injection_point.h"
21+
22+
/*
23+
* pg_get_injection_points
24+
*
25+
* Return a table of all the injection points currently attached to the
26+
* system.
27+
*/
28+
Datum
29+
pg_get_injection_points(PG_FUNCTION_ARGS)
30+
{
31+
#define NUM_PG_GET_INJECTION_POINTS 3
32+
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
33+
List *inj_points;
34+
ListCell *lc;
35+
36+
/* Build a tuplestore to return our results in */
37+
InitMaterializedSRF(fcinfo, 0);
38+
39+
inj_points = InjectionPointList();
40+
41+
foreach(lc, inj_points)
42+
{
43+
Datum values[NUM_PG_GET_INJECTION_POINTS];
44+
bool nulls[NUM_PG_GET_INJECTION_POINTS];
45+
InjectionPointData *inj_point = lfirst(lc);
46+
47+
memset(values, 0, sizeof(values));
48+
memset(nulls, 0, sizeof(nulls));
49+
50+
values[0] = PointerGetDatum(cstring_to_text(inj_point->name));
51+
values[1] = PointerGetDatum(cstring_to_text(inj_point->library));
52+
values[2] = PointerGetDatum(cstring_to_text(inj_point->function));
53+
54+
/* shove row into tuplestore */
55+
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
56+
}
57+
58+
return (Datum) 0;
59+
#undef NUM_PG_GET_INJECTION_POINTS
60+
}

src/backend/utils/misc/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ backend_sources += files(
77
'guc_tables.c',
88
'help_config.c',
99
'injection_point.c',
10+
'injection_point_funcs.c',
1011
'pg_config.c',
1112
'pg_controldata.c',
1213
'pg_rusage.c',

src/include/catalog/pg_proc.dat

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12556,4 +12556,12 @@
1255612556
proargnames => '{pid,io_id,io_generation,state,operation,off,length,target,handle_data_len,raw_result,result,target_desc,f_sync,f_localmem,f_buffered}',
1255712557
prosrc => 'pg_get_aios' },
1255812558

12559+
# Injection point functions
12560+
{ oid => '8490', descr => 'information about injection points attached',
12561+
proname => 'pg_get_injection_points', prorows => '3', proretset => 't',
12562+
provolatile => 'v', proparallel => 'r', prorettype => 'record',
12563+
proargtypes => '', proallargtypes => '{text,text,text}',
12564+
proargmodes => '{o,o,o}', proargnames => '{name,library,function}',
12565+
prosrc => 'pg_get_injection_points' },
12566+
1255912567
]

src/include/utils/injection_point.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111
#ifndef INJECTION_POINT_H
1212
#define INJECTION_POINT_H
1313

14+
#include "nodes/pg_list.h"
15+
16+
/*
17+
* Injection point data, used when retrieving a list of all the attached
18+
* injection points.
19+
*/
20+
typedef struct InjectionPointData
21+
{
22+
const char *name;
23+
const char *library;
24+
const char *function;
25+
} InjectionPointData;
26+
1427
/*
1528
* Injection points require --enable-injection-points.
1629
*/
@@ -47,6 +60,9 @@ extern void InjectionPointCached(const char *name, void *arg);
4760
extern bool IsInjectionPointAttached(const char *name);
4861
extern bool InjectionPointDetach(const char *name);
4962

63+
/* Get the current set of injection points attached */
64+
extern List *InjectionPointList(void);
65+
5066
#ifdef EXEC_BACKEND
5167
extern PGDLLIMPORT struct InjectionPointsCtl *ActiveInjectionPoints;
5268
#endif

src/test/modules/injection_points/expected/injection_points.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ SELECT injection_points_attach('TestInjectionLog2', 'notice');
3939

4040
(1 row)
4141

42+
SELECT name, library, function FROM pg_get_injection_points()
43+
ORDER BY name COLLATE "C";
44+
name | library | function
45+
--------------------+------------------+------------------
46+
TestInjectionError | injection_points | injection_error
47+
TestInjectionLog | injection_points | injection_notice
48+
TestInjectionLog2 | injection_points | injection_notice
49+
(3 rows)
50+
4251
SELECT injection_points_run('TestInjectionBooh'); -- nothing
4352
injection_points_run
4453
----------------------
@@ -298,5 +307,12 @@ SELECT injection_points_detach('TestConditionLocal1');
298307

299308
(1 row)
300309

310+
-- No points should be left around.
311+
SELECT name, library, function FROM pg_get_injection_points()
312+
ORDER BY name COLLATE "C";
313+
name | library | function
314+
------+---------+----------
315+
(0 rows)
316+
301317
DROP EXTENSION injection_points;
302318
DROP FUNCTION wait_pid;

src/test/modules/injection_points/sql/injection_points.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ SELECT injection_points_attach('TestInjectionError', 'error');
1818
SELECT injection_points_attach('TestInjectionLog', 'notice');
1919
SELECT injection_points_attach('TestInjectionLog2', 'notice');
2020

21+
SELECT name, library, function FROM pg_get_injection_points()
22+
ORDER BY name COLLATE "C";
23+
2124
SELECT injection_points_run('TestInjectionBooh'); -- nothing
2225
SELECT injection_points_run('TestInjectionLog2'); -- notice
2326
SELECT injection_points_run('TestInjectionLog2', NULL); -- notice
@@ -85,5 +88,9 @@ SELECT injection_points_detach('TestConditionError');
8588
SELECT injection_points_attach('TestConditionLocal1', 'error');
8689
SELECT injection_points_detach('TestConditionLocal1');
8790

91+
-- No points should be left around.
92+
SELECT name, library, function FROM pg_get_injection_points()
93+
ORDER BY name COLLATE "C";
94+
8895
DROP EXTENSION injection_points;
8996
DROP FUNCTION wait_pid;

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,7 @@ InjectionPointCacheEntry
12831283
InjectionPointCallback
12841284
InjectionPointCondition
12851285
InjectionPointConditionType
1286+
InjectionPointData
12861287
InjectionPointEntry
12871288
InjectionPointsCtl
12881289
InjectionPointSharedState

0 commit comments

Comments
 (0)