LCOV - code coverage report
Current view: top level - src/bin/pg_waldump - xactdesc.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 50.0 % 248 124
Test Date: 2026-02-17 17:20:33 Functions: 75.0 % 12 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * xactdesc.c
       4              :  *    rmgr descriptor routines for access/transam/xact.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/xactdesc.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : #include "postgres.h"
      16              : 
      17              : #include "access/transam.h"
      18              : #include "access/xact.h"
      19              : #include "replication/origin.h"
      20              : #include "storage/sinval.h"
      21              : #include "storage/standbydefs.h"
      22              : #include "utils/timestamp.h"
      23              : 
      24              : /*
      25              :  * Parse the WAL format of an xact commit and abort records into an easier to
      26              :  * understand format.
      27              :  *
      28              :  * These routines are in xactdesc.c because they're accessed in backend (when
      29              :  * replaying WAL) and frontend (pg_waldump) code. This file is the only xact
      30              :  * specific one shared between both. They're complicated enough that
      31              :  * duplication would be bothersome.
      32              :  */
      33              : 
      34              : void
      35         1692 : ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
      36              : {
      37         1692 :     char       *data = ((char *) xlrec) + MinSizeOfXactCommit;
      38              : 
      39         1692 :     memset(parsed, 0, sizeof(*parsed));
      40              : 
      41         1692 :     parsed->xinfo = 0;           /* default, if no XLOG_XACT_HAS_INFO is
      42              :                                  * present */
      43              : 
      44         1692 :     parsed->xact_time = xlrec->xact_time;
      45              : 
      46         1692 :     if (info & XLOG_XACT_HAS_INFO)
      47              :     {
      48         1672 :         xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
      49              : 
      50         1672 :         parsed->xinfo = xl_xinfo->xinfo;
      51              : 
      52         1672 :         data += sizeof(xl_xact_xinfo);
      53              :     }
      54              : 
      55         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
      56              :     {
      57         1672 :         xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
      58              : 
      59         1672 :         parsed->dbId = xl_dbinfo->dbId;
      60         1672 :         parsed->tsId = xl_dbinfo->tsId;
      61              : 
      62         1672 :         data += sizeof(xl_xact_dbinfo);
      63              :     }
      64              : 
      65         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
      66              :     {
      67            0 :         xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
      68              : 
      69            0 :         parsed->nsubxacts = xl_subxacts->nsubxacts;
      70            0 :         parsed->subxacts = xl_subxacts->subxacts;
      71              : 
      72            0 :         data += MinSizeOfXactSubxacts;
      73            0 :         data += parsed->nsubxacts * sizeof(TransactionId);
      74              :     }
      75              : 
      76         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
      77              :     {
      78           12 :         xl_xact_relfilelocators *xl_rellocators = (xl_xact_relfilelocators *) data;
      79              : 
      80           12 :         parsed->nrels = xl_rellocators->nrels;
      81           12 :         parsed->xlocators = xl_rellocators->xlocators;
      82              : 
      83           12 :         data += MinSizeOfXactRelfileLocators;
      84           12 :         data += xl_rellocators->nrels * sizeof(RelFileLocator);
      85              :     }
      86              : 
      87         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_DROPPED_STATS)
      88              :     {
      89           12 :         xl_xact_stats_items *xl_drops = (xl_xact_stats_items *) data;
      90              : 
      91           12 :         parsed->nstats = xl_drops->nitems;
      92           12 :         parsed->stats = xl_drops->items;
      93              : 
      94           12 :         data += MinSizeOfXactStatsItems;
      95           12 :         data += xl_drops->nitems * sizeof(xl_xact_stats_item);
      96              :     }
      97              : 
      98         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_INVALS)
      99              :     {
     100         1624 :         xl_xact_invals *xl_invals = (xl_xact_invals *) data;
     101              : 
     102         1624 :         parsed->nmsgs = xl_invals->nmsgs;
     103         1624 :         parsed->msgs = xl_invals->msgs;
     104              : 
     105         1624 :         data += MinSizeOfXactInvals;
     106         1624 :         data += xl_invals->nmsgs * sizeof(SharedInvalidationMessage);
     107              :     }
     108              : 
     109         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
     110              :     {
     111            0 :         xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
     112              : 
     113            0 :         parsed->twophase_xid = xl_twophase->xid;
     114              : 
     115            0 :         data += sizeof(xl_xact_twophase);
     116              : 
     117            0 :         if (parsed->xinfo & XACT_XINFO_HAS_GID)
     118              :         {
     119            0 :             strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
     120            0 :             data += strlen(data) + 1;
     121              :         }
     122              :     }
     123              : 
     124              :     /* Note: no alignment is guaranteed after this point */
     125              : 
     126         1692 :     if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
     127              :     {
     128              :         xl_xact_origin xl_origin;
     129              : 
     130              :         /* no alignment is guaranteed, so copy onto stack */
     131            0 :         memcpy(&xl_origin, data, sizeof(xl_origin));
     132              : 
     133            0 :         parsed->origin_lsn = xl_origin.origin_lsn;
     134            0 :         parsed->origin_timestamp = xl_origin.origin_timestamp;
     135              : 
     136            0 :         data += sizeof(xl_xact_origin);
     137              :     }
     138         1692 : }
     139              : 
     140              : void
     141            6 : ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
     142              : {
     143            6 :     char       *data = ((char *) xlrec) + MinSizeOfXactAbort;
     144              : 
     145            6 :     memset(parsed, 0, sizeof(*parsed));
     146              : 
     147            6 :     parsed->xinfo = 0;           /* default, if no XLOG_XACT_HAS_INFO is
     148              :                                  * present */
     149              : 
     150            6 :     parsed->xact_time = xlrec->xact_time;
     151              : 
     152            6 :     if (info & XLOG_XACT_HAS_INFO)
     153              :     {
     154            0 :         xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
     155              : 
     156            0 :         parsed->xinfo = xl_xinfo->xinfo;
     157              : 
     158            0 :         data += sizeof(xl_xact_xinfo);
     159              :     }
     160              : 
     161            6 :     if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
     162              :     {
     163            0 :         xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
     164              : 
     165            0 :         parsed->dbId = xl_dbinfo->dbId;
     166            0 :         parsed->tsId = xl_dbinfo->tsId;
     167              : 
     168            0 :         data += sizeof(xl_xact_dbinfo);
     169              :     }
     170              : 
     171            6 :     if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
     172              :     {
     173            0 :         xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
     174              : 
     175            0 :         parsed->nsubxacts = xl_subxacts->nsubxacts;
     176            0 :         parsed->subxacts = xl_subxacts->subxacts;
     177              : 
     178            0 :         data += MinSizeOfXactSubxacts;
     179            0 :         data += parsed->nsubxacts * sizeof(TransactionId);
     180              :     }
     181              : 
     182            6 :     if (parsed->xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
     183              :     {
     184            0 :         xl_xact_relfilelocators *xl_rellocator = (xl_xact_relfilelocators *) data;
     185              : 
     186            0 :         parsed->nrels = xl_rellocator->nrels;
     187            0 :         parsed->xlocators = xl_rellocator->xlocators;
     188              : 
     189            0 :         data += MinSizeOfXactRelfileLocators;
     190            0 :         data += xl_rellocator->nrels * sizeof(RelFileLocator);
     191              :     }
     192              : 
     193            6 :     if (parsed->xinfo & XACT_XINFO_HAS_DROPPED_STATS)
     194              :     {
     195            0 :         xl_xact_stats_items *xl_drops = (xl_xact_stats_items *) data;
     196              : 
     197            0 :         parsed->nstats = xl_drops->nitems;
     198            0 :         parsed->stats = xl_drops->items;
     199              : 
     200            0 :         data += MinSizeOfXactStatsItems;
     201            0 :         data += xl_drops->nitems * sizeof(xl_xact_stats_item);
     202              :     }
     203              : 
     204            6 :     if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
     205              :     {
     206            0 :         xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
     207              : 
     208            0 :         parsed->twophase_xid = xl_twophase->xid;
     209              : 
     210            0 :         data += sizeof(xl_xact_twophase);
     211              : 
     212            0 :         if (parsed->xinfo & XACT_XINFO_HAS_GID)
     213              :         {
     214            0 :             strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
     215            0 :             data += strlen(data) + 1;
     216              :         }
     217              :     }
     218              : 
     219              :     /* Note: no alignment is guaranteed after this point */
     220              : 
     221            6 :     if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
     222              :     {
     223              :         xl_xact_origin xl_origin;
     224              : 
     225              :         /* no alignment is guaranteed, so copy onto stack */
     226            0 :         memcpy(&xl_origin, data, sizeof(xl_origin));
     227              : 
     228            0 :         parsed->origin_lsn = xl_origin.origin_lsn;
     229            0 :         parsed->origin_timestamp = xl_origin.origin_timestamp;
     230              : 
     231            0 :         data += sizeof(xl_xact_origin);
     232              :     }
     233            6 : }
     234              : 
     235              : /*
     236              :  * ParsePrepareRecord
     237              :  */
     238              : void
     239            0 : ParsePrepareRecord(uint8 info, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed)
     240              : {
     241              :     char       *bufptr;
     242              : 
     243            0 :     bufptr = ((char *) xlrec) + MAXALIGN(sizeof(xl_xact_prepare));
     244              : 
     245            0 :     memset(parsed, 0, sizeof(*parsed));
     246              : 
     247            0 :     parsed->xact_time = xlrec->prepared_at;
     248            0 :     parsed->origin_lsn = xlrec->origin_lsn;
     249            0 :     parsed->origin_timestamp = xlrec->origin_timestamp;
     250            0 :     parsed->twophase_xid = xlrec->xid;
     251            0 :     parsed->dbId = xlrec->database;
     252            0 :     parsed->nsubxacts = xlrec->nsubxacts;
     253            0 :     parsed->nrels = xlrec->ncommitrels;
     254            0 :     parsed->nabortrels = xlrec->nabortrels;
     255            0 :     parsed->nstats = xlrec->ncommitstats;
     256            0 :     parsed->nabortstats = xlrec->nabortstats;
     257            0 :     parsed->nmsgs = xlrec->ninvalmsgs;
     258              : 
     259            0 :     strncpy(parsed->twophase_gid, bufptr, xlrec->gidlen);
     260            0 :     bufptr += MAXALIGN(xlrec->gidlen);
     261              : 
     262            0 :     parsed->subxacts = (TransactionId *) bufptr;
     263            0 :     bufptr += MAXALIGN(xlrec->nsubxacts * sizeof(TransactionId));
     264              : 
     265            0 :     parsed->xlocators = (RelFileLocator *) bufptr;
     266            0 :     bufptr += MAXALIGN(xlrec->ncommitrels * sizeof(RelFileLocator));
     267              : 
     268            0 :     parsed->abortlocators = (RelFileLocator *) bufptr;
     269            0 :     bufptr += MAXALIGN(xlrec->nabortrels * sizeof(RelFileLocator));
     270              : 
     271            0 :     parsed->stats = (xl_xact_stats_item *) bufptr;
     272            0 :     bufptr += MAXALIGN(xlrec->ncommitstats * sizeof(xl_xact_stats_item));
     273              : 
     274            0 :     parsed->abortstats = (xl_xact_stats_item *) bufptr;
     275            0 :     bufptr += MAXALIGN(xlrec->nabortstats * sizeof(xl_xact_stats_item));
     276              : 
     277            0 :     parsed->msgs = (SharedInvalidationMessage *) bufptr;
     278            0 :     bufptr += MAXALIGN(xlrec->ninvalmsgs * sizeof(SharedInvalidationMessage));
     279            0 : }
     280              : 
     281              : static void
     282         1698 : xact_desc_relations(StringInfo buf, char *label, int nrels,
     283              :                     RelFileLocator *xlocators)
     284              : {
     285              :     int         i;
     286              : 
     287         1698 :     if (nrels > 0)
     288              :     {
     289           12 :         appendStringInfo(buf, "; %s:", label);
     290           60 :         for (i = 0; i < nrels; i++)
     291              :         {
     292           48 :             appendStringInfo(buf, " %s",
     293           48 :                              relpathperm(xlocators[i], MAIN_FORKNUM).str);
     294              :         }
     295              :     }
     296         1698 : }
     297              : 
     298              : static void
     299         1698 : xact_desc_subxacts(StringInfo buf, int nsubxacts, TransactionId *subxacts)
     300              : {
     301              :     int         i;
     302              : 
     303         1698 :     if (nsubxacts > 0)
     304              :     {
     305            0 :         appendStringInfoString(buf, "; subxacts:");
     306            0 :         for (i = 0; i < nsubxacts; i++)
     307            0 :             appendStringInfo(buf, " %u", subxacts[i]);
     308              :     }
     309         1698 : }
     310              : 
     311              : static void
     312         1698 : xact_desc_stats(StringInfo buf, const char *label,
     313              :                 int ndropped, xl_xact_stats_item *dropped_stats)
     314              : {
     315              :     int         i;
     316              : 
     317         1698 :     if (ndropped > 0)
     318              :     {
     319           12 :         appendStringInfo(buf, "; %sdropped stats:", label);
     320           24 :         for (i = 0; i < ndropped; i++)
     321              :         {
     322           12 :             uint64      objid =
     323           12 :                 ((uint64) dropped_stats[i].objid_hi) << 32 | dropped_stats[i].objid_lo;
     324              : 
     325           12 :             appendStringInfo(buf, " %d/%u/%" PRIu64,
     326           12 :                              dropped_stats[i].kind,
     327           12 :                              dropped_stats[i].dboid,
     328              :                              objid);
     329              :         }
     330              :     }
     331         1698 : }
     332              : 
     333              : static void
     334         1692 : xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, ReplOriginId origin_id)
     335              : {
     336              :     xl_xact_parsed_commit parsed;
     337              : 
     338         1692 :     ParseCommitRecord(info, xlrec, &parsed);
     339              : 
     340              :     /* If this is a prepared xact, show the xid of the original xact */
     341         1692 :     if (TransactionIdIsValid(parsed.twophase_xid))
     342            0 :         appendStringInfo(buf, "%u: ", parsed.twophase_xid);
     343              : 
     344         1692 :     appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
     345              : 
     346         1692 :     xact_desc_relations(buf, "rels", parsed.nrels, parsed.xlocators);
     347         1692 :     xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     348         1692 :     xact_desc_stats(buf, "", parsed.nstats, parsed.stats);
     349              : 
     350         1692 :     standby_desc_invalidations(buf, parsed.nmsgs, parsed.msgs, parsed.dbId,
     351              :                                parsed.tsId,
     352         1692 :                                XactCompletionRelcacheInitFileInval(parsed.xinfo));
     353              : 
     354         1692 :     if (XactCompletionApplyFeedback(parsed.xinfo))
     355            0 :         appendStringInfoString(buf, "; apply_feedback");
     356              : 
     357         1692 :     if (XactCompletionForceSyncCommit(parsed.xinfo))
     358           28 :         appendStringInfoString(buf, "; sync");
     359              : 
     360         1692 :     if (parsed.xinfo & XACT_XINFO_HAS_ORIGIN)
     361              :     {
     362            0 :         appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     363              :                          origin_id,
     364            0 :                          LSN_FORMAT_ARGS(parsed.origin_lsn),
     365              :                          timestamptz_to_str(parsed.origin_timestamp));
     366              :     }
     367         1692 : }
     368              : 
     369              : static void
     370            6 : xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec, ReplOriginId origin_id)
     371              : {
     372              :     xl_xact_parsed_abort parsed;
     373              : 
     374            6 :     ParseAbortRecord(info, xlrec, &parsed);
     375              : 
     376              :     /* If this is a prepared xact, show the xid of the original xact */
     377            6 :     if (TransactionIdIsValid(parsed.twophase_xid))
     378            0 :         appendStringInfo(buf, "%u: ", parsed.twophase_xid);
     379              : 
     380            6 :     appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
     381              : 
     382            6 :     xact_desc_relations(buf, "rels", parsed.nrels, parsed.xlocators);
     383            6 :     xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     384              : 
     385            6 :     if (parsed.xinfo & XACT_XINFO_HAS_ORIGIN)
     386              :     {
     387            0 :         appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     388              :                          origin_id,
     389            0 :                          LSN_FORMAT_ARGS(parsed.origin_lsn),
     390              :                          timestamptz_to_str(parsed.origin_timestamp));
     391              :     }
     392              : 
     393            6 :     xact_desc_stats(buf, "", parsed.nstats, parsed.stats);
     394            6 : }
     395              : 
     396              : static void
     397            0 : xact_desc_prepare(StringInfo buf, uint8 info, xl_xact_prepare *xlrec, ReplOriginId origin_id)
     398              : {
     399              :     xl_xact_parsed_prepare parsed;
     400              : 
     401            0 :     ParsePrepareRecord(info, xlrec, &parsed);
     402              : 
     403            0 :     appendStringInfo(buf, "gid %s: ", parsed.twophase_gid);
     404            0 :     appendStringInfoString(buf, timestamptz_to_str(parsed.xact_time));
     405              : 
     406            0 :     xact_desc_relations(buf, "rels(commit)", parsed.nrels, parsed.xlocators);
     407            0 :     xact_desc_relations(buf, "rels(abort)", parsed.nabortrels,
     408              :                         parsed.abortlocators);
     409            0 :     xact_desc_stats(buf, "commit ", parsed.nstats, parsed.stats);
     410            0 :     xact_desc_stats(buf, "abort ", parsed.nabortstats, parsed.abortstats);
     411            0 :     xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     412              : 
     413            0 :     standby_desc_invalidations(buf, parsed.nmsgs, parsed.msgs, parsed.dbId,
     414            0 :                                parsed.tsId, xlrec->initfileinval);
     415              : 
     416              :     /*
     417              :      * Check if the replication origin has been set in this record in the same
     418              :      * way as PrepareRedoAdd().
     419              :      */
     420            0 :     if (origin_id != InvalidReplOriginId)
     421            0 :         appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     422              :                          origin_id,
     423            0 :                          LSN_FORMAT_ARGS(parsed.origin_lsn),
     424              :                          timestamptz_to_str(parsed.origin_timestamp));
     425            0 : }
     426              : 
     427              : static void
     428            0 : xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
     429              : {
     430              :     int         i;
     431              : 
     432            0 :     appendStringInfoString(buf, "subxacts:");
     433              : 
     434            0 :     for (i = 0; i < xlrec->nsubxacts; i++)
     435            0 :         appendStringInfo(buf, " %u", xlrec->xsub[i]);
     436            0 : }
     437              : 
     438              : void
     439         2778 : xact_desc(StringInfo buf, XLogReaderState *record)
     440              : {
     441         2778 :     char       *rec = XLogRecGetData(record);
     442         2778 :     uint8       info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
     443              : 
     444         2778 :     if (info == XLOG_XACT_COMMIT || info == XLOG_XACT_COMMIT_PREPARED)
     445         1692 :     {
     446         1692 :         xl_xact_commit *xlrec = (xl_xact_commit *) rec;
     447              : 
     448         1692 :         xact_desc_commit(buf, XLogRecGetInfo(record), xlrec,
     449         1692 :                          XLogRecGetOrigin(record));
     450              :     }
     451         1086 :     else if (info == XLOG_XACT_ABORT || info == XLOG_XACT_ABORT_PREPARED)
     452            6 :     {
     453            6 :         xl_xact_abort *xlrec = (xl_xact_abort *) rec;
     454              : 
     455            6 :         xact_desc_abort(buf, XLogRecGetInfo(record), xlrec,
     456            6 :                         XLogRecGetOrigin(record));
     457              :     }
     458         1080 :     else if (info == XLOG_XACT_PREPARE)
     459              :     {
     460            0 :         xl_xact_prepare *xlrec = (xl_xact_prepare *) rec;
     461              : 
     462            0 :         xact_desc_prepare(buf, XLogRecGetInfo(record), xlrec,
     463            0 :                           XLogRecGetOrigin(record));
     464              :     }
     465         1080 :     else if (info == XLOG_XACT_ASSIGNMENT)
     466              :     {
     467            0 :         xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
     468              : 
     469              :         /*
     470              :          * Note that we ignore the WAL record's xid, since we're more
     471              :          * interested in the top-level xid that issued the record and which
     472              :          * xids are being reported here.
     473              :          */
     474            0 :         appendStringInfo(buf, "xtop %u: ", xlrec->xtop);
     475            0 :         xact_desc_assignment(buf, xlrec);
     476              :     }
     477         1080 :     else if (info == XLOG_XACT_INVALIDATIONS)
     478              :     {
     479         1080 :         xl_xact_invals *xlrec = (xl_xact_invals *) rec;
     480              : 
     481         1080 :         standby_desc_invalidations(buf, xlrec->nmsgs, xlrec->msgs, InvalidOid,
     482              :                                    InvalidOid, false);
     483              :     }
     484         2778 : }
     485              : 
     486              : const char *
     487         2781 : xact_identify(uint8 info)
     488              : {
     489         2781 :     const char *id = NULL;
     490              : 
     491         2781 :     switch (info & XLOG_XACT_OPMASK)
     492              :     {
     493         1693 :         case XLOG_XACT_COMMIT:
     494         1693 :             id = "COMMIT";
     495         1693 :             break;
     496            0 :         case XLOG_XACT_PREPARE:
     497            0 :             id = "PREPARE";
     498            0 :             break;
     499            7 :         case XLOG_XACT_ABORT:
     500            7 :             id = "ABORT";
     501            7 :             break;
     502            0 :         case XLOG_XACT_COMMIT_PREPARED:
     503            0 :             id = "COMMIT_PREPARED";
     504            0 :             break;
     505            0 :         case XLOG_XACT_ABORT_PREPARED:
     506            0 :             id = "ABORT_PREPARED";
     507            0 :             break;
     508            0 :         case XLOG_XACT_ASSIGNMENT:
     509            0 :             id = "ASSIGNMENT";
     510            0 :             break;
     511         1081 :         case XLOG_XACT_INVALIDATIONS:
     512         1081 :             id = "INVALIDATION";
     513         1081 :             break;
     514              :     }
     515              : 
     516         2781 :     return id;
     517              : }
        

Generated by: LCOV version 2.0-1