LCOV - differential code coverage report
Current view: top level - src/backend/access/rmgrdesc - heapdesc.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 59.0 % 217 128 38 20 20 11 17 35 41 35 56 62 5 11
Current Date: 2023-04-08 15:15:32 Functions: 83.3 % 6 5 1 5 1 5
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * heapdesc.c
       4                 :  *    rmgr descriptor routines for access/heap/heapam.c
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  *
      10                 :  * IDENTIFICATION
      11                 :  *    src/backend/access/rmgrdesc/heapdesc.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : #include "postgres.h"
      16                 : 
      17                 : #include "access/heapam_xlog.h"
      18                 : #include "access/rmgrdesc_utils.h"
      19                 : 
      20                 : static void
      21 GIC          41 : out_infobits(StringInfo buf, uint8 infobits)
      22 ECB             : {
      23 GNC          41 :     if ((infobits & XLHL_XMAX_IS_MULTI) == 0 &&
      24              41 :         (infobits & XLHL_XMAX_LOCK_ONLY) == 0 &&
      25              30 :         (infobits & XLHL_XMAX_EXCL_LOCK) == 0 &&
      26              30 :         (infobits & XLHL_XMAX_KEYSHR_LOCK) == 0 &&
      27              30 :         (infobits & XLHL_KEYS_UPDATED) == 0)
      28              22 :         return;
      29                 : 
      30              19 :     appendStringInfoString(buf, ", infobits: [");
      31                 : 
      32 GIC          19 :     if (infobits & XLHL_XMAX_IS_MULTI)
      33 UNC           0 :         appendStringInfoString(buf, " IS_MULTI");
      34 CBC          19 :     if (infobits & XLHL_XMAX_LOCK_ONLY)
      35 GNC          11 :         appendStringInfoString(buf, ", LOCK_ONLY");
      36 CBC          19 :     if (infobits & XLHL_XMAX_EXCL_LOCK)
      37 GNC          11 :         appendStringInfoString(buf, ", EXCL_LOCK");
      38 CBC          19 :     if (infobits & XLHL_XMAX_KEYSHR_LOCK)
      39 UNC           0 :         appendStringInfoString(buf, ", KEYSHR_LOCK");
      40 CBC          19 :     if (infobits & XLHL_KEYS_UPDATED)
      41 GNC           8 :         appendStringInfoString(buf, ", KEYS_UPDATED");
      42                 : 
      43              19 :     appendStringInfoString(buf, " ]");
      44                 : }
      45                 : 
      46                 : static void
      47 UNC           0 : plan_elem_desc(StringInfo buf, void *plan, void *data)
      48                 : {
      49               0 :     xl_heap_freeze_plan *new_plan = (xl_heap_freeze_plan *) plan;
      50               0 :     OffsetNumber **offsets = data;
      51                 : 
      52               0 :     appendStringInfo(buf, "{ xmax: %u, infomask: %u, infomask2: %u, ntuples: %u",
      53                 :                      new_plan->xmax,
      54               0 :                      new_plan->t_infomask, new_plan->t_infomask2,
      55               0 :                      new_plan->ntuples);
      56                 : 
      57               0 :     appendStringInfoString(buf, ", offsets:");
      58               0 :     array_desc(buf, *offsets, sizeof(OffsetNumber), new_plan->ntuples,
      59                 :                &offset_elem_desc, NULL);
      60                 : 
      61               0 :     *offsets += new_plan->ntuples;
      62                 : 
      63               0 :     appendStringInfo(buf, " }");
      64 LBC           0 : }
      65 EUB             : 
      66 ECB             : void
      67 CBC       30937 : heap_desc(StringInfo buf, XLogReaderState *record)
      68 ECB             : {
      69 CBC       30937 :     char       *rec = XLogRecGetData(record);
      70           30937 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      71 EUB             : 
      72 CBC       30937 :     info &= XLOG_HEAP_OPMASK;
      73           30937 :     if (info == XLOG_HEAP_INSERT)
      74                 :     {
      75           30896 :         xl_heap_insert *xlrec = (xl_heap_insert *) rec;
      76                 : 
      77 GNC       30896 :         appendStringInfo(buf, "off: %u, flags: 0x%02X",
      78           30896 :                          xlrec->offnum,
      79 GIC       30896 :                          xlrec->flags);
      80 EUB             :     }
      81 GIC          41 :     else if (info == XLOG_HEAP_DELETE)
      82 EUB             :     {
      83 GBC           8 :         xl_heap_delete *xlrec = (xl_heap_delete *) rec;
      84                 : 
      85 GNC           8 :         appendStringInfo(buf, "off: %u, flags: 0x%02X",
      86 GIC           8 :                          xlrec->offnum,
      87 GBC           8 :                          xlrec->flags);
      88               8 :         out_infobits(buf, xlrec->infobits_set);
      89                 :     }
      90              33 :     else if (info == XLOG_HEAP_UPDATE)
      91 EUB             :     {
      92 GIC          10 :         xl_heap_update *xlrec = (xl_heap_update *) rec;
      93                 : 
      94 GNC          10 :         appendStringInfo(buf, "off: %u, xmax: %u, flags: 0x%02X",
      95 GIC          10 :                          xlrec->old_offnum,
      96 EUB             :                          xlrec->old_xmax,
      97 GBC          10 :                          xlrec->flags);
      98 GIC          10 :         out_infobits(buf, xlrec->old_infobits_set);
      99 GNC          10 :         appendStringInfo(buf, ", new off: %u, xmax %u",
     100 CBC          10 :                          xlrec->new_offnum,
     101                 :                          xlrec->new_xmax);
     102 ECB             :     }
     103 CBC          23 :     else if (info == XLOG_HEAP_HOT_UPDATE)
     104                 :     {
     105              12 :         xl_heap_update *xlrec = (xl_heap_update *) rec;
     106 ECB             : 
     107 GNC          12 :         appendStringInfo(buf, "off: %u, xmax: %u, flags: 0x%02X",
     108 CBC          12 :                          xlrec->old_offnum,
     109                 :                          xlrec->old_xmax,
     110              12 :                          xlrec->flags);
     111              12 :         out_infobits(buf, xlrec->old_infobits_set);
     112 GNC          12 :         appendStringInfo(buf, ", new off: %u, xmax: %u",
     113 GIC          12 :                          xlrec->new_offnum,
     114 ECB             :                          xlrec->new_xmax);
     115                 :     }
     116 CBC          11 :     else if (info == XLOG_HEAP_TRUNCATE)
     117                 :     {
     118 LBC           0 :         xl_heap_truncate *xlrec = (xl_heap_truncate *) rec;
     119 ECB             : 
     120 UNC           0 :         appendStringInfoString(buf, "flags: [");
     121 LBC           0 :         if (xlrec->flags & XLH_TRUNCATE_CASCADE)
     122 UNC           0 :             appendStringInfoString(buf, " CASCADE");
     123 LBC           0 :         if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS)
     124 UNC           0 :             appendStringInfoString(buf, ", RESTART_SEQS");
     125               0 :         appendStringInfoString(buf, " ]");
     126                 : 
     127               0 :         appendStringInfo(buf, ", nrelids: %u", xlrec->nrelids);
     128               0 :         appendStringInfoString(buf, ", relids:");
     129               0 :         array_desc(buf, xlrec->relids, sizeof(Oid), xlrec->nrelids,
     130                 :                    &relid_desc, NULL);
     131 ECB             :     }
     132 GIC          11 :     else if (info == XLOG_HEAP_CONFIRM)
     133 ECB             :     {
     134 LBC           0 :         xl_heap_confirm *xlrec = (xl_heap_confirm *) rec;
     135 ECB             : 
     136 UNC           0 :         appendStringInfo(buf, "off: %u", xlrec->offnum);
     137                 :     }
     138 GIC          11 :     else if (info == XLOG_HEAP_LOCK)
     139 ECB             :     {
     140 GIC          11 :         xl_heap_lock *xlrec = (xl_heap_lock *) rec;
     141 ECB             : 
     142 GNC          11 :         appendStringInfo(buf, "off: %u, xid: %u, flags: 0x%02X",
     143 CBC          11 :                          xlrec->offnum, xlrec->locking_xid, xlrec->flags);
     144              11 :         out_infobits(buf, xlrec->infobits_set);
     145                 :     }
     146 LBC           0 :     else if (info == XLOG_HEAP_INPLACE)
     147 ECB             :     {
     148 LBC           0 :         xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
     149 ECB             : 
     150 UNC           0 :         appendStringInfo(buf, "off: %u", xlrec->offnum);
     151                 :     }
     152 CBC       30937 : }
     153                 : 
     154                 : void
     155 GBC          63 : heap2_desc(StringInfo buf, XLogReaderState *record)
     156                 : {
     157              63 :     char       *rec = XLogRecGetData(record);
     158              63 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
     159 EUB             : 
     160 GBC          63 :     info &= XLOG_HEAP_OPMASK;
     161              63 :     if (info == XLOG_HEAP2_PRUNE)
     162 EUB             :     {
     163 GIC          47 :         xl_heap_prune *xlrec = (xl_heap_prune *) rec;
     164 EUB             : 
     165 GNC          47 :         appendStringInfo(buf, "snapshotConflictHorizon: %u, nredirected: %u, ndead: %u",
     166                 :                          xlrec->snapshotConflictHorizon,
     167 GIC          47 :                          xlrec->nredirected,
     168              47 :                          xlrec->ndead);
     169                 : 
     170 GNC          47 :         if (!XLogRecHasBlockImage(record, 0))
     171                 :         {
     172                 :             OffsetNumber *end;
     173                 :             OffsetNumber *redirected;
     174                 :             OffsetNumber *nowdead;
     175                 :             OffsetNumber *nowunused;
     176                 :             int         nredirected;
     177                 :             int         nunused;
     178                 :             Size        datalen;
     179                 : 
     180              47 :             redirected = (OffsetNumber *) XLogRecGetBlockData(record, 0,
     181                 :                                                               &datalen);
     182                 : 
     183              47 :             nredirected = xlrec->nredirected;
     184              47 :             end = (OffsetNumber *) ((char *) redirected + datalen);
     185              47 :             nowdead = redirected + (nredirected * 2);
     186              47 :             nowunused = nowdead + xlrec->ndead;
     187              47 :             nunused = (end - nowunused);
     188              47 :             Assert(nunused >= 0);
     189                 : 
     190              47 :             appendStringInfo(buf, ", nunused: %u", nunused);
     191                 : 
     192              47 :             appendStringInfoString(buf, ", redirected:");
     193              47 :             array_desc(buf, redirected, sizeof(OffsetNumber) * 2,
     194                 :                        nredirected, &redirect_elem_desc, NULL);
     195              47 :             appendStringInfoString(buf, ", dead:");
     196              47 :             array_desc(buf, nowdead, sizeof(OffsetNumber), xlrec->ndead,
     197                 :                        &offset_elem_desc, NULL);
     198              47 :             appendStringInfoString(buf, ", unused:");
     199              47 :             array_desc(buf, nowunused, sizeof(OffsetNumber), nunused,
     200                 :                        &offset_elem_desc, NULL);
     201                 :         }
     202 ECB             :     }
     203 GIC          16 :     else if (info == XLOG_HEAP2_VACUUM)
     204 EUB             :     {
     205 UIC           0 :         xl_heap_vacuum *xlrec = (xl_heap_vacuum *) rec;
     206 EUB             : 
     207 UNC           0 :         appendStringInfo(buf, "nunused: %u", xlrec->nunused);
     208                 : 
     209               0 :         if (!XLogRecHasBlockImage(record, 0))
     210                 :         {
     211                 :             OffsetNumber *nowunused;
     212                 : 
     213               0 :             nowunused = (OffsetNumber *) XLogRecGetBlockData(record, 0, NULL);
     214                 : 
     215               0 :             appendStringInfoString(buf, ", unused:");
     216               0 :             array_desc(buf, nowunused, sizeof(OffsetNumber), xlrec->nunused,
     217                 :                        &offset_elem_desc, NULL);
     218                 :         }
     219 ECB             :     }
     220 GIC          16 :     else if (info == XLOG_HEAP2_FREEZE_PAGE)
     221 ECB             :     {
     222 UIC           0 :         xl_heap_freeze_page *xlrec = (xl_heap_freeze_page *) rec;
     223 ECB             : 
     224 UNC           0 :         appendStringInfo(buf, "snapshotConflictHorizon: %u, nplans: %u",
     225               0 :                          xlrec->snapshotConflictHorizon, xlrec->nplans);
     226                 : 
     227               0 :         if (!XLogRecHasBlockImage(record, 0))
     228                 :         {
     229                 :             xl_heap_freeze_plan *plans;
     230                 :             OffsetNumber *offsets;
     231                 : 
     232               0 :             plans = (xl_heap_freeze_plan *) XLogRecGetBlockData(record, 0, NULL);
     233               0 :             offsets = (OffsetNumber *) &plans[xlrec->nplans];
     234               0 :             appendStringInfoString(buf, ", plans:");
     235               0 :             array_desc(buf, plans, sizeof(xl_heap_freeze_plan), xlrec->nplans,
     236                 :                        &plan_elem_desc, &offsets);
     237                 :         }
     238                 :     }
     239 GBC          16 :     else if (info == XLOG_HEAP2_VISIBLE)
     240                 :     {
     241 UBC           0 :         xl_heap_visible *xlrec = (xl_heap_visible *) rec;
     242                 : 
     243 UNC           0 :         appendStringInfo(buf, "snapshotConflictHorizon: %u, flags: 0x%02X",
     244               0 :                          xlrec->snapshotConflictHorizon, xlrec->flags);
     245 ECB             :     }
     246 GIC          16 :     else if (info == XLOG_HEAP2_MULTI_INSERT)
     247                 :     {
     248 CBC          16 :         xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
     249 GNC          16 :         bool        isinit = (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
     250                 : 
     251              16 :         appendStringInfo(buf, "ntuples: %d, flags: 0x%02X", xlrec->ntuples,
     252 CBC          16 :                          xlrec->flags);
     253                 : 
     254 GNC          16 :         appendStringInfoString(buf, ", offsets:");
     255              16 :         if (!XLogRecHasBlockImage(record, 0) && !isinit)
     256              13 :             array_desc(buf, xlrec->offsets, sizeof(OffsetNumber),
     257              13 :                        xlrec->ntuples, &offset_elem_desc, NULL);
     258                 :     }
     259 LBC           0 :     else if (info == XLOG_HEAP2_LOCK_UPDATED)
     260 ECB             :     {
     261 UIC           0 :         xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
     262 ECB             : 
     263 UNC           0 :         appendStringInfo(buf, "off: %u, xmax: %u, flags: 0x%02X",
     264 LBC           0 :                          xlrec->offnum, xlrec->xmax, xlrec->flags);
     265 UIC           0 :         out_infobits(buf, xlrec->infobits_set);
     266 ECB             :     }
     267 LBC           0 :     else if (info == XLOG_HEAP2_NEW_CID)
     268                 :     {
     269               0 :         xl_heap_new_cid *xlrec = (xl_heap_new_cid *) rec;
     270                 : 
     271 UNC           0 :         appendStringInfo(buf, "rel: %u/%u/%u, tid: %u/%u",
     272                 :                          xlrec->target_locator.spcOid,
     273                 :                          xlrec->target_locator.dbOid,
     274                 :                          xlrec->target_locator.relNumber,
     275 UIC           0 :                          ItemPointerGetBlockNumber(&(xlrec->target_tid)),
     276               0 :                          ItemPointerGetOffsetNumber(&(xlrec->target_tid)));
     277 UNC           0 :         appendStringInfo(buf, ", cmin: %u, cmax: %u, combo: %u",
     278                 :                          xlrec->cmin, xlrec->cmax, xlrec->combocid);
     279 ECB             :     }
     280 GIC          63 : }
     281                 : 
     282 ECB             : const char *
     283 CBC       30937 : heap_identify(uint8 info)
     284 ECB             : {
     285 CBC       30937 :     const char *id = NULL;
     286 ECB             : 
     287 CBC       30937 :     switch (info & ~XLR_INFO_MASK)
     288                 :     {
     289           29486 :         case XLOG_HEAP_INSERT:
     290 GIC       29486 :             id = "INSERT";
     291 CBC       29486 :             break;
     292            1410 :         case XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE:
     293 GIC        1410 :             id = "INSERT+INIT";
     294 CBC        1410 :             break;
     295               8 :         case XLOG_HEAP_DELETE:
     296 GIC           8 :             id = "DELETE";
     297 CBC           8 :             break;
     298               9 :         case XLOG_HEAP_UPDATE:
     299 GIC           9 :             id = "UPDATE";
     300               9 :             break;
     301               1 :         case XLOG_HEAP_UPDATE | XLOG_HEAP_INIT_PAGE:
     302 CBC           1 :             id = "UPDATE+INIT";
     303 GIC           1 :             break;
     304 GBC          12 :         case XLOG_HEAP_HOT_UPDATE:
     305 GIC          12 :             id = "HOT_UPDATE";
     306 GBC          12 :             break;
     307 UIC           0 :         case XLOG_HEAP_HOT_UPDATE | XLOG_HEAP_INIT_PAGE:
     308 UBC           0 :             id = "HOT_UPDATE+INIT";
     309 UIC           0 :             break;
     310               0 :         case XLOG_HEAP_TRUNCATE:
     311               0 :             id = "TRUNCATE";
     312 UBC           0 :             break;
     313 UIC           0 :         case XLOG_HEAP_CONFIRM:
     314 UBC           0 :             id = "HEAP_CONFIRM";
     315               0 :             break;
     316 GIC          11 :         case XLOG_HEAP_LOCK:
     317              11 :             id = "LOCK";
     318              11 :             break;
     319 LBC           0 :         case XLOG_HEAP_INPLACE:
     320 UIC           0 :             id = "INPLACE";
     321 UBC           0 :             break;
     322                 :     }
     323 EUB             : 
     324 GBC       30937 :     return id;
     325                 : }
     326 EUB             : 
     327                 : const char *
     328 GIC          63 : heap2_identify(uint8 info)
     329                 : {
     330              63 :     const char *id = NULL;
     331 EUB             : 
     332 GBC          63 :     switch (info & ~XLR_INFO_MASK)
     333 EUB             :     {
     334 GBC          47 :         case XLOG_HEAP2_PRUNE:
     335 GIC          47 :             id = "PRUNE";
     336              47 :             break;
     337 UIC           0 :         case XLOG_HEAP2_VACUUM:
     338 LBC           0 :             id = "VACUUM";
     339 UIC           0 :             break;
     340 UBC           0 :         case XLOG_HEAP2_FREEZE_PAGE:
     341 UIC           0 :             id = "FREEZE_PAGE";
     342 UBC           0 :             break;
     343               0 :         case XLOG_HEAP2_VISIBLE:
     344 UIC           0 :             id = "VISIBLE";
     345 LBC           0 :             break;
     346 GIC          16 :         case XLOG_HEAP2_MULTI_INSERT:
     347 CBC          16 :             id = "MULTI_INSERT";
     348              16 :             break;
     349 UIC           0 :         case XLOG_HEAP2_MULTI_INSERT | XLOG_HEAP_INIT_PAGE:
     350 LBC           0 :             id = "MULTI_INSERT+INIT";
     351               0 :             break;
     352 UIC           0 :         case XLOG_HEAP2_LOCK_UPDATED:
     353 LBC           0 :             id = "LOCK_UPDATED";
     354               0 :             break;
     355               0 :         case XLOG_HEAP2_NEW_CID:
     356               0 :             id = "NEW_CID";
     357 UIC           0 :             break;
     358 UBC           0 :         case XLOG_HEAP2_REWRITE:
     359 UIC           0 :             id = "REWRITE";
     360 UBC           0 :             break;
     361                 :     }
     362 EUB             : 
     363 GBC          63 :     return id;
     364 EUB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a