LCOV - code coverage report
Current view: top level - src/test/modules/test_custom_rmgrs - test_custom_rmgrs.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 81.8 % 33 27
Test Date: 2026-03-12 00:14:58 Functions: 85.7 % 7 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*--------------------------------------------------------------------------
       2              :  *
       3              :  * test_custom_rmgrs.c
       4              :  *      Code for testing custom WAL resource managers.
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, 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              : 
      27            1 : PG_MODULE_MAGIC;
      28              : 
      29              : /*
      30              :  * test_custom_rmgrs WAL record message.
      31              :  */
      32              : typedef struct xl_testcustomrmgrs_message
      33              : {
      34              :     Size        message_size;   /* size of the message */
      35              :     char        message[FLEXIBLE_ARRAY_MEMBER]; /* payload */
      36              : } xl_testcustomrmgrs_message;
      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 */
      51              : void        testcustomrmgrs_redo(XLogReaderState *record);
      52              : void        testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record);
      53              : const char *testcustomrmgrs_identify(uint8 info);
      54              : 
      55              : static const RmgrData testcustomrmgrs_rmgr = {
      56              :     .rm_name = TESTCUSTOMRMGRS_NAME,
      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            1 : _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              :      */
      72            1 :     RegisterCustomRmgr(RM_TESTCUSTOMRMGRS_ID, &testcustomrmgrs_rmgr);
      73            1 : }
      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
      82            0 : testcustomrmgrs_redo(XLogReaderState *record)
      83              : {
      84            0 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      85              : 
      86            0 :     if (info != XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
      87            0 :         elog(PANIC, "testcustomrmgrs_redo: unknown op code %u", info);
      88            0 : }
      89              : 
      90              : void
      91            1 : testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record)
      92              : {
      93            1 :     char       *rec = XLogRecGetData(record);
      94            1 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      95              : 
      96            1 :     if (info == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
      97              :     {
      98            1 :         xl_testcustomrmgrs_message *xlrec = (xl_testcustomrmgrs_message *) rec;
      99              : 
     100            1 :         appendStringInfo(buf, "payload (%zu bytes): ", xlrec->message_size);
     101            1 :         appendBinaryStringInfo(buf, xlrec->message, xlrec->message_size);
     102              :     }
     103            1 : }
     104              : 
     105              : const char *
     106            1 : testcustomrmgrs_identify(uint8 info)
     107              : {
     108            1 :     if ((info & ~XLR_INFO_MASK) == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
     109            1 :         return "TEST_CUSTOM_RMGRS_MESSAGE";
     110              : 
     111            0 :     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              :  */
     118            2 : PG_FUNCTION_INFO_V1(test_custom_rmgrs_insert_wal_record);
     119              : Datum
     120            1 : test_custom_rmgrs_insert_wal_record(PG_FUNCTION_ARGS)
     121              : {
     122            1 :     text       *arg = PG_GETARG_TEXT_PP(0);
     123            1 :     char       *payload = VARDATA_ANY(arg);
     124            1 :     Size        len = VARSIZE_ANY_EXHDR(arg);
     125              :     XLogRecPtr  lsn;
     126              :     xl_testcustomrmgrs_message xlrec;
     127              : 
     128            1 :     xlrec.message_size = len;
     129              : 
     130            1 :     XLogBeginInsert();
     131            1 :     XLogRegisterData(&xlrec, SizeOfTestCustomRmgrsMessage);
     132            1 :     XLogRegisterData(payload, len);
     133              : 
     134              :     /* Let's mark this record as unimportant, just in case. */
     135            1 :     XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT);
     136              : 
     137            1 :     lsn = XLogInsert(RM_TESTCUSTOMRMGRS_ID, XLOG_TEST_CUSTOM_RMGRS_MESSAGE);
     138              : 
     139            1 :     PG_RETURN_LSN(lsn);
     140              : }
        

Generated by: LCOV version 2.0-1