LCOV - code coverage report
Current view: top level - src/bin/pg_waldump - gindesc.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 40 124 32.3 %
Date: 2024-12-02 20:15:07 Functions: 2 3 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * gindesc.c
       4             :  *    rmgr descriptor routines for access/transam/gin/ginxlog.c
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/access/rmgrdesc/gindesc.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include "access/ginxlog.h"
      18             : #include "lib/stringinfo.h"
      19             : 
      20             : static void
      21           0 : desc_recompress_leaf(StringInfo buf, ginxlogRecompressDataLeaf *insertData)
      22             : {
      23             :     int         i;
      24           0 :     char       *walbuf = ((char *) insertData) + sizeof(ginxlogRecompressDataLeaf);
      25             : 
      26           0 :     appendStringInfo(buf, " %d segments:", (int) insertData->nactions);
      27             : 
      28           0 :     for (i = 0; i < insertData->nactions; i++)
      29             :     {
      30           0 :         uint8       a_segno = *((uint8 *) (walbuf++));
      31           0 :         uint8       a_action = *((uint8 *) (walbuf++));
      32           0 :         uint16      nitems = 0;
      33           0 :         int         newsegsize = 0;
      34             : 
      35           0 :         if (a_action == GIN_SEGMENT_INSERT ||
      36             :             a_action == GIN_SEGMENT_REPLACE)
      37             :         {
      38           0 :             newsegsize = SizeOfGinPostingList((GinPostingList *) walbuf);
      39           0 :             walbuf += SHORTALIGN(newsegsize);
      40             :         }
      41             : 
      42           0 :         if (a_action == GIN_SEGMENT_ADDITEMS)
      43             :         {
      44           0 :             memcpy(&nitems, walbuf, sizeof(uint16));
      45           0 :             walbuf += sizeof(uint16);
      46           0 :             walbuf += nitems * sizeof(ItemPointerData);
      47             :         }
      48             : 
      49           0 :         switch (a_action)
      50             :         {
      51           0 :             case GIN_SEGMENT_ADDITEMS:
      52           0 :                 appendStringInfo(buf, " %d (add %d items)", a_segno, nitems);
      53           0 :                 break;
      54           0 :             case GIN_SEGMENT_DELETE:
      55           0 :                 appendStringInfo(buf, " %d (delete)", a_segno);
      56           0 :                 break;
      57           0 :             case GIN_SEGMENT_INSERT:
      58           0 :                 appendStringInfo(buf, " %d (insert)", a_segno);
      59           0 :                 break;
      60           0 :             case GIN_SEGMENT_REPLACE:
      61           0 :                 appendStringInfo(buf, " %d (replace)", a_segno);
      62           0 :                 break;
      63           0 :             default:
      64           0 :                 appendStringInfo(buf, " %d unknown action %d ???", a_segno, a_action);
      65             :                 /* cannot decode unrecognized actions further */
      66           0 :                 return;
      67             :         }
      68             :     }
      69             : }
      70             : 
      71             : void
      72        6192 : gin_desc(StringInfo buf, XLogReaderState *record)
      73             : {
      74        6192 :     char       *rec = XLogRecGetData(record);
      75        6192 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      76             : 
      77        6192 :     switch (info)
      78             :     {
      79           0 :         case XLOG_GIN_CREATE_PTREE:
      80             :             /* no further information */
      81           0 :             break;
      82          72 :         case XLOG_GIN_INSERT:
      83             :             {
      84          72 :                 ginxlogInsert *xlrec = (ginxlogInsert *) rec;
      85             : 
      86         144 :                 appendStringInfo(buf, "isdata: %c isleaf: %c",
      87          72 :                                  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
      88          72 :                                  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
      89          72 :                 if (!(xlrec->flags & GIN_INSERT_ISLEAF))
      90             :                 {
      91           0 :                     char       *payload = rec + sizeof(ginxlogInsert);
      92             :                     BlockNumber leftChildBlkno;
      93             :                     BlockNumber rightChildBlkno;
      94             : 
      95           0 :                     leftChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
      96           0 :                     payload += sizeof(BlockIdData);
      97           0 :                     rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
      98           0 :                     payload += sizeof(BlockNumber);
      99           0 :                     appendStringInfo(buf, " children: %u/%u",
     100             :                                      leftChildBlkno, rightChildBlkno);
     101             :                 }
     102          72 :                 if (XLogRecHasBlockImage(record, 0))
     103             :                 {
     104           0 :                     if (XLogRecBlockImageApply(record, 0))
     105           0 :                         appendStringInfoString(buf, " (full page image)");
     106             :                     else
     107           0 :                         appendStringInfoString(buf, " (full page image, for WAL verification)");
     108             :                 }
     109             :                 else
     110             :                 {
     111          72 :                     char       *payload = XLogRecGetBlockData(record, 0, NULL);
     112             : 
     113          72 :                     if (!(xlrec->flags & GIN_INSERT_ISDATA))
     114          72 :                         appendStringInfo(buf, " isdelete: %c",
     115          72 :                                          (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
     116           0 :                     else if (xlrec->flags & GIN_INSERT_ISLEAF)
     117           0 :                         desc_recompress_leaf(buf, (ginxlogRecompressDataLeaf *) payload);
     118             :                     else
     119             :                     {
     120           0 :                         ginxlogInsertDataInternal *insertData =
     121             :                             (ginxlogInsertDataInternal *) payload;
     122             : 
     123           0 :                         appendStringInfo(buf, " pitem: %u-%u/%u",
     124           0 :                                          PostingItemGetBlockNumber(&insertData->newitem),
     125           0 :                                          ItemPointerGetBlockNumber(&insertData->newitem.key),
     126           0 :                                          ItemPointerGetOffsetNumber(&insertData->newitem.key));
     127             :                     }
     128             :                 }
     129             :             }
     130          72 :             break;
     131           0 :         case XLOG_GIN_SPLIT:
     132             :             {
     133           0 :                 ginxlogSplit *xlrec = (ginxlogSplit *) rec;
     134             : 
     135           0 :                 appendStringInfo(buf, "isrootsplit: %c",
     136           0 :                                  (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
     137           0 :                 appendStringInfo(buf, " isdata: %c isleaf: %c",
     138           0 :                                  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
     139           0 :                                  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
     140             :             }
     141           0 :             break;
     142           0 :         case XLOG_GIN_VACUUM_PAGE:
     143             :             /* no further information */
     144           0 :             break;
     145           0 :         case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
     146             :             {
     147           0 :                 if (XLogRecHasBlockImage(record, 0))
     148             :                 {
     149           0 :                     if (XLogRecBlockImageApply(record, 0))
     150           0 :                         appendStringInfoString(buf, " (full page image)");
     151             :                     else
     152           0 :                         appendStringInfoString(buf, " (full page image, for WAL verification)");
     153             :                 }
     154             :                 else
     155             :                 {
     156             :                     ginxlogVacuumDataLeafPage *xlrec =
     157           0 :                         (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
     158             : 
     159           0 :                     desc_recompress_leaf(buf, &xlrec->data);
     160             :                 }
     161             :             }
     162           0 :             break;
     163           0 :         case XLOG_GIN_DELETE_PAGE:
     164             :             /* no further information */
     165           0 :             break;
     166        6012 :         case XLOG_GIN_UPDATE_META_PAGE:
     167             :             /* no further information */
     168        6012 :             break;
     169          96 :         case XLOG_GIN_INSERT_LISTPAGE:
     170             :             /* no further information */
     171          96 :             break;
     172          12 :         case XLOG_GIN_DELETE_LISTPAGE:
     173          12 :             appendStringInfo(buf, "ndeleted: %d",
     174             :                              ((ginxlogDeleteListPages *) rec)->ndeleted);
     175          12 :             break;
     176             :     }
     177        6192 : }
     178             : 
     179             : const char *
     180        6200 : gin_identify(uint8 info)
     181             : {
     182        6200 :     const char *id = NULL;
     183             : 
     184        6200 :     switch (info & ~XLR_INFO_MASK)
     185             :     {
     186           0 :         case XLOG_GIN_CREATE_PTREE:
     187           0 :             id = "CREATE_PTREE";
     188           0 :             break;
     189          74 :         case XLOG_GIN_INSERT:
     190          74 :             id = "INSERT";
     191          74 :             break;
     192           0 :         case XLOG_GIN_SPLIT:
     193           0 :             id = "SPLIT";
     194           0 :             break;
     195           0 :         case XLOG_GIN_VACUUM_PAGE:
     196           0 :             id = "VACUUM_PAGE";
     197           0 :             break;
     198           0 :         case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
     199           0 :             id = "VACUUM_DATA_LEAF_PAGE";
     200           0 :             break;
     201           0 :         case XLOG_GIN_DELETE_PAGE:
     202           0 :             id = "DELETE_PAGE";
     203           0 :             break;
     204        6014 :         case XLOG_GIN_UPDATE_META_PAGE:
     205        6014 :             id = "UPDATE_META_PAGE";
     206        6014 :             break;
     207          98 :         case XLOG_GIN_INSERT_LISTPAGE:
     208          98 :             id = "INSERT_LISTPAGE";
     209          98 :             break;
     210          14 :         case XLOG_GIN_DELETE_LISTPAGE:
     211          14 :             id = "DELETE_LISTPAGE";
     212          14 :             break;
     213             :     }
     214             : 
     215        6200 :     return id;
     216             : }

Generated by: LCOV version 1.14