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 20devel Lines: 81.8 % 33 27
Test Date: 2026-07-03 19:57:34 Functions: 85.7 % 7 6
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 25.0 % 8 2

             Branch data     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