LCOV - code coverage report
Current view: top level - src/backend/access/rmgrdesc - gindesc.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 0.0 % 130 0
Test Date: 2026-03-03 07:15:00 Functions: 0.0 % 3 0
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-2026, 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:", 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            0 : gin_desc(StringInfo buf, XLogReaderState *record)
      73              : {
      74            0 :     char       *rec = XLogRecGetData(record);
      75            0 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      76              : 
      77            0 :     switch (info)
      78              :     {
      79            0 :         case XLOG_GIN_CREATE_PTREE:
      80              :             /* no further information */
      81            0 :             break;
      82            0 :         case XLOG_GIN_INSERT:
      83              :             {
      84            0 :                 ginxlogInsert *xlrec = (ginxlogInsert *) rec;
      85              : 
      86            0 :                 appendStringInfo(buf, "isdata: %c isleaf: %c",
      87            0 :                                  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
      88            0 :                                  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
      89            0 :                 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            0 :                 if (!XLogRecHasBlockImage(record, 0))
     103              :                 {
     104            0 :                     char       *payload = XLogRecGetBlockData(record, 0, NULL);
     105              : 
     106            0 :                     if (!(xlrec->flags & GIN_INSERT_ISDATA))
     107            0 :                         appendStringInfo(buf, " isdelete: %c",
     108            0 :                                          (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
     109            0 :                     else if (xlrec->flags & GIN_INSERT_ISLEAF)
     110            0 :                         desc_recompress_leaf(buf, (ginxlogRecompressDataLeaf *) payload);
     111              :                     else
     112              :                     {
     113            0 :                         ginxlogInsertDataInternal *insertData =
     114              :                             (ginxlogInsertDataInternal *) payload;
     115              : 
     116            0 :                         appendStringInfo(buf, " pitem: %u-%u/%u",
     117            0 :                                          PostingItemGetBlockNumber(&insertData->newitem),
     118            0 :                                          ItemPointerGetBlockNumber(&insertData->newitem.key),
     119            0 :                                          ItemPointerGetOffsetNumber(&insertData->newitem.key));
     120              :                     }
     121              :                 }
     122              :             }
     123            0 :             break;
     124            0 :         case XLOG_GIN_SPLIT:
     125              :             {
     126            0 :                 ginxlogSplit *xlrec = (ginxlogSplit *) rec;
     127              : 
     128            0 :                 appendStringInfo(buf, "isrootsplit: %c",
     129            0 :                                  (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
     130            0 :                 appendStringInfo(buf, " isdata: %c isleaf: %c",
     131            0 :                                  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
     132            0 :                                  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
     133            0 :                 if (xlrec->leftChildBlkno != InvalidBlockNumber)
     134            0 :                     appendStringInfo(buf, " children: %u/%u",
     135              :                                      xlrec->leftChildBlkno, xlrec->rightChildBlkno);
     136              :             }
     137            0 :             break;
     138            0 :         case XLOG_GIN_VACUUM_PAGE:
     139              :             /* no further information */
     140            0 :             break;
     141            0 :         case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
     142              :             {
     143            0 :                 if (!XLogRecHasBlockImage(record, 0))
     144              :                 {
     145              :                     ginxlogVacuumDataLeafPage *xlrec =
     146            0 :                         (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
     147              : 
     148            0 :                     desc_recompress_leaf(buf, &xlrec->data);
     149              :                 }
     150              :             }
     151            0 :             break;
     152            0 :         case XLOG_GIN_DELETE_PAGE:
     153              :             /* no further information */
     154            0 :             break;
     155            0 :         case XLOG_GIN_UPDATE_META_PAGE:
     156              :             {
     157            0 :                 ginxlogUpdateMeta *xlrec = (ginxlogUpdateMeta *) rec;
     158              : 
     159            0 :                 appendStringInfo(buf, "ntuples: %d", xlrec->ntuples);
     160            0 :                 if (xlrec->prevTail != InvalidBlockNumber)
     161            0 :                     appendStringInfo(buf, " prevTail: %u",
     162              :                                      xlrec->prevTail);
     163            0 :                 if (xlrec->newRightlink != InvalidBlockNumber)
     164            0 :                     appendStringInfo(buf, " newRightlink: %u",
     165              :                                      xlrec->newRightlink);
     166              :             }
     167            0 :             break;
     168            0 :         case XLOG_GIN_INSERT_LISTPAGE:
     169              :             {
     170            0 :                 ginxlogInsertListPage *xlrec = (ginxlogInsertListPage *) rec;
     171              : 
     172            0 :                 appendStringInfo(buf, "ntuples: %d", xlrec->ntuples);
     173            0 :                 if (xlrec->rightlink != InvalidBlockNumber)
     174            0 :                     appendStringInfo(buf, " rightlink: %u",
     175              :                                      xlrec->rightlink);
     176              :             }
     177            0 :             break;
     178            0 :         case XLOG_GIN_DELETE_LISTPAGE:
     179            0 :             appendStringInfo(buf, "ndeleted: %d",
     180              :                              ((ginxlogDeleteListPages *) rec)->ndeleted);
     181            0 :             break;
     182              :     }
     183            0 : }
     184              : 
     185              : const char *
     186            0 : gin_identify(uint8 info)
     187              : {
     188            0 :     const char *id = NULL;
     189              : 
     190            0 :     switch (info & ~XLR_INFO_MASK)
     191              :     {
     192            0 :         case XLOG_GIN_CREATE_PTREE:
     193            0 :             id = "CREATE_PTREE";
     194            0 :             break;
     195            0 :         case XLOG_GIN_INSERT:
     196            0 :             id = "INSERT";
     197            0 :             break;
     198            0 :         case XLOG_GIN_SPLIT:
     199            0 :             id = "SPLIT";
     200            0 :             break;
     201            0 :         case XLOG_GIN_VACUUM_PAGE:
     202            0 :             id = "VACUUM_PAGE";
     203            0 :             break;
     204            0 :         case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
     205            0 :             id = "VACUUM_DATA_LEAF_PAGE";
     206            0 :             break;
     207            0 :         case XLOG_GIN_DELETE_PAGE:
     208            0 :             id = "DELETE_PAGE";
     209            0 :             break;
     210            0 :         case XLOG_GIN_UPDATE_META_PAGE:
     211            0 :             id = "UPDATE_META_PAGE";
     212            0 :             break;
     213            0 :         case XLOG_GIN_INSERT_LISTPAGE:
     214            0 :             id = "INSERT_LISTPAGE";
     215            0 :             break;
     216            0 :         case XLOG_GIN_DELETE_LISTPAGE:
     217            0 :             id = "DELETE_LISTPAGE";
     218            0 :             break;
     219              :     }
     220              : 
     221            0 :     return id;
     222              : }
        

Generated by: LCOV version 2.0-1