LCOV - differential code coverage report
Current view: top level - src/backend/access/heap - heapam_visibility.c (source / functions) Coverage Total Hit LBC UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 68.4 % 608 416 1 191 416
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 16 16 16
Baseline: lcov-20250906-005545-baseline Branches: 61.9 % 556 344 1 211 344
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 1 1 1
(360..) days: 68.4 % 607 415 1 191 415
Function coverage date bins:
(360..) days: 100.0 % 16 16 16
Branch coverage date bins:
(30,360] days: 75.0 % 4 3 1 3
(360..) days: 61.8 % 552 341 1 210 341

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * heapam_visibility.c
                                  4                 :                :  *    Tuple visibility rules for tuples stored in heap.
                                  5                 :                :  *
                                  6                 :                :  * NOTE: all the HeapTupleSatisfies routines will update the tuple's
                                  7                 :                :  * "hint" status bits if we see that the inserting or deleting transaction
                                  8                 :                :  * has now committed or aborted (and it is safe to set the hint bits).
                                  9                 :                :  * If the hint bits are changed, MarkBufferDirtyHint is called on
                                 10                 :                :  * the passed-in buffer.  The caller must hold not only a pin, but at least
                                 11                 :                :  * shared buffer content lock on the buffer containing the tuple.
                                 12                 :                :  *
                                 13                 :                :  * NOTE: When using a non-MVCC snapshot, we must check
                                 14                 :                :  * TransactionIdIsInProgress (which looks in the PGPROC array) before
                                 15                 :                :  * TransactionIdDidCommit (which look in pg_xact).  Otherwise we have a race
                                 16                 :                :  * condition: we might decide that a just-committed transaction crashed,
                                 17                 :                :  * because none of the tests succeed.  xact.c is careful to record
                                 18                 :                :  * commit/abort in pg_xact before it unsets MyProc->xid in the PGPROC array.
                                 19                 :                :  * That fixes that problem, but it also means there is a window where
                                 20                 :                :  * TransactionIdIsInProgress and TransactionIdDidCommit will both return true.
                                 21                 :                :  * If we check only TransactionIdDidCommit, we could consider a tuple
                                 22                 :                :  * committed when a later GetSnapshotData call will still think the
                                 23                 :                :  * originating transaction is in progress, which leads to application-level
                                 24                 :                :  * inconsistency.  The upshot is that we gotta check TransactionIdIsInProgress
                                 25                 :                :  * first in all code paths, except for a few cases where we are looking at
                                 26                 :                :  * subtransactions of our own main transaction and so there can't be any race
                                 27                 :                :  * condition.
                                 28                 :                :  *
                                 29                 :                :  * We can't use TransactionIdDidAbort here because it won't treat transactions
                                 30                 :                :  * that were in progress during a crash as aborted.  We determine that
                                 31                 :                :  * transactions aborted/crashed through process of elimination instead.
                                 32                 :                :  *
                                 33                 :                :  * When using an MVCC snapshot, we rely on XidInMVCCSnapshot rather than
                                 34                 :                :  * TransactionIdIsInProgress, but the logic is otherwise the same: do not
                                 35                 :                :  * check pg_xact until after deciding that the xact is no longer in progress.
                                 36                 :                :  *
                                 37                 :                :  *
                                 38                 :                :  * Summary of visibility functions:
                                 39                 :                :  *
                                 40                 :                :  *   HeapTupleSatisfiesMVCC()
                                 41                 :                :  *        visible to supplied snapshot, excludes current command
                                 42                 :                :  *   HeapTupleSatisfiesUpdate()
                                 43                 :                :  *        visible to instant snapshot, with user-supplied command
                                 44                 :                :  *        counter and more complex result
                                 45                 :                :  *   HeapTupleSatisfiesSelf()
                                 46                 :                :  *        visible to instant snapshot and current command
                                 47                 :                :  *   HeapTupleSatisfiesDirty()
                                 48                 :                :  *        like HeapTupleSatisfiesSelf(), but includes open transactions
                                 49                 :                :  *   HeapTupleSatisfiesVacuum()
                                 50                 :                :  *        visible to any running transaction, used by VACUUM
                                 51                 :                :  *   HeapTupleSatisfiesNonVacuumable()
                                 52                 :                :  *        Snapshot-style API for HeapTupleSatisfiesVacuum
                                 53                 :                :  *   HeapTupleSatisfiesToast()
                                 54                 :                :  *        visible unless part of interrupted vacuum, used for TOAST
                                 55                 :                :  *   HeapTupleSatisfiesAny()
                                 56                 :                :  *        all tuples are visible
                                 57                 :                :  *
                                 58                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                 59                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 60                 :                :  *
                                 61                 :                :  * IDENTIFICATION
                                 62                 :                :  *    src/backend/access/heap/heapam_visibility.c
                                 63                 :                :  *
                                 64                 :                :  *-------------------------------------------------------------------------
                                 65                 :                :  */
                                 66                 :                : 
                                 67                 :                : #include "postgres.h"
                                 68                 :                : 
                                 69                 :                : #include "access/heapam.h"
                                 70                 :                : #include "access/htup_details.h"
                                 71                 :                : #include "access/multixact.h"
                                 72                 :                : #include "access/tableam.h"
                                 73                 :                : #include "access/transam.h"
                                 74                 :                : #include "access/xact.h"
                                 75                 :                : #include "access/xlog.h"
                                 76                 :                : #include "storage/bufmgr.h"
                                 77                 :                : #include "storage/procarray.h"
                                 78                 :                : #include "utils/builtins.h"
                                 79                 :                : #include "utils/snapmgr.h"
                                 80                 :                : 
                                 81                 :                : 
                                 82                 :                : /*
                                 83                 :                :  * SetHintBits()
                                 84                 :                :  *
                                 85                 :                :  * Set commit/abort hint bits on a tuple, if appropriate at this time.
                                 86                 :                :  *
                                 87                 :                :  * It is only safe to set a transaction-committed hint bit if we know the
                                 88                 :                :  * transaction's commit record is guaranteed to be flushed to disk before the
                                 89                 :                :  * buffer, or if the table is temporary or unlogged and will be obliterated by
                                 90                 :                :  * a crash anyway.  We cannot change the LSN of the page here, because we may
                                 91                 :                :  * hold only a share lock on the buffer, so we can only use the LSN to
                                 92                 :                :  * interlock this if the buffer's LSN already is newer than the commit LSN;
                                 93                 :                :  * otherwise we have to just refrain from setting the hint bit until some
                                 94                 :                :  * future re-examination of the tuple.
                                 95                 :                :  *
                                 96                 :                :  * We can always set hint bits when marking a transaction aborted.  (Some
                                 97                 :                :  * code in heapam.c relies on that!)
                                 98                 :                :  *
                                 99                 :                :  * Also, if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then
                                100                 :                :  * we can always set the hint bits, since pre-9.0 VACUUM FULL always used
                                101                 :                :  * synchronous commits and didn't move tuples that weren't previously
                                102                 :                :  * hinted.  (This is not known by this subroutine, but is applied by its
                                103                 :                :  * callers.)  Note: old-style VACUUM FULL is gone, but we have to keep this
                                104                 :                :  * module's support for MOVED_OFF/MOVED_IN flag bits for as long as we
                                105                 :                :  * support in-place update from pre-9.0 databases.
                                106                 :                :  *
                                107                 :                :  * Normal commits may be asynchronous, so for those we need to get the LSN
                                108                 :                :  * of the transaction and then check whether this is flushed.
                                109                 :                :  *
                                110                 :                :  * The caller should pass xid as the XID of the transaction to check, or
                                111                 :                :  * InvalidTransactionId if no check is needed.
                                112                 :                :  */
                                113                 :                : static inline void
 6598 tgl@sss.pgh.pa.us         114                 :CBC     9550097 : SetHintBits(HeapTupleHeader tuple, Buffer buffer,
                                115                 :                :             uint16 infomask, TransactionId xid)
                                116                 :                : {
 6611                           117         [ +  + ]:        9550097 :     if (TransactionIdIsValid(xid))
                                118                 :                :     {
                                119                 :                :         /* NB: xid must be known committed here! */
 6505 bruce@momjian.us          120                 :        9423867 :         XLogRecPtr  commitLSN = TransactionIdGetCommitLSN(xid);
                                121                 :                : 
 3491 andres@anarazel.de        122   [ +  +  +  +  :        9570712 :         if (BufferIsPermanent(buffer) && XLogNeedsFlush(commitLSN) &&
                                              +  + ]
                                123                 :         146845 :             BufferGetLSNAtomic(buffer) < commitLSN)
                                124                 :                :         {
                                125                 :                :             /* not flushed and no LSN interlock, so don't set hint */
                                126                 :         131907 :             return;
                                127                 :                :         }
                                128                 :                :     }
                                129                 :                : 
 6611 tgl@sss.pgh.pa.us         130                 :        9418190 :     tuple->t_infomask |= infomask;
 4464 jdavis@postgresql.or      131                 :        9418190 :     MarkBufferDirtyHint(buffer, true);
                                132                 :                : }
                                133                 :                : 
                                134                 :                : /*
                                135                 :                :  * HeapTupleSetHintBits --- exported version of SetHintBits()
                                136                 :                :  *
                                137                 :                :  * This must be separate because of C99's brain-dead notions about how to
                                138                 :                :  * implement inline functions.
                                139                 :                :  */
                                140                 :                : void
 6598 tgl@sss.pgh.pa.us         141                 :            182 : HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
                                142                 :                :                      uint16 infomask, TransactionId xid)
                                143                 :                : {
                                144                 :            182 :     SetHintBits(tuple, buffer, infomask, xid);
                                145                 :            182 : }
                                146                 :                : 
                                147                 :                : 
                                148                 :                : /*
                                149                 :                :  * HeapTupleSatisfiesSelf
                                150                 :                :  *      True iff heap tuple is valid "for itself".
                                151                 :                :  *
                                152                 :                :  * See SNAPSHOT_MVCC's definition for the intended behaviour.
                                153                 :                :  *
                                154                 :                :  * Note:
                                155                 :                :  *      Assumes heap tuple is valid.
                                156                 :                :  *
                                157                 :                :  * The satisfaction of "itself" requires the following:
                                158                 :                :  *
                                159                 :                :  * ((Xmin == my-transaction &&              the row was updated by the current transaction, and
                                160                 :                :  *      (Xmax is null                       it was not deleted
                                161                 :                :  *       [|| Xmax != my-transaction)])          [or it was deleted by another transaction]
                                162                 :                :  * ||
                                163                 :                :  *
                                164                 :                :  * (Xmin is committed &&                    the row was modified by a committed transaction, and
                                165                 :                :  *      (Xmax is null ||                    the row has not been deleted, or
                                166                 :                :  *          (Xmax != my-transaction &&          the row was deleted by another transaction
                                167                 :                :  *           Xmax is not committed)))           that has not been committed
                                168                 :                :  */
                                169                 :                : static bool
 4429 rhaas@postgresql.org      170                 :           2577 : HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                                171                 :                : {
                                172                 :           2577 :     HeapTupleHeader tuple = htup->t_data;
                                173                 :                : 
                                174         [ -  + ]:           2577 :     Assert(ItemPointerIsValid(&htup->t_self));
                                175         [ -  + ]:           2577 :     Assert(htup->t_tableOid != InvalidOid);
                                176                 :                : 
 4276                           177         [ +  + ]:           2577 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                178                 :                :     {
                                179         [ -  + ]:           2526 :         if (HeapTupleHeaderXminInvalid(tuple))
 9867 bruce@momjian.us          180                 :UBC           0 :             return false;
                                181                 :                : 
                                182                 :                :         /* Used by pre-9.0 binary upgrades */
 9659 vadim4o@yahoo.com         183         [ -  + ]:CBC        2526 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                184                 :                :         {
 8109 bruce@momjian.us          185                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                186                 :                : 
                                187         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9659 vadim4o@yahoo.com         188                 :              0 :                 return false;
 8109 bruce@momjian.us          189         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                190                 :                :             {
                                191         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                192                 :                :                 {
 6598 tgl@sss.pgh.pa.us         193                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                194                 :                :                                 InvalidTransactionId);
 8662                           195                 :              0 :                     return false;
                                196                 :                :                 }
 6598                           197                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                198                 :                :                             InvalidTransactionId);
                                199                 :                :             }
                                200                 :                :         }
                                201                 :                :         /* Used by pre-9.0 binary upgrades */
 9659 vadim4o@yahoo.com         202         [ -  + ]:CBC        2526 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                203                 :                :         {
 8109 bruce@momjian.us          204                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                205                 :                : 
                                206         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                207                 :                :             {
                                208         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8662 tgl@sss.pgh.pa.us         209                 :              0 :                     return false;
 8109 bruce@momjian.us          210         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us         211                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                212                 :                :                                 InvalidTransactionId);
                                213                 :                :                 else
                                214                 :                :                 {
                                215                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                216                 :                :                                 InvalidTransactionId);
 8662                           217                 :              0 :                     return false;
                                218                 :                :                 }
                                219                 :                :             }
                                220                 :                :         }
 4276 rhaas@postgresql.org      221         [ +  - ]:CBC        2526 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                222                 :                :         {
10170 vadim4o@yahoo.com         223         [ +  + ]:           2526 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
 9867 bruce@momjian.us          224                 :           2465 :                 return true;
                                225                 :                : 
 4483                           226         [ +  + ]:             61 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 7436 tgl@sss.pgh.pa.us         227                 :             10 :                 return true;
                                228                 :                : 
 4609 alvherre@alvh.no-ip.      229         [ -  + ]:             51 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                230                 :                :             {
                                231                 :                :                 TransactionId xmax;
                                232                 :                : 
 4609 alvherre@alvh.no-ip.      233                 :UBC           0 :                 xmax = HeapTupleGetUpdateXid(tuple);
                                234                 :                : 
                                235                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 4299                           236         [ #  # ]:              0 :                 Assert(TransactionIdIsValid(xmax));
                                237                 :                : 
                                238                 :                :                 /* updating subtransaction must have aborted */
 4609                           239         [ #  # ]:              0 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                                240                 :              0 :                     return true;
                                241                 :                :                 else
                                242                 :              0 :                     return false;
                                243                 :                :             }
                                244                 :                : 
 4609 alvherre@alvh.no-ip.      245         [ +  + ]:CBC          51 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                246                 :                :             {
                                247                 :                :                 /* deleting subtransaction must have aborted */
 6598 tgl@sss.pgh.pa.us         248                 :              9 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                249                 :                :                             InvalidTransactionId);
 7737                           250                 :              9 :                 return true;
                                251                 :                :             }
                                252                 :                : 
 9762 vadim4o@yahoo.com         253                 :             42 :             return false;
                                254                 :                :         }
 4276 rhaas@postgresql.org      255         [ #  # ]:UBC           0 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 9867 bruce@momjian.us          256                 :              0 :             return false;
 4276 rhaas@postgresql.org      257         [ #  # ]:              0 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6598 tgl@sss.pgh.pa.us         258                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                259                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                                260                 :                :         else
                                261                 :                :         {
                                262                 :                :             /* it must have aborted or crashed */
                                263                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                264                 :                :                         InvalidTransactionId);
 7427                           265                 :              0 :             return false;
                                266                 :                :         }
                                267                 :                :     }
                                268                 :                : 
                                269                 :                :     /* by here, the inserting transaction has committed */
                                270                 :                : 
10170 vadim4o@yahoo.com         271         [ +  - ]:CBC          51 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
 9867 bruce@momjian.us          272                 :             51 :         return true;
                                273                 :                : 
10170 vadim4o@yahoo.com         274         [ #  # ]:UBC           0 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                275                 :                :     {
 4609 alvherre@alvh.no-ip.      276         [ #  # ]:              0 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9762 vadim4o@yahoo.com         277                 :              0 :             return true;
 9601 bruce@momjian.us          278                 :              0 :         return false;           /* updated by other */
                                279                 :                :     }
                                280                 :                : 
 7436 tgl@sss.pgh.pa.us         281         [ #  # ]:              0 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                282                 :                :     {
                                283                 :                :         TransactionId xmax;
                                284                 :                : 
 4609 alvherre@alvh.no-ip.      285         [ #  # ]:              0 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                286                 :              0 :             return true;
                                287                 :                : 
                                288                 :              0 :         xmax = HeapTupleGetUpdateXid(tuple);
                                289                 :                : 
                                290                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 4299                           291         [ #  # ]:              0 :         Assert(TransactionIdIsValid(xmax));
                                292                 :                : 
 4609                           293         [ #  # ]:              0 :         if (TransactionIdIsCurrentTransactionId(xmax))
                                294                 :              0 :             return false;
                                295         [ #  # ]:              0 :         if (TransactionIdIsInProgress(xmax))
                                296                 :              0 :             return true;
                                297         [ #  # ]:              0 :         if (TransactionIdDidCommit(xmax))
                                298                 :              0 :             return false;
                                299                 :                :         /* it must have aborted or crashed */
 7436 tgl@sss.pgh.pa.us         300                 :              0 :         return true;
                                301                 :                :     }
                                302                 :                : 
 4609 alvherre@alvh.no-ip.      303         [ #  # ]:              0 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                304                 :                :     {
                                305         [ #  # ]:              0 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9762 vadim4o@yahoo.com         306                 :              0 :             return true;
 9867 bruce@momjian.us          307                 :              0 :         return false;
                                308                 :                :     }
                                309                 :                : 
 4609 alvherre@alvh.no-ip.      310         [ #  # ]:              0 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 7427 tgl@sss.pgh.pa.us         311                 :              0 :         return true;
                                312                 :                : 
 4609 alvherre@alvh.no-ip.      313         [ #  # ]:              0 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                314                 :                :     {
                                315                 :                :         /* it must have aborted or crashed */
 6598 tgl@sss.pgh.pa.us         316                 :              0 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                317                 :                :                     InvalidTransactionId);
 9867 bruce@momjian.us          318                 :              0 :         return true;
                                319                 :                :     }
                                320                 :                : 
                                321                 :                :     /* xmax transaction committed */
                                322                 :                : 
 4609 alvherre@alvh.no-ip.      323         [ #  # ]:              0 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                324                 :                :     {
 6598 tgl@sss.pgh.pa.us         325                 :              0 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                326                 :                :                     InvalidTransactionId);
 9762 vadim4o@yahoo.com         327                 :              0 :         return true;
                                328                 :                :     }
                                329                 :                : 
 6598 tgl@sss.pgh.pa.us         330                 :              0 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                331                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 9867 bruce@momjian.us          332                 :              0 :     return false;
                                333                 :                : }
                                334                 :                : 
                                335                 :                : /*
                                336                 :                :  * HeapTupleSatisfiesAny
                                337                 :                :  *      Dummy "satisfies" routine: any tuple satisfies SnapshotAny.
                                338                 :                :  */
                                339                 :                : static bool
 4429 rhaas@postgresql.org      340                 :CBC     7898740 : HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                                341                 :                : {
 6740 tgl@sss.pgh.pa.us         342                 :        7898740 :     return true;
                                343                 :                : }
                                344                 :                : 
                                345                 :                : /*
                                346                 :                :  * HeapTupleSatisfiesToast
                                347                 :                :  *      True iff heap tuple is valid as a TOAST row.
                                348                 :                :  *
                                349                 :                :  * See SNAPSHOT_TOAST's definition for the intended behaviour.
                                350                 :                :  *
                                351                 :                :  * This is a simplified version that only checks for VACUUM moving conditions.
                                352                 :                :  * It's appropriate for TOAST usage because TOAST really doesn't want to do
                                353                 :                :  * its own time qual checks; if you can see the main table row that contains
                                354                 :                :  * a TOAST reference, you should be able to see the TOASTed value.  However,
                                355                 :                :  * vacuuming a TOAST table is independent of the main table, and in case such
                                356                 :                :  * a vacuum fails partway through, we'd better do this much checking.
                                357                 :                :  *
                                358                 :                :  * Among other things, this means you can't do UPDATEs of rows in a TOAST
                                359                 :                :  * table.
                                360                 :                :  */
                                361                 :                : static bool
 4429 rhaas@postgresql.org      362                 :          79934 : HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
                                363                 :                :                         Buffer buffer)
                                364                 :                : {
                                365                 :          79934 :     HeapTupleHeader tuple = htup->t_data;
                                366                 :                : 
                                367         [ -  + ]:          79934 :     Assert(ItemPointerIsValid(&htup->t_self));
                                368         [ -  + ]:          79934 :     Assert(htup->t_tableOid != InvalidOid);
                                369                 :                : 
 4276                           370         [ +  + ]:          79934 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                371                 :                :     {
                                372         [ -  + ]:          62548 :         if (HeapTupleHeaderXminInvalid(tuple))
 8634 tgl@sss.pgh.pa.us         373                 :UBC           0 :             return false;
                                374                 :                : 
                                375                 :                :         /* Used by pre-9.0 binary upgrades */
 8634 tgl@sss.pgh.pa.us         376         [ -  + ]:CBC       62548 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                377                 :                :         {
 8109 bruce@momjian.us          378                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                379                 :                : 
                                380         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8634 tgl@sss.pgh.pa.us         381                 :              0 :                 return false;
 8109 bruce@momjian.us          382         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                383                 :                :             {
                                384         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                385                 :                :                 {
 6598 tgl@sss.pgh.pa.us         386                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                387                 :                :                                 InvalidTransactionId);
 8634                           388                 :              0 :                     return false;
                                389                 :                :                 }
 6598                           390                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                391                 :                :                             InvalidTransactionId);
                                392                 :                :             }
                                393                 :                :         }
                                394                 :                :         /* Used by pre-9.0 binary upgrades */
 8634 tgl@sss.pgh.pa.us         395         [ -  + ]:CBC       62548 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                396                 :                :         {
 8109 bruce@momjian.us          397                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                398                 :                : 
                                399         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                400                 :                :             {
                                401         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8634 tgl@sss.pgh.pa.us         402                 :              0 :                     return false;
 8109 bruce@momjian.us          403         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us         404                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                405                 :                :                                 InvalidTransactionId);
                                406                 :                :                 else
                                407                 :                :                 {
                                408                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                409                 :                :                                 InvalidTransactionId);
 8634                           410                 :              0 :                     return false;
                                411                 :                :                 }
                                412                 :                :             }
                                413                 :                :         }
                                414                 :                : 
                                415                 :                :         /*
                                416                 :                :          * An invalid Xmin can be left behind by a speculative insertion that
                                417                 :                :          * is canceled by super-deleting the tuple.  This also applies to
                                418                 :                :          * TOAST tuples created during speculative insertion.
                                419                 :                :          */
 3774 andres@anarazel.de        420         [ -  + ]:CBC       62548 :         else if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple)))
 3774 andres@anarazel.de        421                 :UBC           0 :             return false;
                                422                 :                :     }
                                423                 :                : 
                                424                 :                :     /* otherwise assume the tuple is valid for TOAST. */
 8634 tgl@sss.pgh.pa.us         425                 :CBC       79934 :     return true;
                                426                 :                : }
                                427                 :                : 
                                428                 :                : /*
                                429                 :                :  * HeapTupleSatisfiesUpdate
                                430                 :                :  *
                                431                 :                :  *  This function returns a more detailed result code than most of the
                                432                 :                :  *  functions in this file, since UPDATE needs to know more than "is it
                                433                 :                :  *  visible?".  It also allows for user-supplied CommandId rather than
                                434                 :                :  *  relying on CurrentCommandId.
                                435                 :                :  *
                                436                 :                :  *  The possible return codes are:
                                437                 :                :  *
                                438                 :                :  *  TM_Invisible: the tuple didn't exist at all when the scan started, e.g. it
                                439                 :                :  *  was created by a later CommandId.
                                440                 :                :  *
                                441                 :                :  *  TM_Ok: The tuple is valid and visible, so it may be updated.
                                442                 :                :  *
                                443                 :                :  *  TM_SelfModified: The tuple was updated by the current transaction, after
                                444                 :                :  *  the current scan started.
                                445                 :                :  *
                                446                 :                :  *  TM_Updated: The tuple was updated by a committed transaction (including
                                447                 :                :  *  the case where the tuple was moved into a different partition).
                                448                 :                :  *
                                449                 :                :  *  TM_Deleted: The tuple was deleted by a committed transaction.
                                450                 :                :  *
                                451                 :                :  *  TM_BeingModified: The tuple is being updated by an in-progress transaction
                                452                 :                :  *  other than the current transaction.  (Note: this includes the case where
                                453                 :                :  *  the tuple is share-locked by a MultiXact, even if the MultiXact includes
                                454                 :                :  *  the current transaction.  Callers that want to distinguish that case must
                                455                 :                :  *  test for it themselves.)
                                456                 :                :  */
                                457                 :                : TM_Result
 4429 rhaas@postgresql.org      458                 :        1897267 : HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
                                459                 :                :                          Buffer buffer)
                                460                 :                : {
                                461                 :        1897267 :     HeapTupleHeader tuple = htup->t_data;
                                462                 :                : 
                                463         [ -  + ]:        1897267 :     Assert(ItemPointerIsValid(&htup->t_self));
                                464         [ -  + ]:        1897267 :     Assert(htup->t_tableOid != InvalidOid);
                                465                 :                : 
 4276                           466         [ +  + ]:        1897267 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                467                 :                :     {
                                468         [ -  + ]:         241622 :         if (HeapTupleHeaderXminInvalid(tuple))
 2359 andres@anarazel.de        469                 :UBC           0 :             return TM_Invisible;
                                470                 :                : 
                                471                 :                :         /* Used by pre-9.0 binary upgrades */
 8662 tgl@sss.pgh.pa.us         472         [ -  + ]:CBC      241622 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                473                 :                :         {
 8109 bruce@momjian.us          474                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                475                 :                : 
                                476         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 2359 andres@anarazel.de        477                 :              0 :                 return TM_Invisible;
 8109 bruce@momjian.us          478         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                479                 :                :             {
                                480         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                481                 :                :                 {
 6598 tgl@sss.pgh.pa.us         482                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                483                 :                :                                 InvalidTransactionId);
 2359 andres@anarazel.de        484                 :              0 :                     return TM_Invisible;
                                485                 :                :                 }
 6598 tgl@sss.pgh.pa.us         486                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                487                 :                :                             InvalidTransactionId);
                                488                 :                :             }
                                489                 :                :         }
                                490                 :                :         /* Used by pre-9.0 binary upgrades */
 8662 tgl@sss.pgh.pa.us         491         [ -  + ]:CBC      241622 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                492                 :                :         {
 8109 bruce@momjian.us          493                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                494                 :                : 
                                495         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                496                 :                :             {
                                497         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 2359 andres@anarazel.de        498                 :              0 :                     return TM_Invisible;
 8109 bruce@momjian.us          499         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us         500                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                501                 :                :                                 InvalidTransactionId);
                                502                 :                :                 else
                                503                 :                :                 {
                                504                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                505                 :                :                                 InvalidTransactionId);
 2359 andres@anarazel.de        506                 :              0 :                     return TM_Invisible;
                                507                 :                :                 }
                                508                 :                :             }
                                509                 :                :         }
 4276 rhaas@postgresql.org      510         [ +  + ]:CBC      241622 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                511                 :                :         {
 8484 bruce@momjian.us          512         [ +  + ]:         238486 :             if (HeapTupleHeaderGetCmin(tuple) >= curcid)
 2359 andres@anarazel.de        513                 :             12 :                 return TM_Invisible;    /* inserted after scan started */
                                514                 :                : 
 8403 bruce@momjian.us          515         [ +  + ]:         238474 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
 2359 andres@anarazel.de        516                 :         198264 :                 return TM_Ok;
                                517                 :                : 
 4280 alvherre@alvh.no-ip.      518         [ +  + ]:          40210 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                519                 :                :             {
                                520                 :                :                 TransactionId xmax;
                                521                 :                : 
                                522                 :          40200 :                 xmax = HeapTupleHeaderGetRawXmax(tuple);
                                523                 :                : 
                                524                 :                :                 /*
                                525                 :                :                  * Careful here: even though this tuple was created by our own
                                526                 :                :                  * transaction, it might be locked by other transactions, if
                                527                 :                :                  * the original version was key-share locked when we updated
                                528                 :                :                  * it.
                                529                 :                :                  */
                                530                 :                : 
                                531         [ +  + ]:          40200 :                 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                532                 :                :                 {
 3802                           533         [ +  - ]:             31 :                     if (MultiXactIdIsRunning(xmax, true))
 2359 andres@anarazel.de        534                 :             31 :                         return TM_BeingModified;
                                535                 :                :                     else
 2359 andres@anarazel.de        536                 :UBC           0 :                         return TM_Ok;
                                537                 :                :                 }
                                538                 :                : 
                                539                 :                :                 /*
                                540                 :                :                  * If the locker is gone, then there is nothing of interest
                                541                 :                :                  * left in this Xmax; otherwise, report the tuple as
                                542                 :                :                  * locked/updated.
                                543                 :                :                  */
 4280 alvherre@alvh.no-ip.      544         [ -  + ]:CBC       40169 :                 if (!TransactionIdIsInProgress(xmax))
 2359 andres@anarazel.de        545                 :UBC           0 :                     return TM_Ok;
 2359 andres@anarazel.de        546                 :CBC       40169 :                 return TM_BeingModified;
                                547                 :                :             }
                                548                 :                : 
 4609 alvherre@alvh.no-ip.      549         [ +  + ]:             10 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                550                 :                :             {
                                551                 :                :                 TransactionId xmax;
                                552                 :                : 
                                553                 :              7 :                 xmax = HeapTupleGetUpdateXid(tuple);
                                554                 :                : 
                                555                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 4299                           556         [ -  + ]:              7 :                 Assert(TransactionIdIsValid(xmax));
                                557                 :                : 
                                558                 :                :                 /* deleting subtransaction must have aborted */
 4609                           559         [ +  - ]:              7 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                                560                 :                :                 {
 3802                           561         [ +  - ]:              7 :                     if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
                                562                 :                :                                              false))
 2359 andres@anarazel.de        563                 :              7 :                         return TM_BeingModified;
 2359 andres@anarazel.de        564                 :UBC           0 :                     return TM_Ok;
                                565                 :                :                 }
                                566                 :                :                 else
                                567                 :                :                 {
 4609 alvherre@alvh.no-ip.      568         [ #  # ]:              0 :                     if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 2359 andres@anarazel.de        569                 :              0 :                         return TM_SelfModified; /* updated after scan started */
                                570                 :                :                     else
                                571                 :              0 :                         return TM_Invisible;    /* updated before scan started */
                                572                 :                :                 }
                                573                 :                :             }
                                574                 :                : 
 4609 alvherre@alvh.no-ip.      575         [ -  + ]:CBC           3 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                576                 :                :             {
                                577                 :                :                 /* deleting subtransaction must have aborted */
 6598 tgl@sss.pgh.pa.us         578                 :UBC           0 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                579                 :                :                             InvalidTransactionId);
 2359 andres@anarazel.de        580                 :              0 :                 return TM_Ok;
                                581                 :                :             }
                                582                 :                : 
 8484 bruce@momjian.us          583         [ +  - ]:CBC           3 :             if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 2359 andres@anarazel.de        584                 :              3 :                 return TM_SelfModified; /* updated after scan started */
                                585                 :                :             else
 2359 andres@anarazel.de        586                 :UBC           0 :                 return TM_Invisible;    /* updated before scan started */
                                587                 :                :         }
 4276 rhaas@postgresql.org      588         [ -  + ]:CBC        3136 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 2359 andres@anarazel.de        589                 :UBC           0 :             return TM_Invisible;
 4276 rhaas@postgresql.org      590         [ +  - ]:CBC        3136 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6598 tgl@sss.pgh.pa.us         591                 :           3136 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                592                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                                593                 :                :         else
                                594                 :                :         {
                                595                 :                :             /* it must have aborted or crashed */
 6598 tgl@sss.pgh.pa.us         596                 :UBC           0 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                597                 :                :                         InvalidTransactionId);
 2359 andres@anarazel.de        598                 :              0 :             return TM_Invisible;
                                599                 :                :         }
                                600                 :                :     }
                                601                 :                : 
                                602                 :                :     /* by here, the inserting transaction has committed */
                                603                 :                : 
 8403 bruce@momjian.us          604         [ +  + ]:CBC     1658781 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
 2359 andres@anarazel.de        605                 :        1610480 :         return TM_Ok;
                                606                 :                : 
 8662 tgl@sss.pgh.pa.us         607         [ +  + ]:          48301 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                608                 :                :     {
 4609 alvherre@alvh.no-ip.      609         [ -  + ]:            148 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 2359 andres@anarazel.de        610                 :UBC           0 :             return TM_Ok;
 1657 alvherre@alvh.no-ip.      611         [ +  - ]:CBC         148 :         if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 2359 andres@anarazel.de        612                 :            148 :             return TM_Updated;  /* updated by other */
                                613                 :                :         else
 2359 andres@anarazel.de        614                 :UBC           0 :             return TM_Deleted;  /* deleted by other */
                                615                 :                :     }
                                616                 :                : 
 7436 tgl@sss.pgh.pa.us         617         [ +  + ]:CBC       48153 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                618                 :                :     {
                                619                 :                :         TransactionId xmax;
                                620                 :                : 
 3361 alvherre@alvh.no-ip.      621         [ -  + ]:            613 :         if (HEAP_LOCKED_UPGRADED(tuple->t_infomask))
 2359 andres@anarazel.de        622                 :UBC           0 :             return TM_Ok;
                                623                 :                : 
 4609 alvherre@alvh.no-ip.      624         [ +  + ]:CBC         613 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                625                 :                :         {
 3361                           626         [ +  + ]:            577 :             if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), true))
 2359 andres@anarazel.de        627                 :            111 :                 return TM_BeingModified;
                                628                 :                : 
 4609 alvherre@alvh.no-ip.      629                 :            466 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
 2359 andres@anarazel.de        630                 :            466 :             return TM_Ok;
                                631                 :                :         }
                                632                 :                : 
 4609 alvherre@alvh.no-ip.      633                 :             36 :         xmax = HeapTupleGetUpdateXid(tuple);
 4057                           634         [ -  + ]:             36 :         if (!TransactionIdIsValid(xmax))
                                635                 :                :         {
 4057 alvherre@alvh.no-ip.      636         [ #  # ]:UBC           0 :             if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 2359 andres@anarazel.de        637                 :              0 :                 return TM_BeingModified;
                                638                 :                :         }
                                639                 :                : 
                                640                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 4299 alvherre@alvh.no-ip.      641         [ -  + ]:CBC          36 :         Assert(TransactionIdIsValid(xmax));
                                642                 :                : 
 4609                           643         [ -  + ]:             36 :         if (TransactionIdIsCurrentTransactionId(xmax))
                                644                 :                :         {
 4609 alvherre@alvh.no-ip.      645         [ #  # ]:UBC           0 :             if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 2359 andres@anarazel.de        646                 :              0 :                 return TM_SelfModified; /* updated after scan started */
                                647                 :                :             else
                                648                 :              0 :                 return TM_Invisible;    /* updated before scan started */
                                649                 :                :         }
                                650                 :                : 
 4057 alvherre@alvh.no-ip.      651         [ +  + ]:CBC          36 :         if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 2359 andres@anarazel.de        652                 :             32 :             return TM_BeingModified;
                                653                 :                : 
 4609 alvherre@alvh.no-ip.      654         [ +  + ]:              4 :         if (TransactionIdDidCommit(xmax))
                                655                 :                :         {
 1657                           656         [ -  + ]:              1 :             if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 2359 andres@anarazel.de        657                 :UBC           0 :                 return TM_Updated;
                                658                 :                :             else
 2359 andres@anarazel.de        659                 :CBC           1 :                 return TM_Deleted;
                                660                 :                :         }
                                661                 :                : 
                                662                 :                :         /*
                                663                 :                :          * By here, the update in the Xmax is either aborted or crashed, but
                                664                 :                :          * what about the other members?
                                665                 :                :          */
                                666                 :                : 
 4057 alvherre@alvh.no-ip.      667         [ +  - ]:              3 :         if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
                                668                 :                :         {
                                669                 :                :             /*
                                670                 :                :              * There's no member, even just a locker, alive anymore, so we can
                                671                 :                :              * mark the Xmax as invalid.
                                672                 :                :              */
 4299                           673                 :              3 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                674                 :                :                         InvalidTransactionId);
 2359 andres@anarazel.de        675                 :              3 :             return TM_Ok;
                                676                 :                :         }
                                677                 :                :         else
                                678                 :                :         {
                                679                 :                :             /* There are lockers running */
 2359 andres@anarazel.de        680                 :UBC           0 :             return TM_BeingModified;
                                681                 :                :         }
                                682                 :                :     }
                                683                 :                : 
 4609 alvherre@alvh.no-ip.      684         [ +  + ]:CBC       47540 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                685                 :                :     {
                                686         [ +  + ]:          42741 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 2359 andres@anarazel.de        687                 :          42665 :             return TM_BeingModified;
 8484 bruce@momjian.us          688         [ +  - ]:             76 :         if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 2359 andres@anarazel.de        689                 :             76 :             return TM_SelfModified; /* updated after scan started */
                                690                 :                :         else
 2359 andres@anarazel.de        691                 :UBC           0 :             return TM_Invisible;    /* updated before scan started */
                                692                 :                :     }
                                693                 :                : 
 4609 alvherre@alvh.no-ip.      694         [ +  + ]:CBC        4799 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 2359 andres@anarazel.de        695                 :           1265 :         return TM_BeingModified;
                                696                 :                : 
 4609 alvherre@alvh.no-ip.      697         [ +  + ]:           3534 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                698                 :                :     {
                                699                 :                :         /* it must have aborted or crashed */
 6598 tgl@sss.pgh.pa.us         700                 :            194 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                701                 :                :                     InvalidTransactionId);
 2359 andres@anarazel.de        702                 :            194 :         return TM_Ok;
                                703                 :                :     }
                                704                 :                : 
                                705                 :                :     /* xmax transaction committed */
                                706                 :                : 
 4609 alvherre@alvh.no-ip.      707         [ +  + ]:           3340 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                708                 :                :     {
 6598 tgl@sss.pgh.pa.us         709                 :           3276 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                710                 :                :                     InvalidTransactionId);
 2359 andres@anarazel.de        711                 :           3276 :         return TM_Ok;
                                712                 :                :     }
                                713                 :                : 
 6598 tgl@sss.pgh.pa.us         714                 :             64 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                715                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 1657 alvherre@alvh.no-ip.      716         [ +  - ]:             64 :     if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 2359 andres@anarazel.de        717                 :             64 :         return TM_Updated;      /* updated by other */
                                718                 :                :     else
 2359 andres@anarazel.de        719                 :UBC           0 :         return TM_Deleted;      /* deleted by other */
                                720                 :                : }
                                721                 :                : 
                                722                 :                : /*
                                723                 :                :  * HeapTupleSatisfiesDirty
                                724                 :                :  *      True iff heap tuple is valid including effects of open transactions.
                                725                 :                :  *
                                726                 :                :  * See SNAPSHOT_DIRTY's definition for the intended behaviour.
                                727                 :                :  *
                                728                 :                :  * This is essentially like HeapTupleSatisfiesSelf as far as effects of
                                729                 :                :  * the current transaction and committed/aborted xacts are concerned.
                                730                 :                :  * However, we also include the effects of other xacts still in progress.
                                731                 :                :  *
                                732                 :                :  * A special hack is that the passed-in snapshot struct is used as an
                                733                 :                :  * output argument to return the xids of concurrent xacts that affected the
                                734                 :                :  * tuple.  snapshot->xmin is set to the tuple's xmin if that is another
                                735                 :                :  * transaction that's still in progress; or to InvalidTransactionId if the
                                736                 :                :  * tuple's xmin is committed good, committed dead, or my own xact.
                                737                 :                :  * Similarly for snapshot->xmax and the tuple's xmax.  If the tuple was
                                738                 :                :  * inserted speculatively, meaning that the inserter might still back down
                                739                 :                :  * on the insertion without aborting the whole transaction, the associated
                                740                 :                :  * token is also returned in snapshot->speculativeToken.
                                741                 :                :  */
                                742                 :                : static bool
 4429 rhaas@postgresql.org      743                 :CBC     5925929 : HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
                                744                 :                :                         Buffer buffer)
                                745                 :                : {
                                746                 :        5925929 :     HeapTupleHeader tuple = htup->t_data;
                                747                 :                : 
                                748         [ -  + ]:        5925929 :     Assert(ItemPointerIsValid(&htup->t_self));
                                749         [ -  + ]:        5925929 :     Assert(htup->t_tableOid != InvalidOid);
                                750                 :                : 
 6740 tgl@sss.pgh.pa.us         751                 :        5925929 :     snapshot->xmin = snapshot->xmax = InvalidTransactionId;
 3774 andres@anarazel.de        752                 :        5925929 :     snapshot->speculativeToken = 0;
                                753                 :                : 
 4276 rhaas@postgresql.org      754         [ +  + ]:        5925929 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                755                 :                :     {
                                756         [ +  + ]:        5582907 :         if (HeapTupleHeaderXminInvalid(tuple))
 9762 vadim4o@yahoo.com         757                 :            420 :             return false;
                                758                 :                : 
                                759                 :                :         /* Used by pre-9.0 binary upgrades */
 9659                           760         [ -  + ]:        5582487 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                761                 :                :         {
 8109 bruce@momjian.us          762                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                763                 :                : 
                                764         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9651 vadim4o@yahoo.com         765                 :              0 :                 return false;
 8109 bruce@momjian.us          766         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                767                 :                :             {
                                768         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                769                 :                :                 {
 6598 tgl@sss.pgh.pa.us         770                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                771                 :                :                                 InvalidTransactionId);
 8662                           772                 :              0 :                     return false;
                                773                 :                :                 }
 6598                           774                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                775                 :                :                             InvalidTransactionId);
                                776                 :                :             }
                                777                 :                :         }
                                778                 :                :         /* Used by pre-9.0 binary upgrades */
 9659 vadim4o@yahoo.com         779         [ -  + ]:CBC     5582487 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                780                 :                :         {
 8109 bruce@momjian.us          781                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                782                 :                : 
                                783         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                784                 :                :             {
                                785         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8662 tgl@sss.pgh.pa.us         786                 :              0 :                     return false;
 8109 bruce@momjian.us          787         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us         788                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                789                 :                :                                 InvalidTransactionId);
                                790                 :                :                 else
                                791                 :                :                 {
                                792                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                793                 :                :                                 InvalidTransactionId);
 9644 vadim4o@yahoo.com         794                 :              0 :                     return false;
                                795                 :                :                 }
                                796                 :                :             }
                                797                 :                :         }
 4276 rhaas@postgresql.org      798         [ +  + ]:CBC     5582487 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                799                 :                :         {
 9762 vadim4o@yahoo.com         800         [ +  + ]:        5556954 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                                801                 :          30988 :                 return true;
                                802                 :                : 
 4483 bruce@momjian.us          803         [ +  + ]:        5525966 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 7436 tgl@sss.pgh.pa.us         804                 :           5040 :                 return true;
                                805                 :                : 
 4609 alvherre@alvh.no-ip.      806         [ +  + ]:        5520926 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                807                 :                :             {
                                808                 :                :                 TransactionId xmax;
                                809                 :                : 
                                810                 :             16 :                 xmax = HeapTupleGetUpdateXid(tuple);
                                811                 :                : 
                                812                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 4299                           813         [ -  + ]:             16 :                 Assert(TransactionIdIsValid(xmax));
                                814                 :                : 
                                815                 :                :                 /* updating subtransaction must have aborted */
 4609                           816         [ -  + ]:             16 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
 4609 alvherre@alvh.no-ip.      817                 :UBC           0 :                     return true;
                                818                 :                :                 else
 4609 alvherre@alvh.no-ip.      819                 :CBC          16 :                     return false;
                                820                 :                :             }
                                821                 :                : 
                                822         [ -  + ]:        5520910 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                823                 :                :             {
                                824                 :                :                 /* deleting subtransaction must have aborted */
 6598 tgl@sss.pgh.pa.us         825                 :UBC           0 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                826                 :                :                             InvalidTransactionId);
 7737                           827                 :              0 :                 return true;
                                828                 :                :             }
                                829                 :                : 
 9762 vadim4o@yahoo.com         830                 :CBC     5520910 :             return false;
                                831                 :                :         }
 4276 rhaas@postgresql.org      832         [ +  + ]:          25533 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
                                833                 :                :         {
                                834                 :                :             /*
                                835                 :                :              * Return the speculative token to caller.  Caller can worry about
                                836                 :                :              * xmax, since it requires a conclusively locked row version, and
                                837                 :                :              * a concurrent update to this tuple is a conflict of its
                                838                 :                :              * purposes.
                                839                 :                :              */
 3774 andres@anarazel.de        840         [ +  + ]:             82 :             if (HeapTupleHeaderIsSpeculative(tuple))
                                841                 :                :             {
                                842                 :              2 :                 snapshot->speculativeToken =
                                843                 :              2 :                     HeapTupleHeaderGetSpeculativeToken(tuple);
                                844                 :                : 
                                845         [ -  + ]:              2 :                 Assert(snapshot->speculativeToken != 0);
                                846                 :                :             }
                                847                 :                : 
 4276 rhaas@postgresql.org      848                 :             82 :             snapshot->xmin = HeapTupleHeaderGetRawXmin(tuple);
                                849                 :                :             /* XXX shouldn't we fall through to look at xmax? */
 9601 bruce@momjian.us          850                 :             82 :             return true;        /* in insertion by other */
                                851                 :                :         }
 4276 rhaas@postgresql.org      852         [ +  + ]:          25451 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6598 tgl@sss.pgh.pa.us         853                 :          25041 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                854                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                                855                 :                :         else
                                856                 :                :         {
                                857                 :                :             /* it must have aborted or crashed */
                                858                 :            410 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                859                 :                :                         InvalidTransactionId);
 7427                           860                 :            410 :             return false;
                                861                 :                :         }
                                862                 :                :     }
                                863                 :                : 
                                864                 :                :     /* by here, the inserting transaction has committed */
                                865                 :                : 
 9762 vadim4o@yahoo.com         866         [ +  + ]:         368063 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
                                867                 :         132942 :         return true;
                                868                 :                : 
                                869         [ +  + ]:         235121 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                870                 :                :     {
 4609 alvherre@alvh.no-ip.      871         [ -  + ]:          81208 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9762 vadim4o@yahoo.com         872                 :UBC           0 :             return true;
 9601 bruce@momjian.us          873                 :CBC       81208 :         return false;           /* updated by other */
                                874                 :                :     }
                                875                 :                : 
 7436 tgl@sss.pgh.pa.us         876         [ +  + ]:         153913 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                877                 :                :     {
                                878                 :                :         TransactionId xmax;
                                879                 :                : 
 4609 alvherre@alvh.no-ip.      880         [ +  + ]:             30 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                881                 :             13 :             return true;
                                882                 :                : 
                                883                 :             17 :         xmax = HeapTupleGetUpdateXid(tuple);
                                884                 :                : 
                                885                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 4299                           886         [ -  + ]:             17 :         Assert(TransactionIdIsValid(xmax));
                                887                 :                : 
 4609                           888         [ +  + ]:             17 :         if (TransactionIdIsCurrentTransactionId(xmax))
                                889                 :              1 :             return false;
                                890         [ -  + ]:             16 :         if (TransactionIdIsInProgress(xmax))
                                891                 :                :         {
 4609 alvherre@alvh.no-ip.      892                 :UBC           0 :             snapshot->xmax = xmax;
                                893                 :              0 :             return true;
                                894                 :                :         }
 4609 alvherre@alvh.no-ip.      895         [ +  - ]:CBC          16 :         if (TransactionIdDidCommit(xmax))
                                896                 :             16 :             return false;
                                897                 :                :         /* it must have aborted or crashed */
 7436 tgl@sss.pgh.pa.us         898                 :UBC           0 :         return true;
                                899                 :                :     }
                                900                 :                : 
 4609 alvherre@alvh.no-ip.      901         [ +  + ]:CBC      153883 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                902                 :                :     {
                                903         [ +  + ]:         114999 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9196 inoue@tpf.co.jp           904                 :             36 :             return true;
 9762 vadim4o@yahoo.com         905                 :         114963 :         return false;
                                906                 :                :     }
                                907                 :                : 
 4609 alvherre@alvh.no-ip.      908         [ +  + ]:          38884 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
                                909                 :                :     {
 4418                           910         [ +  + ]:             14 :         if (!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                911                 :             12 :             snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
 7427 tgl@sss.pgh.pa.us         912                 :             14 :         return true;
                                913                 :                :     }
                                914                 :                : 
 4609 alvherre@alvh.no-ip.      915         [ +  + ]:          38870 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                916                 :                :     {
                                917                 :                :         /* it must have aborted or crashed */
 6598 tgl@sss.pgh.pa.us         918                 :             28 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                919                 :                :                     InvalidTransactionId);
 7427                           920                 :             28 :         return true;
                                921                 :                :     }
                                922                 :                : 
                                923                 :                :     /* xmax transaction committed */
                                924                 :                : 
 4609 alvherre@alvh.no-ip.      925         [ +  + ]:          38842 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                926                 :                :     {
 6598 tgl@sss.pgh.pa.us         927                 :          13554 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                928                 :                :                     InvalidTransactionId);
 9762 vadim4o@yahoo.com         929                 :          13554 :         return true;
                                930                 :                :     }
                                931                 :                : 
 6598 tgl@sss.pgh.pa.us         932                 :          25288 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                933                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 9601 bruce@momjian.us          934                 :          25288 :     return false;               /* updated by other */
                                935                 :                : }
                                936                 :                : 
                                937                 :                : /*
                                938                 :                :  * HeapTupleSatisfiesMVCC
                                939                 :                :  *      True iff heap tuple is valid for the given MVCC snapshot.
                                940                 :                :  *
                                941                 :                :  * See SNAPSHOT_MVCC's definition for the intended behaviour.
                                942                 :                :  *
                                943                 :                :  * Notice that here, we will not update the tuple status hint bits if the
                                944                 :                :  * inserting/deleting transaction is still running according to our snapshot,
                                945                 :                :  * even if in reality it's committed or aborted by now.  This is intentional.
                                946                 :                :  * Checking the true transaction state would require access to high-traffic
                                947                 :                :  * shared data structures, creating contention we'd rather do without, and it
                                948                 :                :  * would not change the result of our visibility check anyway.  The hint bits
                                949                 :                :  * will be updated by the first visitor that has a snapshot new enough to see
                                950                 :                :  * the inserting/deleting transaction as done.  In the meantime, the cost of
                                951                 :                :  * leaving the hint bits unset is basically that each HeapTupleSatisfiesMVCC
                                952                 :                :  * call will need to run TransactionIdIsCurrentTransactionId in addition to
                                953                 :                :  * XidInMVCCSnapshot (but it would have to do the latter anyway).  In the old
                                954                 :                :  * coding where we tried to set the hint bits as soon as possible, we instead
                                955                 :                :  * did TransactionIdIsInProgress in each call --- to no avail, as long as the
                                956                 :                :  * inserting/deleting transaction was still running --- which was more cycles
                                957                 :                :  * and more contention on ProcArrayLock.
                                958                 :                :  */
                                959                 :                : static bool
 4429 rhaas@postgresql.org      960                 :       78865771 : HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                                961                 :                :                        Buffer buffer)
                                962                 :                : {
                                963                 :       78865771 :     HeapTupleHeader tuple = htup->t_data;
                                964                 :                : 
                                965                 :                :     /*
                                966                 :                :      * Assert that the caller has registered the snapshot.  This function
                                967                 :                :      * doesn't care about the registration as such, but in general you
                                968                 :                :      * shouldn't try to use a snapshot without registration because it might
                                969                 :                :      * get invalidated while it's still in use, and this is a convenient place
                                970                 :                :      * to check for that.
                                971                 :                :      */
  179 heikki.linnakangas@i      972   [ +  +  -  + ]:       78865771 :     Assert(snapshot->regd_count > 0 || snapshot->active_count > 0);
                                973                 :                : 
 4429 rhaas@postgresql.org      974         [ -  + ]:       78865771 :     Assert(ItemPointerIsValid(&htup->t_self));
                                975         [ -  + ]:       78865771 :     Assert(htup->t_tableOid != InvalidOid);
                                976                 :                : 
 4276                           977         [ +  + ]:       78865771 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                978                 :                :     {
                                979         [ +  + ]:       15104260 :         if (HeapTupleHeaderXminInvalid(tuple))
 9761 vadim4o@yahoo.com         980                 :         177356 :             return false;
                                981                 :                : 
                                982                 :                :         /* Used by pre-9.0 binary upgrades */
 9659                           983         [ -  + ]:       14926904 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                984                 :                :         {
 8109 bruce@momjian.us          985                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                986                 :                : 
                                987         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9659 vadim4o@yahoo.com         988                 :              0 :                 return false;
 3664 tgl@sss.pgh.pa.us         989         [ #  # ]:              0 :             if (!XidInMVCCSnapshot(xvac, snapshot))
                                990                 :                :             {
 8109 bruce@momjian.us          991         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                992                 :                :                 {
 6598 tgl@sss.pgh.pa.us         993                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                994                 :                :                                 InvalidTransactionId);
 8662                           995                 :              0 :                     return false;
                                996                 :                :                 }
 6598                           997                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                998                 :                :                             InvalidTransactionId);
                                999                 :                :             }
                               1000                 :                :         }
                               1001                 :                :         /* Used by pre-9.0 binary upgrades */
 9659 vadim4o@yahoo.com        1002         [ -  + ]:CBC    14926904 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                               1003                 :                :         {
 8109 bruce@momjian.us         1004                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                               1005                 :                : 
                               1006         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                               1007                 :                :             {
 3664 tgl@sss.pgh.pa.us        1008         [ #  # ]:              0 :                 if (XidInMVCCSnapshot(xvac, snapshot))
 8662                          1009                 :              0 :                     return false;
 8109 bruce@momjian.us         1010         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us        1011                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1012                 :                :                                 InvalidTransactionId);
                               1013                 :                :                 else
                               1014                 :                :                 {
                               1015                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1016                 :                :                                 InvalidTransactionId);
 8662                          1017                 :              0 :                     return false;
                               1018                 :                :                 }
                               1019                 :                :             }
                               1020                 :                :         }
 4276 rhaas@postgresql.org     1021         [ +  + ]:CBC    14926904 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                               1022                 :                :         {
 8484 bruce@momjian.us         1023         [ +  + ]:       10990694 :             if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
 9761 vadim4o@yahoo.com        1024                 :           6557 :                 return false;   /* inserted after scan started */
                               1025                 :                : 
                               1026         [ +  + ]:       10984137 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                               1027                 :        8049098 :                 return true;
                               1028                 :                : 
 4483 bruce@momjian.us         1029         [ +  + ]:        2935039 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 7436 tgl@sss.pgh.pa.us        1030                 :           2155 :                 return true;
                               1031                 :                : 
 4609 alvherre@alvh.no-ip.     1032         [ +  + ]:        2932884 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1033                 :                :             {
                               1034                 :                :                 TransactionId xmax;
                               1035                 :                : 
                               1036                 :              7 :                 xmax = HeapTupleGetUpdateXid(tuple);
                               1037                 :                : 
                               1038                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 4299                          1039         [ -  + ]:              7 :                 Assert(TransactionIdIsValid(xmax));
                               1040                 :                : 
                               1041                 :                :                 /* updating subtransaction must have aborted */
 4609                          1042         [ +  - ]:              7 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                               1043                 :              7 :                     return true;
 4609 alvherre@alvh.no-ip.     1044         [ #  # ]:UBC           0 :                 else if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
                               1045                 :              0 :                     return true;    /* updated after scan started */
                               1046                 :                :                 else
 2999 tgl@sss.pgh.pa.us        1047                 :              0 :                     return false;   /* updated before scan started */
                               1048                 :                :             }
                               1049                 :                : 
 4609 alvherre@alvh.no-ip.     1050         [ +  + ]:CBC     2932877 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                               1051                 :                :             {
                               1052                 :                :                 /* deleting subtransaction must have aborted */
 6598 tgl@sss.pgh.pa.us        1053                 :             17 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1054                 :                :                             InvalidTransactionId);
 7737                          1055                 :             17 :                 return true;
                               1056                 :                :             }
                               1057                 :                : 
 8484 bruce@momjian.us         1058         [ +  + ]:        2932860 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 9761 vadim4o@yahoo.com        1059                 :            747 :                 return true;    /* deleted after scan started */
                               1060                 :                :             else
                               1061                 :        2932113 :                 return false;   /* deleted before scan started */
                               1062                 :                :         }
 3664 tgl@sss.pgh.pa.us        1063         [ +  + ]:        3936210 :         else if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
 9761 vadim4o@yahoo.com        1064                 :          21796 :             return false;
 4276 rhaas@postgresql.org     1065         [ +  + ]:        3914414 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6598 tgl@sss.pgh.pa.us        1066                 :        3861770 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1067                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                               1068                 :                :         else
                               1069                 :                :         {
                               1070                 :                :             /* it must have aborted or crashed */
                               1071                 :          52644 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1072                 :                :                         InvalidTransactionId);
 7427                          1073                 :          52644 :             return false;
                               1074                 :                :         }
                               1075                 :                :     }
                               1076                 :                :     else
                               1077                 :                :     {
                               1078                 :                :         /* xmin is committed, but maybe not according to our snapshot */
 3664                          1079   [ +  +  +  + ]:      123658134 :         if (!HeapTupleHeaderXminFrozen(tuple) &&
                               1080                 :       59896623 :             XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
                               1081                 :           3625 :             return false;       /* treat as still in progress */
                               1082                 :                :     }
                               1083                 :                : 
                               1084                 :                :     /* by here, the inserting transaction has committed */
                               1085                 :                : 
 9761 vadim4o@yahoo.com        1086         [ +  + ]:       67619656 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
                               1087                 :       62837147 :         return true;
                               1088                 :                : 
 4609 alvherre@alvh.no-ip.     1089         [ +  + ]:        4782509 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 7436 tgl@sss.pgh.pa.us        1090                 :          45084 :         return true;
                               1091                 :                : 
                               1092         [ +  + ]:        4737425 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1093                 :                :     {
                               1094                 :                :         TransactionId xmax;
                               1095                 :                : 
                               1096                 :                :         /* already checked above */
 4609 alvherre@alvh.no-ip.     1097         [ -  + ]:            144 :         Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
                               1098                 :                : 
                               1099                 :            144 :         xmax = HeapTupleGetUpdateXid(tuple);
                               1100                 :                : 
                               1101                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 4299                          1102         [ -  + ]:            144 :         Assert(TransactionIdIsValid(xmax));
                               1103                 :                : 
 4609                          1104         [ +  + ]:            144 :         if (TransactionIdIsCurrentTransactionId(xmax))
                               1105                 :                :         {
                               1106         [ -  + ]:             23 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 4609 alvherre@alvh.no-ip.     1107                 :UBC           0 :                 return true;    /* deleted after scan started */
                               1108                 :                :             else
 4609 alvherre@alvh.no-ip.     1109                 :CBC          23 :                 return false;   /* deleted before scan started */
                               1110                 :                :         }
 3664 tgl@sss.pgh.pa.us        1111         [ +  + ]:            121 :         if (XidInMVCCSnapshot(xmax, snapshot))
 4609 alvherre@alvh.no-ip.     1112                 :             18 :             return true;
                               1113         [ +  + ]:            103 :         if (TransactionIdDidCommit(xmax))
 3664 tgl@sss.pgh.pa.us        1114                 :             98 :             return false;       /* updating transaction committed */
                               1115                 :                :         /* it must have aborted or crashed */
 9761 vadim4o@yahoo.com        1116                 :              5 :         return true;
                               1117                 :                :     }
                               1118                 :                : 
                               1119         [ +  + ]:        4737281 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1120                 :                :     {
 4609 alvherre@alvh.no-ip.     1121         [ +  + ]:         456245 :         if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                               1122                 :                :         {
 8484 bruce@momjian.us         1123         [ +  + ]:         132131 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 9601                          1124                 :           1070 :                 return true;    /* deleted after scan started */
                               1125                 :                :             else
                               1126                 :         131061 :                 return false;   /* deleted before scan started */
                               1127                 :                :         }
                               1128                 :                : 
 3664 tgl@sss.pgh.pa.us        1129         [ +  + ]:         324114 :         if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
 7427                          1130                 :          12415 :             return true;
                               1131                 :                : 
 4609 alvherre@alvh.no-ip.     1132         [ +  + ]:         311699 :         if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                               1133                 :                :         {
                               1134                 :                :             /* it must have aborted or crashed */
 6598 tgl@sss.pgh.pa.us        1135                 :           6444 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1136                 :                :                         InvalidTransactionId);
 9761 vadim4o@yahoo.com        1137                 :           6444 :             return true;
                               1138                 :                :         }
                               1139                 :                : 
                               1140                 :                :         /* xmax transaction committed */
 6598 tgl@sss.pgh.pa.us        1141                 :         305255 :         SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                               1142                 :                :                     HeapTupleHeaderGetRawXmax(tuple));
                               1143                 :                :     }
                               1144                 :                :     else
                               1145                 :                :     {
                               1146                 :                :         /* xmax is committed, but maybe not according to our snapshot */
 3664                          1147         [ +  + ]:        4281036 :         if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
                               1148                 :            763 :             return true;        /* treat as still in progress */
                               1149                 :                :     }
                               1150                 :                : 
                               1151                 :                :     /* xmax transaction committed */
                               1152                 :                : 
 9761 vadim4o@yahoo.com        1153                 :        4585528 :     return false;
                               1154                 :                : }
                               1155                 :                : 
                               1156                 :                : 
                               1157                 :                : /*
                               1158                 :                :  * HeapTupleSatisfiesVacuum
                               1159                 :                :  *
                               1160                 :                :  *  Determine the status of tuples for VACUUM purposes.  Here, what
                               1161                 :                :  *  we mainly want to know is if a tuple is potentially visible to *any*
                               1162                 :                :  *  running transaction.  If so, it can't be removed yet by VACUUM.
                               1163                 :                :  *
                               1164                 :                :  * OldestXmin is a cutoff XID (obtained from
                               1165                 :                :  * GetOldestNonRemovableTransactionId()).  Tuples deleted by XIDs >=
                               1166                 :                :  * OldestXmin are deemed "recently dead"; they might still be visible to some
                               1167                 :                :  * open transaction, so we can't remove them, even if we see that the deleting
                               1168                 :                :  * transaction has committed.
                               1169                 :                :  */
                               1170                 :                : HTSV_Result
 4429 rhaas@postgresql.org     1171                 :       16847429 : HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
                               1172                 :                :                          Buffer buffer)
                               1173                 :                : {
 1851 andres@anarazel.de       1174                 :       16847429 :     TransactionId dead_after = InvalidTransactionId;
                               1175                 :                :     HTSV_Result res;
                               1176                 :                : 
                               1177                 :       16847429 :     res = HeapTupleSatisfiesVacuumHorizon(htup, buffer, &dead_after);
                               1178                 :                : 
                               1179         [ +  + ]:       16847429 :     if (res == HEAPTUPLE_RECENTLY_DEAD)
                               1180                 :                :     {
                               1181         [ -  + ]:         236026 :         Assert(TransactionIdIsValid(dead_after));
                               1182                 :                : 
                               1183         [ +  + ]:         236026 :         if (TransactionIdPrecedes(dead_after, OldestXmin))
                               1184                 :          19974 :             res = HEAPTUPLE_DEAD;
                               1185                 :                :     }
                               1186                 :                :     else
                               1187         [ -  + ]:       16611403 :         Assert(!TransactionIdIsValid(dead_after));
                               1188                 :                : 
                               1189                 :       16847429 :     return res;
                               1190                 :                : }
                               1191                 :                : 
                               1192                 :                : /*
                               1193                 :                :  * Work horse for HeapTupleSatisfiesVacuum and similar routines.
                               1194                 :                :  *
                               1195                 :                :  * In contrast to HeapTupleSatisfiesVacuum this routine, when encountering a
                               1196                 :                :  * tuple that could still be visible to some backend, stores the xid that
                               1197                 :                :  * needs to be compared with the horizon in *dead_after, and returns
                               1198                 :                :  * HEAPTUPLE_RECENTLY_DEAD. The caller then can perform the comparison with
                               1199                 :                :  * the horizon.  This is e.g. useful when comparing with different horizons.
                               1200                 :                :  *
                               1201                 :                :  * Note: HEAPTUPLE_DEAD can still be returned here, e.g. if the inserting
                               1202                 :                :  * transaction aborted.
                               1203                 :                :  */
                               1204                 :                : HTSV_Result
                               1205                 :       24229173 : HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *dead_after)
                               1206                 :                : {
 4429 rhaas@postgresql.org     1207                 :       24229173 :     HeapTupleHeader tuple = htup->t_data;
                               1208                 :                : 
                               1209         [ -  + ]:       24229173 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1210         [ -  + ]:       24229173 :     Assert(htup->t_tableOid != InvalidOid);
 1851 andres@anarazel.de       1211         [ -  + ]:       24229173 :     Assert(dead_after != NULL);
                               1212                 :                : 
                               1213                 :       24229173 :     *dead_after = InvalidTransactionId;
                               1214                 :                : 
                               1215                 :                :     /*
                               1216                 :                :      * Has inserting transaction committed?
                               1217                 :                :      *
                               1218                 :                :      * If the inserting transaction aborted, then the tuple was never visible
                               1219                 :                :      * to any other transaction, so we can delete it immediately.
                               1220                 :                :      */
 4276 rhaas@postgresql.org     1221         [ +  + ]:       24229173 :     if (!HeapTupleHeaderXminCommitted(tuple))
                               1222                 :                :     {
                               1223         [ +  + ]:        6089135 :         if (HeapTupleHeaderXminInvalid(tuple))
 8822 tgl@sss.pgh.pa.us        1224                 :          14360 :             return HEAPTUPLE_DEAD;
                               1225                 :                :         /* Used by pre-9.0 binary upgrades */
                               1226         [ -  + ]:        6074775 :         else if (tuple->t_infomask & HEAP_MOVED_OFF)
                               1227                 :                :         {
 8109 bruce@momjian.us         1228                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                               1229                 :                : 
                               1230         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8662 tgl@sss.pgh.pa.us        1231                 :              0 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
 8109 bruce@momjian.us         1232         [ #  # ]:              0 :             if (TransactionIdIsInProgress(xvac))
 8662 tgl@sss.pgh.pa.us        1233                 :              0 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
 8109 bruce@momjian.us         1234         [ #  # ]:              0 :             if (TransactionIdDidCommit(xvac))
                               1235                 :                :             {
 6598 tgl@sss.pgh.pa.us        1236                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1237                 :                :                             InvalidTransactionId);
 8822                          1238                 :              0 :                 return HEAPTUPLE_DEAD;
                               1239                 :                :             }
 6598                          1240                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1241                 :                :                         InvalidTransactionId);
                               1242                 :                :         }
                               1243                 :                :         /* Used by pre-9.0 binary upgrades */
 8822 tgl@sss.pgh.pa.us        1244         [ -  + ]:CBC     6074775 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                               1245                 :                :         {
 8109 bruce@momjian.us         1246                 :UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                               1247                 :                : 
                               1248         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8662 tgl@sss.pgh.pa.us        1249                 :              0 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
 8109 bruce@momjian.us         1250         [ #  # ]:              0 :             if (TransactionIdIsInProgress(xvac))
 8662 tgl@sss.pgh.pa.us        1251                 :              0 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
 8109 bruce@momjian.us         1252         [ #  # ]:              0 :             if (TransactionIdDidCommit(xvac))
 6598 tgl@sss.pgh.pa.us        1253                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1254                 :                :                             InvalidTransactionId);
                               1255                 :                :             else
                               1256                 :                :             {
                               1257                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1258                 :                :                             InvalidTransactionId);
 8822                          1259                 :              0 :                 return HEAPTUPLE_DEAD;
                               1260                 :                :             }
                               1261                 :                :         }
 4112 andres@anarazel.de       1262         [ +  + ]:CBC     6074775 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                               1263                 :                :         {
 8020 tgl@sss.pgh.pa.us        1264         [ +  + ]:        2055307 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                               1265                 :        2019492 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1266                 :                :             /* only locked? run infomask-only check first, for performance */
 4432 alvherre@alvh.no-ip.     1267   [ +  +  -  + ]:          63496 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
                               1268                 :          27681 :                 HeapTupleHeaderIsOnlyLocked(tuple))
 8020 tgl@sss.pgh.pa.us        1269                 :           8134 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1270                 :                :             /* inserted and then deleted by same xact */
 4112 andres@anarazel.de       1271         [ +  - ]:          27681 :             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
                               1272                 :          27681 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
                               1273                 :                :             /* deleting subtransaction must have aborted */
 4112 andres@anarazel.de       1274                 :UBC           0 :             return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1275                 :                :         }
 4112 andres@anarazel.de       1276         [ +  + ]:CBC     4019468 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
                               1277                 :                :         {
                               1278                 :                :             /*
                               1279                 :                :              * It'd be possible to discern between INSERT/DELETE in progress
                               1280                 :                :              * here by looking at xmax - but that doesn't seem beneficial for
                               1281                 :                :              * the majority of callers and even detrimental for some. We'd
                               1282                 :                :              * rather have callers look at/wait for xmin than xmax. It's
                               1283                 :                :              * always correct to return INSERT_IN_PROGRESS because that's
                               1284                 :                :              * what's happening from the view of other backends.
                               1285                 :                :              */
                               1286                 :           5254 :             return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1287                 :                :         }
 4276 rhaas@postgresql.org     1288         [ +  + ]:        4014214 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6598 tgl@sss.pgh.pa.us        1289                 :        3980291 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1290                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                               1291                 :                :         else
                               1292                 :                :         {
                               1293                 :                :             /*
                               1294                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed
                               1295                 :                :              */
                               1296                 :          33923 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1297                 :                :                         InvalidTransactionId);
 8822                          1298                 :          33923 :             return HEAPTUPLE_DEAD;
                               1299                 :                :         }
                               1300                 :                : 
                               1301                 :                :         /*
                               1302                 :                :          * At this point the xmin is known committed, but we might not have
                               1303                 :                :          * been able to set the hint bit yet; so we can no longer Assert that
                               1304                 :                :          * it's set.
                               1305                 :                :          */
                               1306                 :                :     }
                               1307                 :                : 
                               1308                 :                :     /*
                               1309                 :                :      * Okay, the inserter committed, so it was good at some point.  Now what
                               1310                 :                :      * about the deleting transaction?
                               1311                 :                :      */
                               1312         [ +  + ]:       22120329 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1313                 :       20090954 :         return HEAPTUPLE_LIVE;
                               1314                 :                : 
 4609 alvherre@alvh.no-ip.     1315         [ +  + ]:        2029375 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                               1316                 :                :     {
                               1317                 :                :         /*
                               1318                 :                :          * "Deleting" xact really only locked it, so the tuple is live in any
                               1319                 :                :          * case.  However, we should make sure that either XMAX_COMMITTED or
                               1320                 :                :          * XMAX_INVALID gets set once the xact is gone, to reduce the costs of
                               1321                 :                :          * examining the tuple for future xacts.
                               1322                 :                :          */
 8639 tgl@sss.pgh.pa.us        1323         [ +  - ]:          13396 :         if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1324                 :                :         {
 7436                          1325         [ +  + ]:          13396 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1326                 :                :             {
                               1327                 :                :                 /*
                               1328                 :                :                  * If it's a pre-pg_upgrade tuple, the multixact cannot
                               1329                 :                :                  * possibly be running; otherwise have to check.
                               1330                 :                :                  */
 3361 alvherre@alvh.no-ip.     1331   [ +  -  +  + ]:            442 :                 if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
 4057                          1332                 :            221 :                     MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
                               1333                 :                :                                          true))
 7436 tgl@sss.pgh.pa.us        1334                 :              4 :                     return HEAPTUPLE_LIVE;
 4609 alvherre@alvh.no-ip.     1335                 :            217 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
                               1336                 :                :             }
                               1337                 :                :             else
                               1338                 :                :             {
                               1339         [ -  + ]:          13175 :                 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 7436 tgl@sss.pgh.pa.us        1340                 :UBC           0 :                     return HEAPTUPLE_LIVE;
 4609 alvherre@alvh.no-ip.     1341                 :CBC       13175 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1342                 :                :                             InvalidTransactionId);
                               1343                 :                :             }
                               1344                 :                :         }
                               1345                 :                : 
                               1346                 :                :         /*
                               1347                 :                :          * We don't really care whether xmax did commit, abort or crash. We
                               1348                 :                :          * know that xmax did lock the tuple, but it did not and will never
                               1349                 :                :          * actually update it.
                               1350                 :                :          */
                               1351                 :                : 
 8662 tgl@sss.pgh.pa.us        1352                 :          13392 :         return HEAPTUPLE_LIVE;
                               1353                 :                :     }
                               1354                 :                : 
 7436                          1355         [ +  + ]:        2015979 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1356                 :                :     {
 2864 andres@anarazel.de       1357                 :              6 :         TransactionId xmax = HeapTupleGetUpdateXid(tuple);
                               1358                 :                : 
                               1359                 :                :         /* already checked above */
                               1360         [ -  + ]:              6 :         Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
                               1361                 :                : 
                               1362                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 4299 alvherre@alvh.no-ip.     1363         [ -  + ]:              6 :         Assert(TransactionIdIsValid(xmax));
                               1364                 :                : 
 2864 andres@anarazel.de       1365         [ -  + ]:              6 :         if (TransactionIdIsInProgress(xmax))
 2864 andres@anarazel.de       1366                 :UBC           0 :             return HEAPTUPLE_DELETE_IN_PROGRESS;
 2864 andres@anarazel.de       1367         [ +  - ]:CBC           6 :         else if (TransactionIdDidCommit(xmax))
                               1368                 :                :         {
                               1369                 :                :             /*
                               1370                 :                :              * The multixact might still be running due to lockers.  Need to
                               1371                 :                :              * allow for pruning if below the xid horizon regardless --
                               1372                 :                :              * otherwise we could end up with a tuple where the updater has to
                               1373                 :                :              * be removed due to the horizon, but is not pruned away.  It's
                               1374                 :                :              * not a problem to prune that tuple, because any remaining
                               1375                 :                :              * lockers will also be present in newer tuple versions.
                               1376                 :                :              */
 1851                          1377                 :              6 :             *dead_after = xmax;
                               1378                 :              6 :             return HEAPTUPLE_RECENTLY_DEAD;
                               1379                 :                :         }
 2864 andres@anarazel.de       1380         [ #  # ]:UBC           0 :         else if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
                               1381                 :                :         {
                               1382                 :                :             /*
                               1383                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed.
                               1384                 :                :              * Mark the Xmax as invalid.
                               1385                 :                :              */
                               1386                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
                               1387                 :                :         }
                               1388                 :                : 
 4299 alvherre@alvh.no-ip.     1389                 :              0 :         return HEAPTUPLE_LIVE;
                               1390                 :                :     }
                               1391                 :                : 
 8822 tgl@sss.pgh.pa.us        1392         [ +  + ]:CBC     2015973 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1393                 :                :     {
 4609 alvherre@alvh.no-ip.     1394         [ +  + ]:        1278887 :         if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 8818 tgl@sss.pgh.pa.us        1395                 :          54177 :             return HEAPTUPLE_DELETE_IN_PROGRESS;
 4609 alvherre@alvh.no-ip.     1396         [ +  + ]:        1224710 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 6598 tgl@sss.pgh.pa.us        1397                 :        1222899 :             SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                               1398                 :                :                         HeapTupleHeaderGetRawXmax(tuple));
                               1399                 :                :         else
                               1400                 :                :         {
                               1401                 :                :             /*
                               1402                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed
                               1403                 :                :              */
                               1404                 :           1811 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1405                 :                :                         InvalidTransactionId);
 8822                          1406                 :           1811 :             return HEAPTUPLE_LIVE;
                               1407                 :                :         }
                               1408                 :                : 
                               1409                 :                :         /*
                               1410                 :                :          * At this point the xmax is known committed, but we might not have
                               1411                 :                :          * been able to set the hint bit yet; so we can no longer Assert that
                               1412                 :                :          * it's set.
                               1413                 :                :          */
                               1414                 :                :     }
                               1415                 :                : 
                               1416                 :                :     /*
                               1417                 :                :      * Deleter committed, allow caller to check if it was recent enough that
                               1418                 :                :      * some open transactions could still see the tuple.
                               1419                 :                :      */
 1851 andres@anarazel.de       1420                 :        1959985 :     *dead_after = HeapTupleHeaderGetRawXmax(tuple);
                               1421                 :        1959985 :     return HEAPTUPLE_RECENTLY_DEAD;
                               1422                 :                : }
                               1423                 :                : 
                               1424                 :                : 
                               1425                 :                : /*
                               1426                 :                :  * HeapTupleSatisfiesNonVacuumable
                               1427                 :                :  *
                               1428                 :                :  *  True if tuple might be visible to some transaction; false if it's
                               1429                 :                :  *  surely dead to everyone, ie, vacuumable.
                               1430                 :                :  *
                               1431                 :                :  *  See SNAPSHOT_NON_VACUUMABLE's definition for the intended behaviour.
                               1432                 :                :  *
                               1433                 :                :  *  This is an interface to HeapTupleSatisfiesVacuum that's callable via
                               1434                 :                :  *  HeapTupleSatisfiesSnapshot, so it can be used through a Snapshot.
                               1435                 :                :  *  snapshot->vistest must have been set up with the horizon to use.
                               1436                 :                :  */
                               1437                 :                : static bool
 2921 tgl@sss.pgh.pa.us        1438                 :         350268 : HeapTupleSatisfiesNonVacuumable(HeapTuple htup, Snapshot snapshot,
                               1439                 :                :                                 Buffer buffer)
                               1440                 :                : {
 1851 andres@anarazel.de       1441                 :         350268 :     TransactionId dead_after = InvalidTransactionId;
                               1442                 :                :     HTSV_Result res;
                               1443                 :                : 
                               1444                 :         350268 :     res = HeapTupleSatisfiesVacuumHorizon(htup, buffer, &dead_after);
                               1445                 :                : 
                               1446         [ +  + ]:         350268 :     if (res == HEAPTUPLE_RECENTLY_DEAD)
                               1447                 :                :     {
                               1448         [ -  + ]:          77721 :         Assert(TransactionIdIsValid(dead_after));
                               1449                 :                : 
                               1450         [ +  + ]:          77721 :         if (GlobalVisTestIsRemovableXid(snapshot->vistest, dead_after))
                               1451                 :          64583 :             res = HEAPTUPLE_DEAD;
                               1452                 :                :     }
                               1453                 :                :     else
                               1454         [ -  + ]:         272547 :         Assert(!TransactionIdIsValid(dead_after));
                               1455                 :                : 
                               1456                 :         350268 :     return res != HEAPTUPLE_DEAD;
                               1457                 :                : }
                               1458                 :                : 
                               1459                 :                : 
                               1460                 :                : /*
                               1461                 :                :  * HeapTupleIsSurelyDead
                               1462                 :                :  *
                               1463                 :                :  *  Cheaply determine whether a tuple is surely dead to all onlookers.
                               1464                 :                :  *  We sometimes use this in lieu of HeapTupleSatisfiesVacuum when the
                               1465                 :                :  *  tuple has just been tested by another visibility routine (usually
                               1466                 :                :  *  HeapTupleSatisfiesMVCC) and, therefore, any hint bits that can be set
                               1467                 :                :  *  should already be set.  We assume that if no hint bits are set, the xmin
                               1468                 :                :  *  or xmax transaction is still running.  This is therefore faster than
                               1469                 :                :  *  HeapTupleSatisfiesVacuum, because we consult neither procarray nor CLOG.
                               1470                 :                :  *  It's okay to return false when in doubt, but we must return true only
                               1471                 :                :  *  if the tuple is removable.
                               1472                 :                :  */
                               1473                 :                : bool
                               1474                 :        6421769 : HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
                               1475                 :                : {
 4429 rhaas@postgresql.org     1476                 :        6421769 :     HeapTupleHeader tuple = htup->t_data;
                               1477                 :                : 
                               1478         [ -  + ]:        6421769 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1479         [ -  + ]:        6421769 :     Assert(htup->t_tableOid != InvalidOid);
                               1480                 :                : 
                               1481                 :                :     /*
                               1482                 :                :      * If the inserting transaction is marked invalid, then it aborted, and
                               1483                 :                :      * the tuple is definitely dead.  If it's marked neither committed nor
                               1484                 :                :      * invalid, then we assume it's still alive (since the presumption is that
                               1485                 :                :      * all relevant hint bits were just set moments ago).
                               1486                 :                :      */
 4276                          1487         [ +  + ]:        6421769 :     if (!HeapTupleHeaderXminCommitted(tuple))
 1459 michael@paquier.xyz      1488                 :        5638593 :         return HeapTupleHeaderXminInvalid(tuple);
                               1489                 :                : 
                               1490                 :                :     /*
                               1491                 :                :      * If the inserting transaction committed, but any deleting transaction
                               1492                 :                :      * aborted, the tuple is still alive.
                               1493                 :                :      */
 4609 alvherre@alvh.no-ip.     1494         [ +  + ]:         783176 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1495                 :             35 :         return false;
                               1496                 :                : 
                               1497                 :                :     /*
                               1498                 :                :      * If the XMAX is just a lock, the tuple is still alive.
                               1499                 :                :      */
                               1500         [ -  + ]:         783141 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 4609 alvherre@alvh.no-ip.     1501                 :UBC           0 :         return false;
                               1502                 :                : 
                               1503                 :                :     /*
                               1504                 :                :      * If the Xmax is a MultiXact, it might be dead or alive, but we cannot
                               1505                 :                :      * know without checking pg_multixact.
                               1506                 :                :      */
 4609 alvherre@alvh.no-ip.     1507         [ +  + ]:CBC      783141 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
 4875 rhaas@postgresql.org     1508                 :             46 :         return false;
                               1509                 :                : 
                               1510                 :                :     /* If deleter isn't known to have committed, assume it's still running. */
                               1511         [ +  + ]:         783095 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1512                 :         210305 :         return false;
                               1513                 :                : 
                               1514                 :                :     /* Deleter committed, so tuple is dead if the XID is old enough. */
 1851 andres@anarazel.de       1515                 :         572790 :     return GlobalVisTestIsRemovableXid(vistest,
                               1516                 :                :                                        HeapTupleHeaderGetRawXmax(tuple));
                               1517                 :                : }
                               1518                 :                : 
                               1519                 :                : /*
                               1520                 :                :  * Is the tuple really only locked?  That is, is it not updated?
                               1521                 :                :  *
                               1522                 :                :  * It's easy to check just infomask bits if the locker is not a multi; but
                               1523                 :                :  * otherwise we need to verify that the updating transaction has not aborted.
                               1524                 :                :  *
                               1525                 :                :  * This function is here because it follows the same visibility rules laid out
                               1526                 :                :  * at the top of this file.
                               1527                 :                :  */
                               1528                 :                : bool
 4609 alvherre@alvh.no-ip.     1529                 :          45500 : HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
                               1530                 :                : {
                               1531                 :                :     TransactionId xmax;
                               1532                 :                : 
                               1533                 :                :     /* if there's no valid Xmax, then there's obviously no update either */
                               1534         [ -  + ]:          45500 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
 4609 alvherre@alvh.no-ip.     1535                 :UBC           0 :         return true;
                               1536                 :                : 
 4609 alvherre@alvh.no-ip.     1537         [ +  + ]:CBC       45500 :     if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
                               1538                 :            537 :         return true;
                               1539                 :                : 
                               1540                 :                :     /* invalid xmax means no update */
                               1541         [ -  + ]:          44963 :     if (!TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple)))
 4609 alvherre@alvh.no-ip.     1542                 :UBC           0 :         return true;
                               1543                 :                : 
                               1544                 :                :     /*
                               1545                 :                :      * if HEAP_XMAX_LOCK_ONLY is not set and not a multi, then this must
                               1546                 :                :      * necessarily have been updated
                               1547                 :                :      */
 4609 alvherre@alvh.no-ip.     1548         [ +  + ]:CBC       44963 :     if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
                               1549                 :          44935 :         return false;
                               1550                 :                : 
                               1551                 :                :     /* ... but if it's a multi, then perhaps the updating Xid aborted. */
                               1552                 :             28 :     xmax = HeapTupleGetUpdateXid(tuple);
                               1553                 :                : 
                               1554                 :                :     /* not LOCKED_ONLY, so it has to have an xmax */
 4299                          1555         [ -  + ]:             28 :     Assert(TransactionIdIsValid(xmax));
                               1556                 :                : 
 4609                          1557         [ -  + ]:             28 :     if (TransactionIdIsCurrentTransactionId(xmax))
 4609 alvherre@alvh.no-ip.     1558                 :UBC           0 :         return false;
 4609 alvherre@alvh.no-ip.     1559         [ +  + ]:CBC          28 :     if (TransactionIdIsInProgress(xmax))
                               1560                 :              4 :         return false;
                               1561         [ +  + ]:             24 :     if (TransactionIdDidCommit(xmax))
                               1562                 :             11 :         return false;
                               1563                 :                : 
                               1564                 :                :     /*
                               1565                 :                :      * not current, not in progress, not committed -- must have aborted or
                               1566                 :                :      * crashed
                               1567                 :                :      */
                               1568                 :             13 :     return true;
                               1569                 :                : }
                               1570                 :                : 
                               1571                 :                : /*
                               1572                 :                :  * check whether the transaction id 'xid' is in the pre-sorted array 'xip'.
                               1573                 :                :  */
                               1574                 :                : static bool
 4205 rhaas@postgresql.org     1575                 :          43879 : TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
                               1576                 :                : {
 1283 tgl@sss.pgh.pa.us        1577   [ +  +  +  + ]:          61248 :     return num > 0 &&
                               1578                 :          17369 :         bsearch(&xid, xip, num, sizeof(TransactionId), xidComparator) != NULL;
                               1579                 :                : }
                               1580                 :                : 
                               1581                 :                : /*
                               1582                 :                :  * See the comments for HeapTupleSatisfiesMVCC for the semantics this function
                               1583                 :                :  * obeys.
                               1584                 :                :  *
                               1585                 :                :  * Only usable on tuples from catalog tables!
                               1586                 :                :  *
                               1587                 :                :  * We don't need to support HEAP_MOVED_(IN|OFF) for now because we only support
                               1588                 :                :  * reading catalog pages which couldn't have been created in an older version.
                               1589                 :                :  *
                               1590                 :                :  * We don't set any hint bits in here as it seems unlikely to be beneficial as
                               1591                 :                :  * those should already be set by normal access and it seems to be too
                               1592                 :                :  * dangerous to do so as the semantics of doing so during timetravel are more
                               1593                 :                :  * complicated than when dealing "only" with the present.
                               1594                 :                :  */
                               1595                 :                : static bool
 4205 rhaas@postgresql.org     1596                 :          35822 : HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
                               1597                 :                :                                Buffer buffer)
                               1598                 :                : {
                               1599                 :          35822 :     HeapTupleHeader tuple = htup->t_data;
                               1600                 :          35822 :     TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
                               1601                 :          35822 :     TransactionId xmax = HeapTupleHeaderGetRawXmax(tuple);
                               1602                 :                : 
                               1603         [ -  + ]:          35822 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1604         [ -  + ]:          35822 :     Assert(htup->t_tableOid != InvalidOid);
                               1605                 :                : 
                               1606                 :                :     /* inserting transaction aborted */
                               1607         [ +  + ]:          35822 :     if (HeapTupleHeaderXminInvalid(tuple))
                               1608                 :                :     {
                               1609         [ -  + ]:             75 :         Assert(!TransactionIdDidCommit(xmin));
                               1610                 :             75 :         return false;
                               1611                 :                :     }
                               1612                 :                :     /* check if it's one of our txids, toplevel is also in there */
                               1613         [ +  + ]:          35747 :     else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))
                               1614                 :                :     {
                               1615                 :                :         bool        resolved;
                               1616                 :            484 :         CommandId   cmin = HeapTupleHeaderGetRawCommandId(tuple);
                               1617                 :            484 :         CommandId   cmax = InvalidCommandId;
                               1618                 :                : 
                               1619                 :                :         /*
                               1620                 :                :          * another transaction might have (tried to) delete this tuple or
                               1621                 :                :          * cmin/cmax was stored in a combo CID. So we need to lookup the
                               1622                 :                :          * actual values externally.
                               1623                 :                :          */
                               1624                 :            484 :         resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot,
                               1625                 :                :                                                  htup, buffer,
                               1626                 :                :                                                  &cmin, &cmax);
                               1627                 :                : 
                               1628                 :                :         /*
                               1629                 :                :          * If we haven't resolved the combo CID to cmin/cmax, that means we
                               1630                 :                :          * have not decoded the combo CID yet. That means the cmin is
                               1631                 :                :          * definitely in the future, and we're not supposed to see the tuple
                               1632                 :                :          * yet.
                               1633                 :                :          *
                               1634                 :                :          * XXX This only applies to decoding of in-progress transactions. In
                               1635                 :                :          * regular logical decoding we only execute this code at commit time,
                               1636                 :                :          * at which point we should have seen all relevant combo CIDs. So
                               1637                 :                :          * ideally, we should error out in this case but in practice, this
                               1638                 :                :          * won't happen. If we are too worried about this then we can add an
                               1639                 :                :          * elog inside ResolveCminCmaxDuringDecoding.
                               1640                 :                :          *
                               1641                 :                :          * XXX For the streaming case, we can track the largest combo CID
                               1642                 :                :          * assigned, and error out based on this (when unable to resolve combo
                               1643                 :                :          * CID below that observed maximum value).
                               1644                 :                :          */
                               1645         [ +  + ]:            484 :         if (!resolved)
 1855 akapila@postgresql.o     1646                 :             66 :             return false;
                               1647                 :                : 
 4205 rhaas@postgresql.org     1648         [ -  + ]:            479 :         Assert(cmin != InvalidCommandId);
                               1649                 :                : 
                               1650         [ +  + ]:            479 :         if (cmin >= snapshot->curcid)
 4141 bruce@momjian.us         1651                 :             61 :             return false;       /* inserted after scan started */
                               1652                 :                :         /* fall through */
                               1653                 :                :     }
                               1654                 :                :     /* committed before our xmin horizon. Do a normal visibility check. */
 4205 rhaas@postgresql.org     1655         [ +  + ]:          35263 :     else if (TransactionIdPrecedes(xmin, snapshot->xmin))
                               1656                 :                :     {
                               1657   [ +  +  -  + ]:          32226 :         Assert(!(HeapTupleHeaderXminCommitted(tuple) &&
                               1658                 :                :                  !TransactionIdDidCommit(xmin)));
                               1659                 :                : 
                               1660                 :                :         /* check for hint bit first, consult clog afterwards */
                               1661         [ +  + ]:          32226 :         if (!HeapTupleHeaderXminCommitted(tuple) &&
                               1662         [ -  + ]:             30 :             !TransactionIdDidCommit(xmin))
 4205 rhaas@postgresql.org     1663                 :LBC         (4) :             return false;
                               1664                 :                :         /* fall through */
                               1665                 :                :     }
                               1666                 :                :     /* beyond our xmax horizon, i.e. invisible */
 4205 rhaas@postgresql.org     1667         [ +  + ]:CBC        3037 :     else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))
                               1668                 :                :     {
                               1669                 :            124 :         return false;
                               1670                 :                :     }
                               1671                 :                :     /* check if it's a committed transaction in [xmin, xmax) */
 4141 bruce@momjian.us         1672         [ -  + ]:           2913 :     else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
                               1673                 :                :     {
                               1674                 :                :         /* fall through */
                               1675                 :                :     }
                               1676                 :                : 
                               1677                 :                :     /*
                               1678                 :                :      * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.
                               1679                 :                :      * invisible.
                               1680                 :                :      */
                               1681                 :                :     else
                               1682                 :                :     {
 4205 rhaas@postgresql.org     1683                 :UBC           0 :         return false;
                               1684                 :                :     }
                               1685                 :                : 
                               1686                 :                :     /* at this point we know xmin is visible, go on to check xmax */
                               1687                 :                : 
                               1688                 :                :     /* xid invalid or aborted */
 4205 rhaas@postgresql.org     1689         [ +  + ]:CBC       35557 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1690                 :          30636 :         return true;
                               1691                 :                :     /* locked tuples are always visible */
                               1692         [ +  + ]:           4921 :     else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                               1693                 :           1036 :         return true;
                               1694                 :                : 
                               1695                 :                :     /*
                               1696                 :                :      * We can see multis here if we're looking at user tables or if somebody
                               1697                 :                :      * SELECT ... FOR SHARE/UPDATE a system table.
                               1698                 :                :      */
                               1699         [ +  + ]:           3885 :     else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1700                 :                :     {
                               1701                 :             43 :         xmax = HeapTupleGetUpdateXid(tuple);
                               1702                 :                :     }
                               1703                 :                : 
                               1704                 :                :     /* check if it's one of our txids, toplevel is also in there */
                               1705         [ +  + ]:           3885 :     if (TransactionIdInArray(xmax, snapshot->subxip, snapshot->subxcnt))
                               1706                 :                :     {
                               1707                 :                :         bool        resolved;
                               1708                 :                :         CommandId   cmin;
 4141 bruce@momjian.us         1709                 :            279 :         CommandId   cmax = HeapTupleHeaderGetRawCommandId(tuple);
                               1710                 :                : 
                               1711                 :                :         /* Lookup actual cmin/cmax values */
 4205 rhaas@postgresql.org     1712                 :            279 :         resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot,
                               1713                 :                :                                                  htup, buffer,
                               1714                 :                :                                                  &cmin, &cmax);
                               1715                 :                : 
                               1716                 :                :         /*
                               1717                 :                :          * If we haven't resolved the combo CID to cmin/cmax, that means we
                               1718                 :                :          * have not decoded the combo CID yet. That means the cmax is
                               1719                 :                :          * definitely in the future, and we're still supposed to see the
                               1720                 :                :          * tuple.
                               1721                 :                :          *
                               1722                 :                :          * XXX This only applies to decoding of in-progress transactions. In
                               1723                 :                :          * regular logical decoding we only execute this code at commit time,
                               1724                 :                :          * at which point we should have seen all relevant combo CIDs. So
                               1725                 :                :          * ideally, we should error out in this case but in practice, this
                               1726                 :                :          * won't happen. If we are too worried about this then we can add an
                               1727                 :                :          * elog inside ResolveCminCmaxDuringDecoding.
                               1728                 :                :          *
                               1729                 :                :          * XXX For the streaming case, we can track the largest combo CID
                               1730                 :                :          * assigned, and error out based on this (when unable to resolve combo
                               1731                 :                :          * CID below that observed maximum value).
                               1732                 :                :          */
 1855 akapila@postgresql.o     1733   [ +  +  -  + ]:            279 :         if (!resolved || cmax == InvalidCommandId)
                               1734                 :             11 :             return true;
                               1735                 :                : 
 4205 rhaas@postgresql.org     1736         [ +  + ]:            268 :         if (cmax >= snapshot->curcid)
 4141 bruce@momjian.us         1737                 :             85 :             return true;        /* deleted after scan started */
                               1738                 :                :         else
                               1739                 :            183 :             return false;       /* deleted before scan started */
                               1740                 :                :     }
                               1741                 :                :     /* below xmin horizon, normal transaction state is valid */
 4205 rhaas@postgresql.org     1742         [ +  + ]:           3606 :     else if (TransactionIdPrecedes(xmax, snapshot->xmin))
                               1743                 :                :     {
                               1744   [ +  +  -  + ]:           2024 :         Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED &&
                               1745                 :                :                  !TransactionIdDidCommit(xmax)));
                               1746                 :                : 
                               1747                 :                :         /* check hint bit first */
                               1748         [ +  + ]:           2024 :         if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                               1749                 :           1961 :             return false;
                               1750                 :                : 
                               1751                 :                :         /* check clog */
                               1752                 :             63 :         return !TransactionIdDidCommit(xmax);
                               1753                 :                :     }
                               1754                 :                :     /* above xmax horizon, we cannot possibly see the deleting transaction */
                               1755         [ +  + ]:           1582 :     else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
                               1756                 :            248 :         return true;
                               1757                 :                :     /* xmax is between [xmin, xmax), check known committed array */
                               1758         [ +  - ]:           1334 :     else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
                               1759                 :           1334 :         return false;
                               1760                 :                :     /* xmax is between [xmin, xmax), but known not to have committed yet */
                               1761                 :                :     else
 4205 rhaas@postgresql.org     1762                 :UBC           0 :         return true;
                               1763                 :                : }
                               1764                 :                : 
                               1765                 :                : /*
                               1766                 :                :  * HeapTupleSatisfiesVisibility
                               1767                 :                :  *      True iff heap tuple satisfies a time qual.
                               1768                 :                :  *
                               1769                 :                :  * Notes:
                               1770                 :                :  *  Assumes heap tuple is valid, and buffer at least share locked.
                               1771                 :                :  *
                               1772                 :                :  *  Hint bits in the HeapTuple's t_infomask may be updated as a side effect;
                               1773                 :                :  *  if so, the indicated buffer is marked dirty.
                               1774                 :                :  */
                               1775                 :                : bool
 1083 pg@bowt.ie               1776                 :CBC    93159041 : HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                               1777                 :                : {
 2420 andres@anarazel.de       1778   [ +  +  +  +  :       93159041 :     switch (snapshot->snapshot_type)
                                        +  +  +  - ]
                               1779                 :                :     {
                               1780                 :       78865771 :         case SNAPSHOT_MVCC:
 1083 pg@bowt.ie               1781                 :       78865771 :             return HeapTupleSatisfiesMVCC(htup, snapshot, buffer);
 2420 andres@anarazel.de       1782                 :           2577 :         case SNAPSHOT_SELF:
 1083 pg@bowt.ie               1783                 :           2577 :             return HeapTupleSatisfiesSelf(htup, snapshot, buffer);
 2420 andres@anarazel.de       1784                 :        7898740 :         case SNAPSHOT_ANY:
 1083 pg@bowt.ie               1785                 :        7898740 :             return HeapTupleSatisfiesAny(htup, snapshot, buffer);
 2420 andres@anarazel.de       1786                 :          79934 :         case SNAPSHOT_TOAST:
 1083 pg@bowt.ie               1787                 :          79934 :             return HeapTupleSatisfiesToast(htup, snapshot, buffer);
 2420 andres@anarazel.de       1788                 :        5925929 :         case SNAPSHOT_DIRTY:
 1083 pg@bowt.ie               1789                 :        5925929 :             return HeapTupleSatisfiesDirty(htup, snapshot, buffer);
 2420 andres@anarazel.de       1790                 :          35822 :         case SNAPSHOT_HISTORIC_MVCC:
 1083 pg@bowt.ie               1791                 :          35822 :             return HeapTupleSatisfiesHistoricMVCC(htup, snapshot, buffer);
 2420 andres@anarazel.de       1792                 :         350268 :         case SNAPSHOT_NON_VACUUMABLE:
 1083 pg@bowt.ie               1793                 :         350268 :             return HeapTupleSatisfiesNonVacuumable(htup, snapshot, buffer);
                               1794                 :                :     }
                               1795                 :                : 
 2420 andres@anarazel.de       1796                 :UBC           0 :     return false;               /* keep compiler quiet */
                               1797                 :                : }
        

Generated by: LCOV version 2.4-beta