LCOV - code coverage report
Current view: top level - src/test/modules/test_custom_rmgrs - test_custom_rmgrs.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 27 33 81.8 %
Date: 2024-12-02 20:15:07 Functions: 6 7 85.7 %
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-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             : 
      27           2 : 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           2 : _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           2 :     RegisterCustomRmgr(RM_TESTCUSTOMRMGRS_ID, &testcustomrmgrs_rmgr);
      73           2 : }
      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           2 : testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record)
      92             : {
      93           2 :     char       *rec = XLogRecGetData(record);
      94           2 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      95             : 
      96           2 :     if (info == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
      97             :     {
      98           2 :         xl_testcustomrmgrs_message *xlrec = (xl_testcustomrmgrs_message *) rec;
      99             : 
     100           2 :         appendStringInfo(buf, "payload (%zu bytes): ", xlrec->message_size);
     101           2 :         appendBinaryStringInfo(buf, xlrec->message, xlrec->message_size);
     102             :     }
     103           2 : }
     104             : 
     105             : const char *
     106           2 : testcustomrmgrs_identify(uint8 info)
     107             : {
     108           2 :     if ((info & ~XLR_INFO_MASK) == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
     109           2 :         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           4 : PG_FUNCTION_INFO_V1(test_custom_rmgrs_insert_wal_record);
     119             : Datum
     120           2 : test_custom_rmgrs_insert_wal_record(PG_FUNCTION_ARGS)
     121             : {
     122           2 :     text       *arg = PG_GETARG_TEXT_PP(0);
     123           2 :     char       *payload = VARDATA_ANY(arg);
     124           2 :     Size        len = VARSIZE_ANY_EXHDR(arg);
     125             :     XLogRecPtr  lsn;
     126             :     xl_testcustomrmgrs_message xlrec;
     127             : 
     128           2 :     xlrec.message_size = len;
     129             : 
     130           2 :     XLogBeginInsert();
     131           2 :     XLogRegisterData((char *) &xlrec, SizeOfTestCustomRmgrsMessage);
     132           2 :     XLogRegisterData((char *) payload, len);
     133             : 
     134             :     /* Let's mark this record as unimportant, just in case. */
     135           2 :     XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT);
     136             : 
     137           2 :     lsn = XLogInsert(RM_TESTCUSTOMRMGRS_ID, XLOG_TEST_CUSTOM_RMGRS_MESSAGE);
     138             : 
     139           2 :     PG_RETURN_LSN(lsn);
     140             : }

Generated by: LCOV version 1.14