PostgreSQL Source Code  git master
test_custom_rmgrs.c
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------
2  *
3  * test_custom_rmgrs.c
4  * Code for testing custom WAL resource managers.
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c
11  *
12  * Custom WAL resource manager for records containing a simple textual
13  * payload, no-op redo, and no decoding.
14  *
15  * -------------------------------------------------------------------------
16  */
17 
18 #include "postgres.h"
19 
20 #include "access/xlog.h"
21 #include "access/xlog_internal.h"
22 #include "access/xloginsert.h"
23 #include "fmgr.h"
24 #include "utils/pg_lsn.h"
25 #include "varatt.h"
26 
28 
29 /*
30  * test_custom_rmgrs WAL record message.
31  */
33 {
34  Size message_size; /* size of the message */
35  char message[FLEXIBLE_ARRAY_MEMBER]; /* payload */
37 
38 #define SizeOfTestCustomRmgrsMessage (offsetof(xl_testcustomrmgrs_message, message))
39 #define XLOG_TEST_CUSTOM_RMGRS_MESSAGE 0x00
40 
41 /*
42  * While developing or testing, use RM_EXPERIMENTAL_ID for rmid. For a real
43  * extension, reserve a new resource manager ID to avoid conflicting with
44  * other extensions; see:
45  * https://wiki.postgresql.org/wiki/CustomWALResourceManagers
46  */
47 #define RM_TESTCUSTOMRMGRS_ID RM_EXPERIMENTAL_ID
48 #define TESTCUSTOMRMGRS_NAME "test_custom_rmgrs"
49 
50 /* RMGR API, see xlog_internal.h */
53 const char *testcustomrmgrs_identify(uint8 info);
54 
57  .rm_redo = testcustomrmgrs_redo,
58  .rm_desc = testcustomrmgrs_desc,
59  .rm_identify = testcustomrmgrs_identify
60 };
61 
62 /*
63  * Module load callback
64  */
65 void
66 _PG_init(void)
67 {
68  /*
69  * In order to create our own custom resource manager, we have to be
70  * loaded via shared_preload_libraries. Otherwise, registration will fail.
71  */
73 }
74 
75 /* RMGR API implementation */
76 
77 /*
78  * Redo is just a noop for this module, because we aren't testing recovery of
79  * any real structure.
80  */
81 void
83 {
84  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
85 
87  elog(PANIC, "testcustomrmgrs_redo: unknown op code %u", info);
88 }
89 
90 void
92 {
93  char *rec = XLogRecGetData(record);
94  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
95 
97  {
99 
100  appendStringInfo(buf, "payload (%zu bytes): ", xlrec->message_size);
102  }
103 }
104 
105 const char *
107 {
109  return "TEST_CUSTOM_RMGRS_MESSAGE";
110 
111  return NULL;
112 }
113 
114 /*
115  * SQL function for writing a simple message into WAL with the help of custom
116  * WAL resource manager.
117  */
119 Datum
121 {
122  text *arg = PG_GETARG_TEXT_PP(0);
123  char *payload = VARDATA_ANY(arg);
125  XLogRecPtr lsn;
127 
128  xlrec.message_size = len;
129 
130  XLogBeginInsert();
132  XLogRegisterData((char *) payload, len);
133 
134  /* Let's mark this record as unimportant, just in case. */
136 
138 
139  PG_RETURN_LSN(lsn);
140 }
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:385
unsigned char uint8
Definition: c.h:491
size_t Size
Definition: c.h:592
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:224
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
void * arg
const void size_t len
#define PG_RETURN_LSN(x)
Definition: pg_lsn.h:34
static char * buf
Definition: pg_test_fsync.c:73
uintptr_t Datum
Definition: postgres.h:64
void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr)
Definition: rmgr.c:107
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
const char * rm_name
Definition: c.h:674
char message[FLEXIBLE_ARRAY_MEMBER]
void testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record)
void _PG_init(void)
const char * testcustomrmgrs_identify(uint8 info)
static const RmgrData testcustomrmgrs_rmgr
PG_MODULE_MAGIC
Datum test_custom_rmgrs_insert_wal_record(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(test_custom_rmgrs_insert_wal_record)
#define XLOG_TEST_CUSTOM_RMGRS_MESSAGE
#define SizeOfTestCustomRmgrsMessage
#define RM_TESTCUSTOMRMGRS_ID
#define TESTCUSTOMRMGRS_NAME
void testcustomrmgrs_redo(XLogReaderState *record)
struct xl_testcustomrmgrs_message xl_testcustomrmgrs_message
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
#define XLOG_MARK_UNIMPORTANT
Definition: xlog.h:153
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:364
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
void XLogBeginInsert(void)
Definition: xloginsert.c:149
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLR_INFO_MASK
Definition: xlogrecord.h:62