PostgreSQL Source Code git master
test_custom_fixed_stats.c
Go to the documentation of this file.
1/*--------------------------------------------------------------------------
2 *
3 * test_custom_fixed_stats.c
4 * Test module for fixed-sized custom pgstats
5 *
6 * Copyright (c) 2025, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/test/modules/test_custom_stats/test_custom_fixed_stats.c
10 *
11 * -------------------------------------------------------------------------
12 */
13
14#include "postgres.h"
15
16#include "access/htup_details.h"
17#include "funcapi.h"
18#include "pgstat.h"
19#include "utils/builtins.h"
21
23 .name = "test_custom_fixed_stats",
24 .version = PG_VERSION
25);
26
27/* Fixed-amount custom statistics entry */
29{
30 PgStat_Counter numcalls; /* # of times update function called */
33
35{
36 LWLock lock; /* protects counters */
37 uint32 changecount; /* for atomic reads */
38 PgStat_StatCustomFixedEntry stats; /* current counters */
41
42/* Callbacks for fixed-amount statistics */
43static void test_custom_stats_fixed_init_shmem_cb(void *stats);
46
48 .name = "test_custom_fixed_stats",
49 .fixed_amount = true, /* exactly one entry */
50 .write_to_file = true, /* persist to stats file */
51
52 .shared_size = sizeof(PgStat_StatCustomFixedEntry),
53 .shared_data_off = offsetof(PgStatShared_CustomFixedEntry, stats),
54 .shared_data_len = sizeof(((PgStatShared_CustomFixedEntry *) 0)->stats),
55
59};
60
61/*
62 * Kind ID for test_custom_fixed_stats.
63 */
64#define PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS 26
65
66/*--------------------------------------------------------------------------
67 * Module initialization
68 *--------------------------------------------------------------------------
69 */
70
71void
73{
74 /* Must be loaded via shared_preload_libraries */
76 return;
77
78 /* Register custom statistics kind */
80}
81
82/*
83 * test_custom_stats_fixed_init_shmem_cb
84 * Initialize shared memory structure
85 */
86static void
88{
91
92 LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
93}
94
95/*
96 * test_custom_stats_fixed_reset_all_cb
97 * Reset the fixed-sized stats
98 */
99static void
101{
102 PgStatShared_CustomFixedEntry *stats_shmem =
104
105 /* see explanation above PgStatShared_Archiver for the reset protocol */
106 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
108 &stats_shmem->stats,
109 sizeof(stats_shmem->stats),
110 &stats_shmem->changecount);
111 stats_shmem->stats.stat_reset_timestamp = ts;
112 LWLockRelease(&stats_shmem->lock);
113}
114
115/*
116 * test_custom_stats_fixed_snapshot_cb
117 * Copy current stats to snapshot area
118 */
119static void
121{
122 PgStatShared_CustomFixedEntry *stats_shmem =
124 PgStat_StatCustomFixedEntry *stat_snap =
126 PgStat_StatCustomFixedEntry *reset_offset = &stats_shmem->reset_offset;
128
130 &stats_shmem->stats,
131 sizeof(stats_shmem->stats),
132 &stats_shmem->changecount);
133
134 LWLockAcquire(&stats_shmem->lock, LW_SHARED);
135 memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
136 LWLockRelease(&stats_shmem->lock);
137
138 /* Apply reset offsets */
139#define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
140 FIXED_COMP(numcalls);
141#undef FIXED_COMP
142}
143
144/*--------------------------------------------------------------------------
145 * SQL-callable functions
146 *--------------------------------------------------------------------------
147 */
148
149/*
150 * test_custom_stats_fixed_update
151 * Increment call counter
152 */
154Datum
156{
158
160
161 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
162
164 stats_shmem->stats.numcalls++;
166
167 LWLockRelease(&stats_shmem->lock);
168
170}
171
172/*
173 * test_custom_stats_fixed_reset
174 * Reset statistics by calling pgstat system
175 */
177Datum
179{
181
183}
184
185/*
186 * test_custom_stats_fixed_report
187 * Return current counter values
188 */
190Datum
192{
193 TupleDesc tupdesc;
194 Datum values[2] = {0};
195 bool nulls[2] = {false};
197
198 /* Take snapshot (applies reset offsets) */
201
202 /* Build return tuple */
203 tupdesc = CreateTemplateTupleDesc(2);
204 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numcalls",
205 INT8OID, -1, 0);
206 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "stats_reset",
207 TIMESTAMPTZOID, -1, 0);
208 BlessTupleDesc(tupdesc);
209
210 values[0] = Int64GetDatum(stats->numcalls);
211
212 /* Handle uninitialized timestamp (no reset yet) */
213 if (stats->stat_reset_timestamp == 0)
214 {
215 nulls[1] = true;
216 }
217 else
218 {
220 }
221
222 /* Return as tuple */
224}
int16 AttrNumber
Definition: attnum.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:153
uint32_t uint32
Definition: c.h:552
int64 TimestampTz
Definition: timestamp.h:39
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2260
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:698
@ LW_SHARED
Definition: lwlock.h:113
@ LW_EXCLUSIVE
Definition: lwlock.h:112
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1786
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:1060
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition: pgstat.c:876
void pgstat_register_kind(PgStat_Kind kind, const PgStat_KindInfo *kind_info)
Definition: pgstat.c:1463
int64 PgStat_Counter
Definition: pgstat.h:67
static void * pgstat_get_custom_snapshot_data(PgStat_Kind kind)
static void * pgstat_get_custom_shmem_data(PgStat_Kind kind)
static void pgstat_end_changecount_write(uint32 *cc)
static void pgstat_begin_changecount_write(uint32 *cc)
static void pgstat_copy_changecounted_stats(void *dst, void *src, size_t len, uint32 *cc)
static Datum Int64GetDatum(int64 X)
Definition: postgres.h:403
uint64_t Datum
Definition: postgres.h:70
void reset(void)
Definition: sql-declare.c:600
Definition: lwlock.h:42
PgStat_StatCustomFixedEntry reset_offset
PgStat_StatCustomFixedEntry stats
const char *const name
void _PG_init(void)
#define PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS
Datum test_custom_stats_fixed_reset(PG_FUNCTION_ARGS)
static const PgStat_KindInfo custom_stats
#define FIXED_COMP(fld)
static void test_custom_stats_fixed_init_shmem_cb(void *stats)
static void test_custom_stats_fixed_snapshot_cb(void)
static void test_custom_stats_fixed_reset_all_cb(TimestampTz ts)
struct PgStatShared_CustomFixedEntry PgStatShared_CustomFixedEntry
PG_FUNCTION_INFO_V1(test_custom_stats_fixed_update)
Datum test_custom_stats_fixed_update(PG_FUNCTION_ARGS)
Datum test_custom_stats_fixed_report(PG_FUNCTION_ARGS)
struct PgStat_StatCustomFixedEntry PgStat_StatCustomFixedEntry
PG_MODULE_MAGIC_EXT(.name="test_custom_fixed_stats",.version=PG_VERSION)
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:182
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:842
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
const char * name