LCOV - differential code coverage report
Current view: top level - src/backend/access/heap - heapam_visibility.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 68.2 % 607 414 193 414
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 16 16 16
Baseline: 16@8cea358b128 Branches: 57.6 % 644 371 273 371
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 68.2 % 607 414 193 414
Function coverage date bins:
(240..) days: 100.0 % 16 16 16
Branch coverage date bins:
(240..) days: 57.6 % 644 371 273 371

 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-2024, 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
 6088 tgl@sss.pgh.pa.us         114                 :CBC     9039584 : SetHintBits(HeapTupleHeader tuple, Buffer buffer,
                                115                 :                :             uint16 infomask, TransactionId xid)
                                116                 :                : {
 6101                           117         [ +  + ]:        9039584 :     if (TransactionIdIsValid(xid))
                                118                 :                :     {
                                119                 :                :         /* NB: xid must be known committed here! */
 5995 bruce@momjian.us          120                 :        8921123 :         XLogRecPtr  commitLSN = TransactionIdGetCommitLSN(xid);
                                121                 :                : 
 2981 andres@anarazel.de        122   [ +  +  +  +  :        9094900 :         if (BufferIsPermanent(buffer) && XLogNeedsFlush(commitLSN) &&
                                              +  + ]
                                123                 :         173777 :             BufferGetLSNAtomic(buffer) < commitLSN)
                                124                 :                :         {
                                125                 :                :             /* not flushed and no LSN interlock, so don't set hint */
                                126                 :         154556 :             return;
                                127                 :                :         }
                                128                 :                :     }
                                129                 :                : 
 6101 tgl@sss.pgh.pa.us         130                 :        8885028 :     tuple->t_infomask |= infomask;
 3954 jdavis@postgresql.or      131                 :        8885028 :     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
 6088 tgl@sss.pgh.pa.us         141                 :            172 : HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
                                142                 :                :                      uint16 infomask, TransactionId xid)
                                143                 :                : {
                                144                 :            172 :     SetHintBits(tuple, buffer, infomask, xid);
                                145                 :            172 : }
                                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
 3919 rhaas@postgresql.org      170                 :           2558 : HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                                171                 :                : {
                                172                 :           2558 :     HeapTupleHeader tuple = htup->t_data;
                                173                 :                : 
                                174         [ -  + ]:           2558 :     Assert(ItemPointerIsValid(&htup->t_self));
                                175         [ -  + ]:           2558 :     Assert(htup->t_tableOid != InvalidOid);
                                176                 :                : 
 3766                           177         [ +  + ]:           2558 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                178                 :                :     {
                                179         [ -  + ]:           2507 :         if (HeapTupleHeaderXminInvalid(tuple))
 9357 bruce@momjian.us          180                 :UBC           0 :             return false;
                                181                 :                : 
                                182                 :                :         /* Used by pre-9.0 binary upgrades */
 9149 vadim4o@yahoo.com         183         [ -  + ]:CBC        2507 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                184                 :                :         {
 7599 bruce@momjian.us          185         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                186                 :                : 
                                187         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9149 vadim4o@yahoo.com         188                 :              0 :                 return false;
 7599 bruce@momjian.us          189         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                190                 :                :             {
                                191         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                192                 :                :                 {
 6088 tgl@sss.pgh.pa.us         193                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                194                 :                :                                 InvalidTransactionId);
 8152                           195                 :              0 :                     return false;
                                196                 :                :                 }
 6088                           197                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                198                 :                :                             InvalidTransactionId);
                                199                 :                :             }
                                200                 :                :         }
                                201                 :                :         /* Used by pre-9.0 binary upgrades */
 9149 vadim4o@yahoo.com         202         [ -  + ]:CBC        2507 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                203                 :                :         {
 7599 bruce@momjian.us          204         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                205                 :                : 
                                206         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                207                 :                :             {
                                208         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8152 tgl@sss.pgh.pa.us         209                 :              0 :                     return false;
 7599 bruce@momjian.us          210         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6088 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);
 8152                           217                 :              0 :                     return false;
                                218                 :                :                 }
                                219                 :                :             }
                                220                 :                :         }
 3766 rhaas@postgresql.org      221         [ +  - ]:CBC        2507 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                222                 :                :         {
 9660 vadim4o@yahoo.com         223         [ +  + ]:           2507 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
 9357 bruce@momjian.us          224                 :           2446 :                 return true;
                                225                 :                : 
 3973                           226   [ +  +  -  + ]:             61 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 6926 tgl@sss.pgh.pa.us         227                 :             10 :                 return true;
                                228                 :                : 
 4099 alvherre@alvh.no-ip.      229         [ -  + ]:             51 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                230                 :                :             {
                                231                 :                :                 TransactionId xmax;
                                232                 :                : 
 4099 alvherre@alvh.no-ip.      233                 :UBC           0 :                 xmax = HeapTupleGetUpdateXid(tuple);
                                234                 :                : 
                                235                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 3789                           236         [ #  # ]:              0 :                 Assert(TransactionIdIsValid(xmax));
                                237                 :                : 
                                238                 :                :                 /* updating subtransaction must have aborted */
 4099                           239         [ #  # ]:              0 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                                240                 :              0 :                     return true;
                                241                 :                :                 else
                                242                 :              0 :                     return false;
                                243                 :                :             }
                                244                 :                : 
 4099 alvherre@alvh.no-ip.      245         [ +  + ]:CBC          51 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                246                 :                :             {
                                247                 :                :                 /* deleting subtransaction must have aborted */
 6088 tgl@sss.pgh.pa.us         248                 :              9 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                249                 :                :                             InvalidTransactionId);
 7227                           250                 :              9 :                 return true;
                                251                 :                :             }
                                252                 :                : 
 9252 vadim4o@yahoo.com         253                 :             42 :             return false;
                                254                 :                :         }
 3766 rhaas@postgresql.org      255         [ #  # ]:UBC           0 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 9357 bruce@momjian.us          256                 :              0 :             return false;
 3766 rhaas@postgresql.org      257         [ #  # ]:              0 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6088 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);
 6917                           265                 :              0 :             return false;
                                266                 :                :         }
                                267                 :                :     }
                                268                 :                : 
                                269                 :                :     /* by here, the inserting transaction has committed */
                                270                 :                : 
 9660 vadim4o@yahoo.com         271         [ +  - ]:CBC          51 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
 9357 bruce@momjian.us          272                 :             51 :         return true;
                                273                 :                : 
 9660 vadim4o@yahoo.com         274         [ #  # ]:UBC           0 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                275                 :                :     {
 4099 alvherre@alvh.no-ip.      276   [ #  #  #  # ]:              0 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9252 vadim4o@yahoo.com         277                 :              0 :             return true;
 9091 bruce@momjian.us          278                 :              0 :         return false;           /* updated by other */
                                279                 :                :     }
                                280                 :                : 
 6926 tgl@sss.pgh.pa.us         281         [ #  # ]:              0 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                282                 :                :     {
                                283                 :                :         TransactionId xmax;
                                284                 :                : 
 4099 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 */
 3789                           291         [ #  # ]:              0 :         Assert(TransactionIdIsValid(xmax));
                                292                 :                : 
 4099                           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 */
 6926 tgl@sss.pgh.pa.us         300                 :              0 :         return true;
                                301                 :                :     }
                                302                 :                : 
 4099 alvherre@alvh.no-ip.      303         [ #  # ]:              0 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                304                 :                :     {
                                305   [ #  #  #  # ]:              0 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9252 vadim4o@yahoo.com         306                 :              0 :             return true;
 9357 bruce@momjian.us          307                 :              0 :         return false;
                                308                 :                :     }
                                309                 :                : 
 4099 alvherre@alvh.no-ip.      310         [ #  # ]:              0 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 6917 tgl@sss.pgh.pa.us         311                 :              0 :         return true;
                                312                 :                : 
 4099 alvherre@alvh.no-ip.      313         [ #  # ]:              0 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                314                 :                :     {
                                315                 :                :         /* it must have aborted or crashed */
 6088 tgl@sss.pgh.pa.us         316                 :              0 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                317                 :                :                     InvalidTransactionId);
 9357 bruce@momjian.us          318                 :              0 :         return true;
                                319                 :                :     }
                                320                 :                : 
                                321                 :                :     /* xmax transaction committed */
                                322                 :                : 
 4099 alvherre@alvh.no-ip.      323   [ #  #  #  # ]:              0 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                324                 :                :     {
 6088 tgl@sss.pgh.pa.us         325                 :              0 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                326                 :                :                     InvalidTransactionId);
 9252 vadim4o@yahoo.com         327                 :              0 :         return true;
                                328                 :                :     }
                                329                 :                : 
 6088 tgl@sss.pgh.pa.us         330                 :              0 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                331                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 9357 bruce@momjian.us          332                 :              0 :     return false;
                                333                 :                : }
                                334                 :                : 
                                335                 :                : /*
                                336                 :                :  * HeapTupleSatisfiesAny
                                337                 :                :  *      Dummy "satisfies" routine: any tuple satisfies SnapshotAny.
                                338                 :                :  */
                                339                 :                : static bool
 3919 rhaas@postgresql.org      340                 :CBC     7807042 : HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                                341                 :                : {
 6230 tgl@sss.pgh.pa.us         342                 :        7807042 :     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
 3919 rhaas@postgresql.org      362                 :          71239 : HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
                                363                 :                :                         Buffer buffer)
                                364                 :                : {
                                365                 :          71239 :     HeapTupleHeader tuple = htup->t_data;
                                366                 :                : 
                                367         [ -  + ]:          71239 :     Assert(ItemPointerIsValid(&htup->t_self));
                                368         [ -  + ]:          71239 :     Assert(htup->t_tableOid != InvalidOid);
                                369                 :                : 
 3766                           370         [ +  + ]:          71239 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                371                 :                :     {
                                372         [ -  + ]:          56205 :         if (HeapTupleHeaderXminInvalid(tuple))
 8124 tgl@sss.pgh.pa.us         373                 :UBC           0 :             return false;
                                374                 :                : 
                                375                 :                :         /* Used by pre-9.0 binary upgrades */
 8124 tgl@sss.pgh.pa.us         376         [ -  + ]:CBC       56205 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                377                 :                :         {
 7599 bruce@momjian.us          378         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                379                 :                : 
                                380         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8124 tgl@sss.pgh.pa.us         381                 :              0 :                 return false;
 7599 bruce@momjian.us          382         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                383                 :                :             {
                                384         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                385                 :                :                 {
 6088 tgl@sss.pgh.pa.us         386                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                387                 :                :                                 InvalidTransactionId);
 8124                           388                 :              0 :                     return false;
                                389                 :                :                 }
 6088                           390                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                391                 :                :                             InvalidTransactionId);
                                392                 :                :             }
                                393                 :                :         }
                                394                 :                :         /* Used by pre-9.0 binary upgrades */
 8124 tgl@sss.pgh.pa.us         395         [ -  + ]:CBC       56205 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                396                 :                :         {
 7599 bruce@momjian.us          397         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                398                 :                : 
                                399         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                400                 :                :             {
                                401         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8124 tgl@sss.pgh.pa.us         402                 :              0 :                     return false;
 7599 bruce@momjian.us          403         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6088 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);
 8124                           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                 :                :          */
 3264 andres@anarazel.de        420   [ +  -  -  + ]:CBC       56205 :         else if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple)))
 3264 andres@anarazel.de        421                 :UBC           0 :             return false;
                                422                 :                :     }
                                423                 :                : 
                                424                 :                :     /* otherwise assume the tuple is valid for TOAST. */
 8124 tgl@sss.pgh.pa.us         425                 :CBC       71239 :     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
 3919 rhaas@postgresql.org      458                 :        1792551 : HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
                                459                 :                :                          Buffer buffer)
                                460                 :                : {
                                461                 :        1792551 :     HeapTupleHeader tuple = htup->t_data;
                                462                 :                : 
                                463         [ -  + ]:        1792551 :     Assert(ItemPointerIsValid(&htup->t_self));
                                464         [ -  + ]:        1792551 :     Assert(htup->t_tableOid != InvalidOid);
                                465                 :                : 
 3766                           466         [ +  + ]:        1792551 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                467                 :                :     {
                                468         [ -  + ]:         195160 :         if (HeapTupleHeaderXminInvalid(tuple))
 1849 andres@anarazel.de        469                 :UBC           0 :             return TM_Invisible;
                                470                 :                : 
                                471                 :                :         /* Used by pre-9.0 binary upgrades */
 8152 tgl@sss.pgh.pa.us         472         [ -  + ]:CBC      195160 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                473                 :                :         {
 7599 bruce@momjian.us          474         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                475                 :                : 
                                476         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 1849 andres@anarazel.de        477                 :              0 :                 return TM_Invisible;
 7599 bruce@momjian.us          478         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                479                 :                :             {
                                480         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                481                 :                :                 {
 6088 tgl@sss.pgh.pa.us         482                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                483                 :                :                                 InvalidTransactionId);
 1849 andres@anarazel.de        484                 :              0 :                     return TM_Invisible;
                                485                 :                :                 }
 6088 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 */
 8152 tgl@sss.pgh.pa.us         491         [ -  + ]:CBC      195160 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                492                 :                :         {
 7599 bruce@momjian.us          493         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                494                 :                : 
                                495         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                496                 :                :             {
                                497         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 1849 andres@anarazel.de        498                 :              0 :                     return TM_Invisible;
 7599 bruce@momjian.us          499         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6088 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);
 1849 andres@anarazel.de        506                 :              0 :                     return TM_Invisible;
                                507                 :                :                 }
                                508                 :                :             }
                                509                 :                :         }
 3766 rhaas@postgresql.org      510         [ +  + ]:CBC      195160 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                511                 :                :         {
 7974 bruce@momjian.us          512         [ +  + ]:         192670 :             if (HeapTupleHeaderGetCmin(tuple) >= curcid)
 1849 andres@anarazel.de        513                 :             12 :                 return TM_Invisible;    /* inserted after scan started */
                                514                 :                : 
 7893 bruce@momjian.us          515         [ +  + ]:         192658 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
 1849 andres@anarazel.de        516                 :         152443 :                 return TM_Ok;
                                517                 :                : 
 3770 alvherre@alvh.no-ip.      518   [ +  +  -  + ]:          40215 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                519                 :                :             {
                                520                 :                :                 TransactionId xmax;
                                521                 :                : 
                                522                 :          40205 :                 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         [ +  + ]:          40205 :                 if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                532                 :                :                 {
 3292                           533         [ +  - ]:             31 :                     if (MultiXactIdIsRunning(xmax, true))
 1849 andres@anarazel.de        534                 :             31 :                         return TM_BeingModified;
                                535                 :                :                     else
 1849 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                 :                :                  */
 3770 alvherre@alvh.no-ip.      544         [ -  + ]:CBC       40174 :                 if (!TransactionIdIsInProgress(xmax))
 1849 andres@anarazel.de        545                 :UBC           0 :                     return TM_Ok;
 1849 andres@anarazel.de        546                 :CBC       40174 :                 return TM_BeingModified;
                                547                 :                :             }
                                548                 :                : 
 4099 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 */
 3789                           556         [ -  + ]:              7 :                 Assert(TransactionIdIsValid(xmax));
                                557                 :                : 
                                558                 :                :                 /* deleting subtransaction must have aborted */
 4099                           559         [ +  - ]:              7 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                                560                 :                :                 {
 3292                           561         [ +  - ]:              7 :                     if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
                                562                 :                :                                              false))
 1849 andres@anarazel.de        563                 :              7 :                         return TM_BeingModified;
 1849 andres@anarazel.de        564                 :UBC           0 :                     return TM_Ok;
                                565                 :                :                 }
                                566                 :                :                 else
                                567                 :                :                 {
 4099 alvherre@alvh.no-ip.      568         [ #  # ]:              0 :                     if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 1849 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                 :                : 
 4099 alvherre@alvh.no-ip.      575         [ -  + ]:CBC           3 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                576                 :                :             {
                                577                 :                :                 /* deleting subtransaction must have aborted */
 6088 tgl@sss.pgh.pa.us         578                 :UBC           0 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                579                 :                :                             InvalidTransactionId);
 1849 andres@anarazel.de        580                 :              0 :                 return TM_Ok;
                                581                 :                :             }
                                582                 :                : 
 7974 bruce@momjian.us          583         [ +  - ]:CBC           3 :             if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 1849 andres@anarazel.de        584                 :              3 :                 return TM_SelfModified; /* updated after scan started */
                                585                 :                :             else
 1849 andres@anarazel.de        586                 :UBC           0 :                 return TM_Invisible;    /* updated before scan started */
                                587                 :                :         }
 3766 rhaas@postgresql.org      588         [ -  + ]:CBC        2490 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
 1849 andres@anarazel.de        589                 :UBC           0 :             return TM_Invisible;
 3766 rhaas@postgresql.org      590         [ +  - ]:CBC        2490 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6088 tgl@sss.pgh.pa.us         591                 :           2490 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                592                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                                593                 :                :         else
                                594                 :                :         {
                                595                 :                :             /* it must have aborted or crashed */
 6088 tgl@sss.pgh.pa.us         596                 :UBC           0 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                597                 :                :                         InvalidTransactionId);
 1849 andres@anarazel.de        598                 :              0 :             return TM_Invisible;
                                599                 :                :         }
                                600                 :                :     }
                                601                 :                : 
                                602                 :                :     /* by here, the inserting transaction has committed */
                                603                 :                : 
 7893 bruce@momjian.us          604         [ +  + ]:CBC     1599881 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
 1849 andres@anarazel.de        605                 :        1552708 :         return TM_Ok;
                                606                 :                : 
 8152 tgl@sss.pgh.pa.us         607         [ +  + ]:          47173 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                608                 :                :     {
 4099 alvherre@alvh.no-ip.      609   [ +  -  -  + ]:            145 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 1849 andres@anarazel.de        610                 :UBC           0 :             return TM_Ok;
 1147 alvherre@alvh.no-ip.      611         [ +  - ]:CBC         145 :         if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 1849 andres@anarazel.de        612                 :            145 :             return TM_Updated;  /* updated by other */
                                613                 :                :         else
 1849 andres@anarazel.de        614                 :UBC           0 :             return TM_Deleted;  /* deleted by other */
                                615                 :                :     }
                                616                 :                : 
 6926 tgl@sss.pgh.pa.us         617         [ +  + ]:CBC       47028 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                618                 :                :     {
                                619                 :                :         TransactionId xmax;
                                620                 :                : 
 2851 alvherre@alvh.no-ip.      621   [ +  -  +  +  :            588 :         if (HEAP_LOCKED_UPGRADED(tuple->t_infomask))
                                              -  + ]
 1849 andres@anarazel.de        622                 :UBC           0 :             return TM_Ok;
                                623                 :                : 
 4099 alvherre@alvh.no-ip.      624   [ +  +  -  + ]:CBC         588 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                625                 :                :         {
 2851                           626         [ +  + ]:            551 :             if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), true))
 1849 andres@anarazel.de        627                 :             97 :                 return TM_BeingModified;
                                628                 :                : 
 4099 alvherre@alvh.no-ip.      629                 :            454 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
 1849 andres@anarazel.de        630                 :            454 :             return TM_Ok;
                                631                 :                :         }
                                632                 :                : 
 4099 alvherre@alvh.no-ip.      633                 :             37 :         xmax = HeapTupleGetUpdateXid(tuple);
 3547                           634         [ -  + ]:             37 :         if (!TransactionIdIsValid(xmax))
                                635                 :                :         {
 3547 alvherre@alvh.no-ip.      636         [ #  # ]:UBC           0 :             if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 1849 andres@anarazel.de        637                 :              0 :                 return TM_BeingModified;
                                638                 :                :         }
                                639                 :                : 
                                640                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 3789 alvherre@alvh.no-ip.      641         [ -  + ]:CBC          37 :         Assert(TransactionIdIsValid(xmax));
                                642                 :                : 
 4099                           643         [ -  + ]:             37 :         if (TransactionIdIsCurrentTransactionId(xmax))
                                644                 :                :         {
 4099 alvherre@alvh.no-ip.      645         [ #  # ]:UBC           0 :             if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 1849 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                 :                : 
 3547 alvherre@alvh.no-ip.      651         [ +  + ]:CBC          37 :         if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
 1849 andres@anarazel.de        652                 :             32 :             return TM_BeingModified;
                                653                 :                : 
 4099 alvherre@alvh.no-ip.      654         [ +  + ]:              5 :         if (TransactionIdDidCommit(xmax))
                                655                 :                :         {
 1147                           656         [ -  + ]:              1 :             if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 1849 andres@anarazel.de        657                 :UBC           0 :                 return TM_Updated;
                                658                 :                :             else
 1849 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                 :                : 
 3547 alvherre@alvh.no-ip.      667         [ +  - ]:              4 :         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                 :                :              */
 3789                           673                 :              4 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                674                 :                :                         InvalidTransactionId);
 1849 andres@anarazel.de        675                 :              4 :             return TM_Ok;
                                676                 :                :         }
                                677                 :                :         else
                                678                 :                :         {
                                679                 :                :             /* There are lockers running */
 1849 andres@anarazel.de        680                 :UBC           0 :             return TM_BeingModified;
                                681                 :                :         }
                                682                 :                :     }
                                683                 :                : 
 4099 alvherre@alvh.no-ip.      684         [ +  + ]:CBC       46440 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                685                 :                :     {
                                686   [ +  +  -  + ]:          41655 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 1849 andres@anarazel.de        687                 :          41579 :             return TM_BeingModified;
 7974 bruce@momjian.us          688         [ +  - ]:             76 :         if (HeapTupleHeaderGetCmax(tuple) >= curcid)
 1849 andres@anarazel.de        689                 :             76 :             return TM_SelfModified; /* updated after scan started */
                                690                 :                :         else
 1849 andres@anarazel.de        691                 :UBC           0 :             return TM_Invisible;    /* updated before scan started */
                                692                 :                :     }
                                693                 :                : 
 4099 alvherre@alvh.no-ip.      694         [ +  + ]:CBC        4785 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 1849 andres@anarazel.de        695                 :           1210 :         return TM_BeingModified;
                                696                 :                : 
 4099 alvherre@alvh.no-ip.      697         [ +  + ]:           3575 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                698                 :                :     {
                                699                 :                :         /* it must have aborted or crashed */
 6088 tgl@sss.pgh.pa.us         700                 :            195 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                701                 :                :                     InvalidTransactionId);
 1849 andres@anarazel.de        702                 :            195 :         return TM_Ok;
                                703                 :                :     }
                                704                 :                : 
                                705                 :                :     /* xmax transaction committed */
                                706                 :                : 
 4099 alvherre@alvh.no-ip.      707   [ +  +  -  + ]:           3380 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                708                 :                :     {
 6088 tgl@sss.pgh.pa.us         709                 :           3315 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                710                 :                :                     InvalidTransactionId);
 1849 andres@anarazel.de        711                 :           3315 :         return TM_Ok;
                                712                 :                :     }
                                713                 :                : 
 6088 tgl@sss.pgh.pa.us         714                 :             65 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                715                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 1147 alvherre@alvh.no-ip.      716         [ +  - ]:             65 :     if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid))
 1849 andres@anarazel.de        717                 :             65 :         return TM_Updated;      /* updated by other */
                                718                 :                :     else
 1849 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
 3919 rhaas@postgresql.org      743                 :CBC     5879439 : HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
                                744                 :                :                         Buffer buffer)
                                745                 :                : {
                                746                 :        5879439 :     HeapTupleHeader tuple = htup->t_data;
                                747                 :                : 
                                748         [ -  + ]:        5879439 :     Assert(ItemPointerIsValid(&htup->t_self));
                                749         [ -  + ]:        5879439 :     Assert(htup->t_tableOid != InvalidOid);
                                750                 :                : 
 6230 tgl@sss.pgh.pa.us         751                 :        5879439 :     snapshot->xmin = snapshot->xmax = InvalidTransactionId;
 3264 andres@anarazel.de        752                 :        5879439 :     snapshot->speculativeToken = 0;
                                753                 :                : 
 3766 rhaas@postgresql.org      754         [ +  + ]:        5879439 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                755                 :                :     {
                                756         [ +  + ]:        5576161 :         if (HeapTupleHeaderXminInvalid(tuple))
 9252 vadim4o@yahoo.com         757                 :            337 :             return false;
                                758                 :                : 
                                759                 :                :         /* Used by pre-9.0 binary upgrades */
 9149                           760         [ -  + ]:        5575824 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                761                 :                :         {
 7599 bruce@momjian.us          762         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                763                 :                : 
                                764         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9141 vadim4o@yahoo.com         765                 :              0 :                 return false;
 7599 bruce@momjian.us          766         [ #  # ]:              0 :             if (!TransactionIdIsInProgress(xvac))
                                767                 :                :             {
                                768         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                769                 :                :                 {
 6088 tgl@sss.pgh.pa.us         770                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                771                 :                :                                 InvalidTransactionId);
 8152                           772                 :              0 :                     return false;
                                773                 :                :                 }
 6088                           774                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                775                 :                :                             InvalidTransactionId);
                                776                 :                :             }
                                777                 :                :         }
                                778                 :                :         /* Used by pre-9.0 binary upgrades */
 9149 vadim4o@yahoo.com         779         [ -  + ]:CBC     5575824 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                780                 :                :         {
 7599 bruce@momjian.us          781         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                782                 :                : 
                                783         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                784                 :                :             {
                                785         [ #  # ]:              0 :                 if (TransactionIdIsInProgress(xvac))
 8152 tgl@sss.pgh.pa.us         786                 :              0 :                     return false;
 7599 bruce@momjian.us          787         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6088 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);
 9134 vadim4o@yahoo.com         794                 :              0 :                     return false;
                                795                 :                :                 }
                                796                 :                :             }
                                797                 :                :         }
 3766 rhaas@postgresql.org      798         [ +  + ]:CBC     5575824 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                                799                 :                :         {
 9252 vadim4o@yahoo.com         800         [ +  + ]:        5550964 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                                801                 :          30653 :                 return true;
                                802                 :                : 
 3973 bruce@momjian.us          803   [ +  +  -  + ]:        5520311 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 6926 tgl@sss.pgh.pa.us         804                 :           5040 :                 return true;
                                805                 :                : 
 4099 alvherre@alvh.no-ip.      806         [ +  + ]:        5515271 :             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 */
 3789                           813         [ -  + ]:             16 :                 Assert(TransactionIdIsValid(xmax));
                                814                 :                : 
                                815                 :                :                 /* updating subtransaction must have aborted */
 4099                           816         [ -  + ]:             16 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
 4099 alvherre@alvh.no-ip.      817                 :UBC           0 :                     return true;
                                818                 :                :                 else
 4099 alvherre@alvh.no-ip.      819                 :CBC          16 :                     return false;
                                820                 :                :             }
                                821                 :                : 
                                822         [ -  + ]:        5515255 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                823                 :                :             {
                                824                 :                :                 /* deleting subtransaction must have aborted */
 6088 tgl@sss.pgh.pa.us         825                 :UBC           0 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                826                 :                :                             InvalidTransactionId);
 7227                           827                 :              0 :                 return true;
                                828                 :                :             }
                                829                 :                : 
 9252 vadim4o@yahoo.com         830                 :CBC     5515255 :             return false;
                                831                 :                :         }
 3766 rhaas@postgresql.org      832         [ +  + ]:          24860 :         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                 :                :              */
 3264 andres@anarazel.de        840         [ +  + ]:             74 :             if (HeapTupleHeaderIsSpeculative(tuple))
                                841                 :                :             {
                                842                 :              2 :                 snapshot->speculativeToken =
                                843         [ -  + ]:              2 :                     HeapTupleHeaderGetSpeculativeToken(tuple);
                                844                 :                : 
                                845         [ -  + ]:              2 :                 Assert(snapshot->speculativeToken != 0);
                                846                 :                :             }
                                847                 :                : 
 3766 rhaas@postgresql.org      848                 :             74 :             snapshot->xmin = HeapTupleHeaderGetRawXmin(tuple);
                                849                 :                :             /* XXX shouldn't we fall through to look at xmax? */
 9091 bruce@momjian.us          850                 :             74 :             return true;        /* in insertion by other */
                                851                 :                :         }
 3766 rhaas@postgresql.org      852         [ +  + ]:          24786 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6088 tgl@sss.pgh.pa.us         853                 :          24498 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                854                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                                855                 :                :         else
                                856                 :                :         {
                                857                 :                :             /* it must have aborted or crashed */
                                858                 :            288 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                859                 :                :                         InvalidTransactionId);
 6917                           860                 :            288 :             return false;
                                861                 :                :         }
                                862                 :                :     }
                                863                 :                : 
                                864                 :                :     /* by here, the inserting transaction has committed */
                                865                 :                : 
 9252 vadim4o@yahoo.com         866         [ +  + ]:         327776 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
                                867                 :         132166 :         return true;
                                868                 :                : 
                                869         [ +  + ]:         195610 :     if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                                870                 :                :     {
 4099 alvherre@alvh.no-ip.      871   [ +  -  -  + ]:          59569 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 9252 vadim4o@yahoo.com         872                 :UBC           0 :             return true;
 9091 bruce@momjian.us          873                 :CBC       59569 :         return false;           /* updated by other */
                                874                 :                :     }
                                875                 :                : 
 6926 tgl@sss.pgh.pa.us         876         [ +  + ]:         136041 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                                877                 :                :     {
                                878                 :                :         TransactionId xmax;
                                879                 :                : 
 4099 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 */
 3789                           886         [ -  + ]:             17 :         Assert(TransactionIdIsValid(xmax));
                                887                 :                : 
 4099                           888         [ +  + ]:             17 :         if (TransactionIdIsCurrentTransactionId(xmax))
                                889                 :              1 :             return false;
                                890         [ -  + ]:             16 :         if (TransactionIdIsInProgress(xmax))
                                891                 :                :         {
 4099 alvherre@alvh.no-ip.      892                 :UBC           0 :             snapshot->xmax = xmax;
                                893                 :              0 :             return true;
                                894                 :                :         }
 4099 alvherre@alvh.no-ip.      895         [ +  - ]:CBC          16 :         if (TransactionIdDidCommit(xmax))
                                896                 :             16 :             return false;
                                897                 :                :         /* it must have aborted or crashed */
 6926 tgl@sss.pgh.pa.us         898                 :UBC           0 :         return true;
                                899                 :                :     }
                                900                 :                : 
 4099 alvherre@alvh.no-ip.      901         [ +  + ]:CBC      136011 :     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                                902                 :                :     {
                                903   [ +  +  -  + ]:          99454 :         if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 8686 inoue@tpf.co.jp           904                 :             22 :             return true;
 9252 vadim4o@yahoo.com         905                 :          99432 :         return false;
                                906                 :                :     }
                                907                 :                : 
 4099 alvherre@alvh.no-ip.      908         [ +  + ]:          36557 :     if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
                                909                 :                :     {
 3908                           910   [ +  +  +  - ]:             14 :         if (!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                911                 :             12 :             snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
 6917 tgl@sss.pgh.pa.us         912                 :             14 :         return true;
                                913                 :                :     }
                                914                 :                : 
 4099 alvherre@alvh.no-ip.      915         [ +  + ]:          36543 :     if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                                916                 :                :     {
                                917                 :                :         /* it must have aborted or crashed */
 6088 tgl@sss.pgh.pa.us         918                 :             10 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                919                 :                :                     InvalidTransactionId);
 6917                           920                 :             10 :         return true;
                                921                 :                :     }
                                922                 :                : 
                                923                 :                :     /* xmax transaction committed */
                                924                 :                : 
 4099 alvherre@alvh.no-ip.      925   [ +  +  -  + ]:          36533 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                                926                 :                :     {
 6088 tgl@sss.pgh.pa.us         927                 :          13481 :         SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                                928                 :                :                     InvalidTransactionId);
 9252 vadim4o@yahoo.com         929                 :          13481 :         return true;
                                930                 :                :     }
                                931                 :                : 
 6088 tgl@sss.pgh.pa.us         932                 :          23052 :     SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                                933                 :                :                 HeapTupleHeaderGetRawXmax(tuple));
 9091 bruce@momjian.us          934                 :          23052 :     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
 3919 rhaas@postgresql.org      960                 :       66372578 : HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                                961                 :                :                        Buffer buffer)
                                962                 :                : {
                                963                 :       66372578 :     HeapTupleHeader tuple = htup->t_data;
                                964                 :                : 
                                965         [ -  + ]:       66372578 :     Assert(ItemPointerIsValid(&htup->t_self));
                                966         [ -  + ]:       66372578 :     Assert(htup->t_tableOid != InvalidOid);
                                967                 :                : 
 3766                           968         [ +  + ]:       66372578 :     if (!HeapTupleHeaderXminCommitted(tuple))
                                969                 :                :     {
                                970         [ +  + ]:       14407711 :         if (HeapTupleHeaderXminInvalid(tuple))
 9251 vadim4o@yahoo.com         971                 :          97832 :             return false;
                                972                 :                : 
                                973                 :                :         /* Used by pre-9.0 binary upgrades */
 9149                           974         [ -  + ]:       14309879 :         if (tuple->t_infomask & HEAP_MOVED_OFF)
                                975                 :                :         {
 7599 bruce@momjian.us          976         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                977                 :                : 
                                978         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 9149 vadim4o@yahoo.com         979                 :              0 :                 return false;
 3154 tgl@sss.pgh.pa.us         980         [ #  # ]:              0 :             if (!XidInMVCCSnapshot(xvac, snapshot))
                                981                 :                :             {
 7599 bruce@momjian.us          982         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
                                983                 :                :                 {
 6088 tgl@sss.pgh.pa.us         984                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                                985                 :                :                                 InvalidTransactionId);
 8152                           986                 :              0 :                     return false;
                                987                 :                :                 }
 6088                           988                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                                989                 :                :                             InvalidTransactionId);
                                990                 :                :             }
                                991                 :                :         }
                                992                 :                :         /* Used by pre-9.0 binary upgrades */
 9149 vadim4o@yahoo.com         993         [ -  + ]:CBC    14309879 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                                994                 :                :         {
 7599 bruce@momjian.us          995         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                                996                 :                : 
                                997         [ #  # ]:              0 :             if (!TransactionIdIsCurrentTransactionId(xvac))
                                998                 :                :             {
 3154 tgl@sss.pgh.pa.us         999         [ #  # ]:              0 :                 if (XidInMVCCSnapshot(xvac, snapshot))
 8152                          1000                 :              0 :                     return false;
 7599 bruce@momjian.us         1001         [ #  # ]:              0 :                 if (TransactionIdDidCommit(xvac))
 6088 tgl@sss.pgh.pa.us        1002                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1003                 :                :                                 InvalidTransactionId);
                               1004                 :                :                 else
                               1005                 :                :                 {
                               1006                 :              0 :                     SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1007                 :                :                                 InvalidTransactionId);
 8152                          1008                 :              0 :                     return false;
                               1009                 :                :                 }
                               1010                 :                :             }
                               1011                 :                :         }
 3766 rhaas@postgresql.org     1012         [ +  + ]:CBC    14309879 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                               1013                 :                :         {
 7974 bruce@momjian.us         1014         [ +  + ]:       10666730 :             if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
 9251 vadim4o@yahoo.com        1015                 :           6272 :                 return false;   /* inserted after scan started */
                               1016                 :                : 
                               1017         [ +  + ]:       10660458 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                               1018                 :        7810215 :                 return true;
                               1019                 :                : 
 3973 bruce@momjian.us         1020   [ +  +  -  + ]:        2850243 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
 6926 tgl@sss.pgh.pa.us        1021                 :           2145 :                 return true;
                               1022                 :                : 
 4099 alvherre@alvh.no-ip.     1023         [ +  + ]:        2848098 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1024                 :                :             {
                               1025                 :                :                 TransactionId xmax;
                               1026                 :                : 
                               1027                 :              7 :                 xmax = HeapTupleGetUpdateXid(tuple);
                               1028                 :                : 
                               1029                 :                :                 /* not LOCKED_ONLY, so it has to have an xmax */
 3789                          1030         [ -  + ]:              7 :                 Assert(TransactionIdIsValid(xmax));
                               1031                 :                : 
                               1032                 :                :                 /* updating subtransaction must have aborted */
 4099                          1033         [ +  - ]:              7 :                 if (!TransactionIdIsCurrentTransactionId(xmax))
                               1034                 :              7 :                     return true;
 4099 alvherre@alvh.no-ip.     1035         [ #  # ]:UBC           0 :                 else if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
                               1036                 :              0 :                     return true;    /* updated after scan started */
                               1037                 :                :                 else
 2489 tgl@sss.pgh.pa.us        1038                 :              0 :                     return false;   /* updated before scan started */
                               1039                 :                :             }
                               1040                 :                : 
 4099 alvherre@alvh.no-ip.     1041         [ +  + ]:CBC     2848091 :             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                               1042                 :                :             {
                               1043                 :                :                 /* deleting subtransaction must have aborted */
 6088 tgl@sss.pgh.pa.us        1044                 :             17 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1045                 :                :                             InvalidTransactionId);
 7227                          1046                 :             17 :                 return true;
                               1047                 :                :             }
                               1048                 :                : 
 7974 bruce@momjian.us         1049         [ +  + ]:        2848074 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 9251 vadim4o@yahoo.com        1050                 :            682 :                 return true;    /* deleted after scan started */
                               1051                 :                :             else
                               1052                 :        2847392 :                 return false;   /* deleted before scan started */
                               1053                 :                :         }
 3154 tgl@sss.pgh.pa.us        1054         [ +  + ]:        3643149 :         else if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
 9251 vadim4o@yahoo.com        1055                 :          10543 :             return false;
 3766 rhaas@postgresql.org     1056         [ +  + ]:        3632606 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6088 tgl@sss.pgh.pa.us        1057                 :        3582831 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1058                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                               1059                 :                :         else
                               1060                 :                :         {
                               1061                 :                :             /* it must have aborted or crashed */
                               1062                 :          49775 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1063                 :                :                         InvalidTransactionId);
 6917                          1064                 :          49775 :             return false;
                               1065                 :                :         }
                               1066                 :                :     }
                               1067                 :                :     else
                               1068                 :                :     {
                               1069                 :                :         /* xmin is committed, but maybe not according to our snapshot */
 3154                          1070   [ +  +  +  + ]:      101253001 :         if (!HeapTupleHeaderXminFrozen(tuple) &&
                               1071                 :       49288134 :             XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
                               1072                 :           1365 :             return false;       /* treat as still in progress */
                               1073                 :                :     }
                               1074                 :                : 
                               1075                 :                :     /* by here, the inserting transaction has committed */
                               1076                 :                : 
 9251 vadim4o@yahoo.com        1077         [ +  + ]:       55546333 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid or aborted */
                               1078                 :       52615864 :         return true;
                               1079                 :                : 
 4099 alvherre@alvh.no-ip.     1080   [ +  +  -  + ]:        2930469 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 6926 tgl@sss.pgh.pa.us        1081                 :          42058 :         return true;
                               1082                 :                : 
                               1083         [ +  + ]:        2888411 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1084                 :                :     {
                               1085                 :                :         TransactionId xmax;
                               1086                 :                : 
                               1087                 :                :         /* already checked above */
 4099 alvherre@alvh.no-ip.     1088   [ +  -  -  + ]:            166 :         Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
                               1089                 :                : 
                               1090                 :            166 :         xmax = HeapTupleGetUpdateXid(tuple);
                               1091                 :                : 
                               1092                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 3789                          1093         [ -  + ]:            166 :         Assert(TransactionIdIsValid(xmax));
                               1094                 :                : 
 4099                          1095         [ +  + ]:            166 :         if (TransactionIdIsCurrentTransactionId(xmax))
                               1096                 :                :         {
                               1097         [ -  + ]:             23 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 4099 alvherre@alvh.no-ip.     1098                 :UBC           0 :                 return true;    /* deleted after scan started */
                               1099                 :                :             else
 4099 alvherre@alvh.no-ip.     1100                 :CBC          23 :                 return false;   /* deleted before scan started */
                               1101                 :                :         }
 3154 tgl@sss.pgh.pa.us        1102         [ +  + ]:            143 :         if (XidInMVCCSnapshot(xmax, snapshot))
 4099 alvherre@alvh.no-ip.     1103                 :             18 :             return true;
                               1104         [ +  + ]:            125 :         if (TransactionIdDidCommit(xmax))
 3154 tgl@sss.pgh.pa.us        1105                 :            120 :             return false;       /* updating transaction committed */
                               1106                 :                :         /* it must have aborted or crashed */
 9251 vadim4o@yahoo.com        1107                 :              5 :         return true;
                               1108                 :                :     }
                               1109                 :                : 
                               1110         [ +  + ]:        2888245 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1111                 :                :     {
 4099 alvherre@alvh.no-ip.     1112         [ +  + ]:         384138 :         if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
                               1113                 :                :         {
 7974 bruce@momjian.us         1114         [ +  + ]:          98878 :             if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
 9091                          1115                 :           1164 :                 return true;    /* deleted after scan started */
                               1116                 :                :             else
                               1117                 :          97714 :                 return false;   /* deleted before scan started */
                               1118                 :                :         }
                               1119                 :                : 
 3154 tgl@sss.pgh.pa.us        1120         [ +  + ]:         285260 :         if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
 6917                          1121                 :           5720 :             return true;
                               1122                 :                : 
 4099 alvherre@alvh.no-ip.     1123         [ +  + ]:         279540 :         if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
                               1124                 :                :         {
                               1125                 :                :             /* it must have aborted or crashed */
 6088 tgl@sss.pgh.pa.us        1126                 :           5424 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1127                 :                :                         InvalidTransactionId);
 9251 vadim4o@yahoo.com        1128                 :           5424 :             return true;
                               1129                 :                :         }
                               1130                 :                : 
                               1131                 :                :         /* xmax transaction committed */
 6088 tgl@sss.pgh.pa.us        1132                 :         274116 :         SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                               1133                 :                :                     HeapTupleHeaderGetRawXmax(tuple));
                               1134                 :                :     }
                               1135                 :                :     else
                               1136                 :                :     {
                               1137                 :                :         /* xmax is committed, but maybe not according to our snapshot */
 3154                          1138         [ +  + ]:        2504107 :         if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
                               1139                 :            182 :             return true;        /* treat as still in progress */
                               1140                 :                :     }
                               1141                 :                : 
                               1142                 :                :     /* xmax transaction committed */
                               1143                 :                : 
 9251 vadim4o@yahoo.com        1144                 :        2778041 :     return false;
                               1145                 :                : }
                               1146                 :                : 
                               1147                 :                : 
                               1148                 :                : /*
                               1149                 :                :  * HeapTupleSatisfiesVacuum
                               1150                 :                :  *
                               1151                 :                :  *  Determine the status of tuples for VACUUM purposes.  Here, what
                               1152                 :                :  *  we mainly want to know is if a tuple is potentially visible to *any*
                               1153                 :                :  *  running transaction.  If so, it can't be removed yet by VACUUM.
                               1154                 :                :  *
                               1155                 :                :  * OldestXmin is a cutoff XID (obtained from
                               1156                 :                :  * GetOldestNonRemovableTransactionId()).  Tuples deleted by XIDs >=
                               1157                 :                :  * OldestXmin are deemed "recently dead"; they might still be visible to some
                               1158                 :                :  * open transaction, so we can't remove them, even if we see that the deleting
                               1159                 :                :  * transaction has committed.
                               1160                 :                :  */
                               1161                 :                : HTSV_Result
 3919 rhaas@postgresql.org     1162                 :       22316087 : HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
                               1163                 :                :                          Buffer buffer)
                               1164                 :                : {
 1341 andres@anarazel.de       1165                 :       22316087 :     TransactionId dead_after = InvalidTransactionId;
                               1166                 :                :     HTSV_Result res;
                               1167                 :                : 
                               1168                 :       22316087 :     res = HeapTupleSatisfiesVacuumHorizon(htup, buffer, &dead_after);
                               1169                 :                : 
                               1170         [ +  + ]:       22316087 :     if (res == HEAPTUPLE_RECENTLY_DEAD)
                               1171                 :                :     {
                               1172         [ -  + ]:         269407 :         Assert(TransactionIdIsValid(dead_after));
                               1173                 :                : 
                               1174         [ +  + ]:         269407 :         if (TransactionIdPrecedes(dead_after, OldestXmin))
                               1175                 :          29334 :             res = HEAPTUPLE_DEAD;
                               1176                 :                :     }
                               1177                 :                :     else
                               1178         [ -  + ]:       22046680 :         Assert(!TransactionIdIsValid(dead_after));
                               1179                 :                : 
                               1180                 :       22316087 :     return res;
                               1181                 :                : }
                               1182                 :                : 
                               1183                 :                : /*
                               1184                 :                :  * Work horse for HeapTupleSatisfiesVacuum and similar routines.
                               1185                 :                :  *
                               1186                 :                :  * In contrast to HeapTupleSatisfiesVacuum this routine, when encountering a
                               1187                 :                :  * tuple that could still be visible to some backend, stores the xid that
                               1188                 :                :  * needs to be compared with the horizon in *dead_after, and returns
                               1189                 :                :  * HEAPTUPLE_RECENTLY_DEAD. The caller then can perform the comparison with
                               1190                 :                :  * the horizon.  This is e.g. useful when comparing with different horizons.
                               1191                 :                :  *
                               1192                 :                :  * Note: HEAPTUPLE_DEAD can still be returned here, e.g. if the inserting
                               1193                 :                :  * transaction aborted.
                               1194                 :                :  */
                               1195                 :                : HTSV_Result
                               1196                 :       40646879 : HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *dead_after)
                               1197                 :                : {
 3919 rhaas@postgresql.org     1198                 :       40646879 :     HeapTupleHeader tuple = htup->t_data;
                               1199                 :                : 
                               1200         [ -  + ]:       40646879 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1201         [ -  + ]:       40646879 :     Assert(htup->t_tableOid != InvalidOid);
 1341 andres@anarazel.de       1202         [ -  + ]:       40646879 :     Assert(dead_after != NULL);
                               1203                 :                : 
                               1204                 :       40646879 :     *dead_after = InvalidTransactionId;
                               1205                 :                : 
                               1206                 :                :     /*
                               1207                 :                :      * Has inserting transaction committed?
                               1208                 :                :      *
                               1209                 :                :      * If the inserting transaction aborted, then the tuple was never visible
                               1210                 :                :      * to any other transaction, so we can delete it immediately.
                               1211                 :                :      */
 3766 rhaas@postgresql.org     1212         [ +  + ]:       40646879 :     if (!HeapTupleHeaderXminCommitted(tuple))
                               1213                 :                :     {
                               1214         [ +  + ]:        5848300 :         if (HeapTupleHeaderXminInvalid(tuple))
 8312 tgl@sss.pgh.pa.us        1215                 :           9502 :             return HEAPTUPLE_DEAD;
                               1216                 :                :         /* Used by pre-9.0 binary upgrades */
                               1217         [ -  + ]:        5838798 :         else if (tuple->t_infomask & HEAP_MOVED_OFF)
                               1218                 :                :         {
 7599 bruce@momjian.us         1219         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                               1220                 :                : 
                               1221         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8152 tgl@sss.pgh.pa.us        1222                 :              0 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
 7599 bruce@momjian.us         1223         [ #  # ]:              0 :             if (TransactionIdIsInProgress(xvac))
 8152 tgl@sss.pgh.pa.us        1224                 :              0 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
 7599 bruce@momjian.us         1225         [ #  # ]:              0 :             if (TransactionIdDidCommit(xvac))
                               1226                 :                :             {
 6088 tgl@sss.pgh.pa.us        1227                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1228                 :                :                             InvalidTransactionId);
 8312                          1229                 :              0 :                 return HEAPTUPLE_DEAD;
                               1230                 :                :             }
 6088                          1231                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1232                 :                :                         InvalidTransactionId);
                               1233                 :                :         }
                               1234                 :                :         /* Used by pre-9.0 binary upgrades */
 8312 tgl@sss.pgh.pa.us        1235         [ -  + ]:CBC     5838798 :         else if (tuple->t_infomask & HEAP_MOVED_IN)
                               1236                 :                :         {
 7599 bruce@momjian.us         1237         [ #  # ]:UBC           0 :             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
                               1238                 :                : 
                               1239         [ #  # ]:              0 :             if (TransactionIdIsCurrentTransactionId(xvac))
 8152 tgl@sss.pgh.pa.us        1240                 :              0 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
 7599 bruce@momjian.us         1241         [ #  # ]:              0 :             if (TransactionIdIsInProgress(xvac))
 8152 tgl@sss.pgh.pa.us        1242                 :              0 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
 7599 bruce@momjian.us         1243         [ #  # ]:              0 :             if (TransactionIdDidCommit(xvac))
 6088 tgl@sss.pgh.pa.us        1244                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1245                 :                :                             InvalidTransactionId);
                               1246                 :                :             else
                               1247                 :                :             {
                               1248                 :              0 :                 SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1249                 :                :                             InvalidTransactionId);
 8312                          1250                 :              0 :                 return HEAPTUPLE_DEAD;
                               1251                 :                :             }
                               1252                 :                :         }
 3602 andres@anarazel.de       1253         [ +  + ]:CBC     5838798 :         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                               1254                 :                :         {
 7510 tgl@sss.pgh.pa.us        1255         [ +  + ]:        2042798 :             if (tuple->t_infomask & HEAP_XMAX_INVALID)   /* xid invalid */
                               1256                 :        2007752 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1257                 :                :             /* only locked? run infomask-only check first, for performance */
 3922 alvherre@alvh.no-ip.     1258   [ +  +  +  -  :          61963 :             if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
                                              -  + ]
                               1259                 :          26917 :                 HeapTupleHeaderIsOnlyLocked(tuple))
 7510 tgl@sss.pgh.pa.us        1260                 :           8129 :                 return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1261                 :                :             /* inserted and then deleted by same xact */
 3602 andres@anarazel.de       1262   [ +  -  -  +  :          26917 :             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
                                        -  -  +  - ]
                               1263                 :          26917 :                 return HEAPTUPLE_DELETE_IN_PROGRESS;
                               1264                 :                :             /* deleting subtransaction must have aborted */
 3602 andres@anarazel.de       1265                 :UBC           0 :             return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1266                 :                :         }
 3602 andres@anarazel.de       1267         [ +  + ]:CBC     3796000 :         else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
                               1268                 :                :         {
                               1269                 :                :             /*
                               1270                 :                :              * It'd be possible to discern between INSERT/DELETE in progress
                               1271                 :                :              * here by looking at xmax - but that doesn't seem beneficial for
                               1272                 :                :              * the majority of callers and even detrimental for some. We'd
                               1273                 :                :              * rather have callers look at/wait for xmin than xmax. It's
                               1274                 :                :              * always correct to return INSERT_IN_PROGRESS because that's
                               1275                 :                :              * what's happening from the view of other backends.
                               1276                 :                :              */
                               1277                 :           3420 :             return HEAPTUPLE_INSERT_IN_PROGRESS;
                               1278                 :                :         }
 3766 rhaas@postgresql.org     1279         [ +  + ]:        3792580 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
 6088 tgl@sss.pgh.pa.us        1280                 :        3761784 :             SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
                               1281                 :                :                         HeapTupleHeaderGetRawXmin(tuple));
                               1282                 :                :         else
                               1283                 :                :         {
                               1284                 :                :             /*
                               1285                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed
                               1286                 :                :              */
                               1287                 :          30796 :             SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
                               1288                 :                :                         InvalidTransactionId);
 8312                          1289                 :          30796 :             return HEAPTUPLE_DEAD;
                               1290                 :                :         }
                               1291                 :                : 
                               1292                 :                :         /*
                               1293                 :                :          * At this point the xmin is known committed, but we might not have
                               1294                 :                :          * been able to set the hint bit yet; so we can no longer Assert that
                               1295                 :                :          * it's set.
                               1296                 :                :          */
                               1297                 :                :     }
                               1298                 :                : 
                               1299                 :                :     /*
                               1300                 :                :      * Okay, the inserter committed, so it was good at some point.  Now what
                               1301                 :                :      * about the deleting transaction?
                               1302                 :                :      */
                               1303         [ +  + ]:       38560363 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1304                 :       32866744 :         return HEAPTUPLE_LIVE;
                               1305                 :                : 
 4099 alvherre@alvh.no-ip.     1306   [ +  +  -  + ]:        5693619 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                               1307                 :                :     {
                               1308                 :                :         /*
                               1309                 :                :          * "Deleting" xact really only locked it, so the tuple is live in any
                               1310                 :                :          * case.  However, we should make sure that either XMAX_COMMITTED or
                               1311                 :                :          * XMAX_INVALID gets set once the xact is gone, to reduce the costs of
                               1312                 :                :          * examining the tuple for future xacts.
                               1313                 :                :          */
 8129 tgl@sss.pgh.pa.us        1314         [ +  - ]:          13220 :         if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1315                 :                :         {
 6926                          1316         [ +  + ]:          13220 :             if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1317                 :                :             {
                               1318                 :                :                 /*
                               1319                 :                :                  * If it's a pre-pg_upgrade tuple, the multixact cannot
                               1320                 :                :                  * possibly be running; otherwise have to check.
                               1321                 :                :                  */
 2851 alvherre@alvh.no-ip.     1322   [ +  -  +  -  :            418 :                 if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
                                        +  -  +  + ]
 3547                          1323                 :            209 :                     MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
                               1324                 :                :                                          true))
 6926 tgl@sss.pgh.pa.us        1325                 :              4 :                     return HEAPTUPLE_LIVE;
 4099 alvherre@alvh.no-ip.     1326                 :            205 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
                               1327                 :                :             }
                               1328                 :                :             else
                               1329                 :                :             {
                               1330         [ -  + ]:          13011 :                 if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 6926 tgl@sss.pgh.pa.us        1331                 :UBC           0 :                     return HEAPTUPLE_LIVE;
 4099 alvherre@alvh.no-ip.     1332                 :CBC       13011 :                 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1333                 :                :                             InvalidTransactionId);
                               1334                 :                :             }
                               1335                 :                :         }
                               1336                 :                : 
                               1337                 :                :         /*
                               1338                 :                :          * We don't really care whether xmax did commit, abort or crash. We
                               1339                 :                :          * know that xmax did lock the tuple, but it did not and will never
                               1340                 :                :          * actually update it.
                               1341                 :                :          */
                               1342                 :                : 
 8152 tgl@sss.pgh.pa.us        1343                 :          13216 :         return HEAPTUPLE_LIVE;
                               1344                 :                :     }
                               1345                 :                : 
 6926                          1346         [ +  + ]:        5680399 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1347                 :                :     {
 2354 andres@anarazel.de       1348                 :              6 :         TransactionId xmax = HeapTupleGetUpdateXid(tuple);
                               1349                 :                : 
                               1350                 :                :         /* already checked above */
                               1351   [ +  -  -  + ]:              6 :         Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
                               1352                 :                : 
                               1353                 :                :         /* not LOCKED_ONLY, so it has to have an xmax */
 3789 alvherre@alvh.no-ip.     1354         [ -  + ]:              6 :         Assert(TransactionIdIsValid(xmax));
                               1355                 :                : 
 2354 andres@anarazel.de       1356         [ -  + ]:              6 :         if (TransactionIdIsInProgress(xmax))
 2354 andres@anarazel.de       1357                 :UBC           0 :             return HEAPTUPLE_DELETE_IN_PROGRESS;
 2354 andres@anarazel.de       1358         [ +  - ]:CBC           6 :         else if (TransactionIdDidCommit(xmax))
                               1359                 :                :         {
                               1360                 :                :             /*
                               1361                 :                :              * The multixact might still be running due to lockers.  Need to
                               1362                 :                :              * allow for pruning if below the xid horizon regardless --
                               1363                 :                :              * otherwise we could end up with a tuple where the updater has to
                               1364                 :                :              * be removed due to the horizon, but is not pruned away.  It's
                               1365                 :                :              * not a problem to prune that tuple, because any remaining
                               1366                 :                :              * lockers will also be present in newer tuple versions.
                               1367                 :                :              */
 1341                          1368                 :              6 :             *dead_after = xmax;
                               1369                 :              6 :             return HEAPTUPLE_RECENTLY_DEAD;
                               1370                 :                :         }
 2354 andres@anarazel.de       1371         [ #  # ]:UBC           0 :         else if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
                               1372                 :                :         {
                               1373                 :                :             /*
                               1374                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed.
                               1375                 :                :              * Mark the Xmax as invalid.
                               1376                 :                :              */
                               1377                 :              0 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
                               1378                 :                :         }
                               1379                 :                : 
 3789 alvherre@alvh.no-ip.     1380                 :              0 :         return HEAPTUPLE_LIVE;
                               1381                 :                :     }
                               1382                 :                : 
 8312 tgl@sss.pgh.pa.us        1383         [ +  + ]:CBC     5680393 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1384                 :                :     {
 4099 alvherre@alvh.no-ip.     1385         [ +  + ]:        4951822 :         if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
 8308 tgl@sss.pgh.pa.us        1386                 :        3698230 :             return HEAPTUPLE_DELETE_IN_PROGRESS;
 4099 alvherre@alvh.no-ip.     1387         [ +  + ]:        1253592 :         else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
 6088 tgl@sss.pgh.pa.us        1388                 :        1252171 :             SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
                               1389                 :                :                         HeapTupleHeaderGetRawXmax(tuple));
                               1390                 :                :         else
                               1391                 :                :         {
                               1392                 :                :             /*
                               1393                 :                :              * Not in Progress, Not Committed, so either Aborted or crashed
                               1394                 :                :              */
                               1395                 :           1421 :             SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
                               1396                 :                :                         InvalidTransactionId);
 8312                          1397                 :           1421 :             return HEAPTUPLE_LIVE;
                               1398                 :                :         }
                               1399                 :                : 
                               1400                 :                :         /*
                               1401                 :                :          * At this point the xmax is known committed, but we might not have
                               1402                 :                :          * been able to set the hint bit yet; so we can no longer Assert that
                               1403                 :                :          * it's set.
                               1404                 :                :          */
                               1405                 :                :     }
                               1406                 :                : 
                               1407                 :                :     /*
                               1408                 :                :      * Deleter committed, allow caller to check if it was recent enough that
                               1409                 :                :      * some open transactions could still see the tuple.
                               1410                 :                :      */
 1341 andres@anarazel.de       1411                 :        1980742 :     *dead_after = HeapTupleHeaderGetRawXmax(tuple);
                               1412                 :        1980742 :     return HEAPTUPLE_RECENTLY_DEAD;
                               1413                 :                : }
                               1414                 :                : 
                               1415                 :                : 
                               1416                 :                : /*
                               1417                 :                :  * HeapTupleSatisfiesNonVacuumable
                               1418                 :                :  *
                               1419                 :                :  *  True if tuple might be visible to some transaction; false if it's
                               1420                 :                :  *  surely dead to everyone, ie, vacuumable.
                               1421                 :                :  *
                               1422                 :                :  *  See SNAPSHOT_NON_VACUUMABLE's definition for the intended behaviour.
                               1423                 :                :  *
                               1424                 :                :  *  This is an interface to HeapTupleSatisfiesVacuum that's callable via
                               1425                 :                :  *  HeapTupleSatisfiesSnapshot, so it can be used through a Snapshot.
                               1426                 :                :  *  snapshot->vistest must have been set up with the horizon to use.
                               1427                 :                :  */
                               1428                 :                : static bool
 2411 tgl@sss.pgh.pa.us        1429                 :         303685 : HeapTupleSatisfiesNonVacuumable(HeapTuple htup, Snapshot snapshot,
                               1430                 :                :                                 Buffer buffer)
                               1431                 :                : {
 1341 andres@anarazel.de       1432                 :         303685 :     TransactionId dead_after = InvalidTransactionId;
                               1433                 :                :     HTSV_Result res;
                               1434                 :                : 
                               1435                 :         303685 :     res = HeapTupleSatisfiesVacuumHorizon(htup, buffer, &dead_after);
                               1436                 :                : 
                               1437         [ +  + ]:         303685 :     if (res == HEAPTUPLE_RECENTLY_DEAD)
                               1438                 :                :     {
                               1439         [ -  + ]:          62064 :         Assert(TransactionIdIsValid(dead_after));
                               1440                 :                : 
                               1441         [ +  + ]:          62064 :         if (GlobalVisTestIsRemovableXid(snapshot->vistest, dead_after))
                               1442                 :          50464 :             res = HEAPTUPLE_DEAD;
                               1443                 :                :     }
                               1444                 :                :     else
                               1445         [ -  + ]:         241621 :         Assert(!TransactionIdIsValid(dead_after));
                               1446                 :                : 
                               1447                 :         303685 :     return res != HEAPTUPLE_DEAD;
                               1448                 :                : }
                               1449                 :                : 
                               1450                 :                : 
                               1451                 :                : /*
                               1452                 :                :  * HeapTupleIsSurelyDead
                               1453                 :                :  *
                               1454                 :                :  *  Cheaply determine whether a tuple is surely dead to all onlookers.
                               1455                 :                :  *  We sometimes use this in lieu of HeapTupleSatisfiesVacuum when the
                               1456                 :                :  *  tuple has just been tested by another visibility routine (usually
                               1457                 :                :  *  HeapTupleSatisfiesMVCC) and, therefore, any hint bits that can be set
                               1458                 :                :  *  should already be set.  We assume that if no hint bits are set, the xmin
                               1459                 :                :  *  or xmax transaction is still running.  This is therefore faster than
                               1460                 :                :  *  HeapTupleSatisfiesVacuum, because we consult neither procarray nor CLOG.
                               1461                 :                :  *  It's okay to return false when in doubt, but we must return true only
                               1462                 :                :  *  if the tuple is removable.
                               1463                 :                :  */
                               1464                 :                : bool
                               1465                 :        6285392 : HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
                               1466                 :                : {
 3919 rhaas@postgresql.org     1467                 :        6285392 :     HeapTupleHeader tuple = htup->t_data;
                               1468                 :                : 
                               1469         [ -  + ]:        6285392 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1470         [ -  + ]:        6285392 :     Assert(htup->t_tableOid != InvalidOid);
                               1471                 :                : 
                               1472                 :                :     /*
                               1473                 :                :      * If the inserting transaction is marked invalid, then it aborted, and
                               1474                 :                :      * the tuple is definitely dead.  If it's marked neither committed nor
                               1475                 :                :      * invalid, then we assume it's still alive (since the presumption is that
                               1476                 :                :      * all relevant hint bits were just set moments ago).
                               1477                 :                :      */
 3766                          1478         [ +  + ]:        6285392 :     if (!HeapTupleHeaderXminCommitted(tuple))
  949 michael@paquier.xyz      1479                 :        5622091 :         return HeapTupleHeaderXminInvalid(tuple);
                               1480                 :                : 
                               1481                 :                :     /*
                               1482                 :                :      * If the inserting transaction committed, but any deleting transaction
                               1483                 :                :      * aborted, the tuple is still alive.
                               1484                 :                :      */
 4099 alvherre@alvh.no-ip.     1485         [ +  + ]:         663301 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1486                 :             61 :         return false;
                               1487                 :                : 
                               1488                 :                :     /*
                               1489                 :                :      * If the XMAX is just a lock, the tuple is still alive.
                               1490                 :                :      */
                               1491   [ +  -  -  + ]:         663240 :     if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
 4099 alvherre@alvh.no-ip.     1492                 :UBC           0 :         return false;
                               1493                 :                : 
                               1494                 :                :     /*
                               1495                 :                :      * If the Xmax is a MultiXact, it might be dead or alive, but we cannot
                               1496                 :                :      * know without checking pg_multixact.
                               1497                 :                :      */
 4099 alvherre@alvh.no-ip.     1498         [ +  + ]:CBC      663240 :     if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
 4365 rhaas@postgresql.org     1499                 :             46 :         return false;
                               1500                 :                : 
                               1501                 :                :     /* If deleter isn't known to have committed, assume it's still running. */
                               1502         [ +  + ]:         663194 :     if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
                               1503                 :         172712 :         return false;
                               1504                 :                : 
                               1505                 :                :     /* Deleter committed, so tuple is dead if the XID is old enough. */
 1341 andres@anarazel.de       1506                 :         490482 :     return GlobalVisTestIsRemovableXid(vistest,
                               1507                 :                :                                        HeapTupleHeaderGetRawXmax(tuple));
                               1508                 :                : }
                               1509                 :                : 
                               1510                 :                : /*
                               1511                 :                :  * Is the tuple really only locked?  That is, is it not updated?
                               1512                 :                :  *
                               1513                 :                :  * It's easy to check just infomask bits if the locker is not a multi; but
                               1514                 :                :  * otherwise we need to verify that the updating transaction has not aborted.
                               1515                 :                :  *
                               1516                 :                :  * This function is here because it follows the same visibility rules laid out
                               1517                 :                :  * at the top of this file.
                               1518                 :                :  */
                               1519                 :                : bool
 4099 alvherre@alvh.no-ip.     1520                 :          60986 : HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
                               1521                 :                : {
                               1522                 :                :     TransactionId xmax;
                               1523                 :                : 
                               1524                 :                :     /* if there's no valid Xmax, then there's obviously no update either */
                               1525         [ -  + ]:          60986 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
 4099 alvherre@alvh.no-ip.     1526                 :UBC           0 :         return true;
                               1527                 :                : 
 4099 alvherre@alvh.no-ip.     1528         [ +  + ]:CBC       60986 :     if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
                               1529                 :            522 :         return true;
                               1530                 :                : 
                               1531                 :                :     /* invalid xmax means no update */
                               1532         [ -  + ]:          60464 :     if (!TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple)))
 4099 alvherre@alvh.no-ip.     1533                 :UBC           0 :         return true;
                               1534                 :                : 
                               1535                 :                :     /*
                               1536                 :                :      * if HEAP_XMAX_LOCK_ONLY is not set and not a multi, then this must
                               1537                 :                :      * necessarily have been updated
                               1538                 :                :      */
 4099 alvherre@alvh.no-ip.     1539         [ +  + ]:CBC       60464 :     if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
                               1540                 :          60437 :         return false;
                               1541                 :                : 
                               1542                 :                :     /* ... but if it's a multi, then perhaps the updating Xid aborted. */
                               1543                 :             27 :     xmax = HeapTupleGetUpdateXid(tuple);
                               1544                 :                : 
                               1545                 :                :     /* not LOCKED_ONLY, so it has to have an xmax */
 3789                          1546         [ -  + ]:             27 :     Assert(TransactionIdIsValid(xmax));
                               1547                 :                : 
 4099                          1548         [ -  + ]:             27 :     if (TransactionIdIsCurrentTransactionId(xmax))
 4099 alvherre@alvh.no-ip.     1549                 :UBC           0 :         return false;
 4099 alvherre@alvh.no-ip.     1550         [ +  + ]:CBC          27 :     if (TransactionIdIsInProgress(xmax))
                               1551                 :              4 :         return false;
                               1552         [ +  + ]:             23 :     if (TransactionIdDidCommit(xmax))
                               1553                 :             11 :         return false;
                               1554                 :                : 
                               1555                 :                :     /*
                               1556                 :                :      * not current, not in progress, not committed -- must have aborted or
                               1557                 :                :      * crashed
                               1558                 :                :      */
                               1559                 :             12 :     return true;
                               1560                 :                : }
                               1561                 :                : 
                               1562                 :                : /*
                               1563                 :                :  * check whether the transaction id 'xid' is in the pre-sorted array 'xip'.
                               1564                 :                :  */
                               1565                 :                : static bool
 3695 rhaas@postgresql.org     1566                 :          38512 : TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
                               1567                 :                : {
  773 tgl@sss.pgh.pa.us        1568   [ +  +  +  + ]:          54823 :     return num > 0 &&
                               1569                 :          16311 :         bsearch(&xid, xip, num, sizeof(TransactionId), xidComparator) != NULL;
                               1570                 :                : }
                               1571                 :                : 
                               1572                 :                : /*
                               1573                 :                :  * See the comments for HeapTupleSatisfiesMVCC for the semantics this function
                               1574                 :                :  * obeys.
                               1575                 :                :  *
                               1576                 :                :  * Only usable on tuples from catalog tables!
                               1577                 :                :  *
                               1578                 :                :  * We don't need to support HEAP_MOVED_(IN|OFF) for now because we only support
                               1579                 :                :  * reading catalog pages which couldn't have been created in an older version.
                               1580                 :                :  *
                               1581                 :                :  * We don't set any hint bits in here as it seems unlikely to be beneficial as
                               1582                 :                :  * those should already be set by normal access and it seems to be too
                               1583                 :                :  * dangerous to do so as the semantics of doing so during timetravel are more
                               1584                 :                :  * complicated than when dealing "only" with the present.
                               1585                 :                :  */
                               1586                 :                : static bool
 3695 rhaas@postgresql.org     1587                 :          30415 : HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
                               1588                 :                :                                Buffer buffer)
                               1589                 :                : {
                               1590                 :          30415 :     HeapTupleHeader tuple = htup->t_data;
                               1591         [ +  + ]:          30415 :     TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
                               1592                 :          30415 :     TransactionId xmax = HeapTupleHeaderGetRawXmax(tuple);
                               1593                 :                : 
                               1594         [ -  + ]:          30415 :     Assert(ItemPointerIsValid(&htup->t_self));
                               1595         [ -  + ]:          30415 :     Assert(htup->t_tableOid != InvalidOid);
                               1596                 :                : 
                               1597                 :                :     /* inserting transaction aborted */
                               1598         [ +  + ]:          30415 :     if (HeapTupleHeaderXminInvalid(tuple))
                               1599                 :                :     {
                               1600         [ -  + ]:             75 :         Assert(!TransactionIdDidCommit(xmin));
                               1601                 :             75 :         return false;
                               1602                 :                :     }
                               1603                 :                :     /* check if it's one of our txids, toplevel is also in there */
                               1604         [ +  + ]:          30340 :     else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))
                               1605                 :                :     {
                               1606                 :                :         bool        resolved;
                               1607                 :            470 :         CommandId   cmin = HeapTupleHeaderGetRawCommandId(tuple);
                               1608                 :            470 :         CommandId   cmax = InvalidCommandId;
                               1609                 :                : 
                               1610                 :                :         /*
                               1611                 :                :          * another transaction might have (tried to) delete this tuple or
                               1612                 :                :          * cmin/cmax was stored in a combo CID. So we need to lookup the
                               1613                 :                :          * actual values externally.
                               1614                 :                :          */
                               1615                 :            470 :         resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot,
                               1616                 :                :                                                  htup, buffer,
                               1617                 :                :                                                  &cmin, &cmax);
                               1618                 :                : 
                               1619                 :                :         /*
                               1620                 :                :          * If we haven't resolved the combo CID to cmin/cmax, that means we
                               1621                 :                :          * have not decoded the combo CID yet. That means the cmin is
                               1622                 :                :          * definitely in the future, and we're not supposed to see the tuple
                               1623                 :                :          * yet.
                               1624                 :                :          *
                               1625                 :                :          * XXX This only applies to decoding of in-progress transactions. In
                               1626                 :                :          * regular logical decoding we only execute this code at commit time,
                               1627                 :                :          * at which point we should have seen all relevant combo CIDs. So
                               1628                 :                :          * ideally, we should error out in this case but in practice, this
                               1629                 :                :          * won't happen. If we are too worried about this then we can add an
                               1630                 :                :          * elog inside ResolveCminCmaxDuringDecoding.
                               1631                 :                :          *
                               1632                 :                :          * XXX For the streaming case, we can track the largest combo CID
                               1633                 :                :          * assigned, and error out based on this (when unable to resolve combo
                               1634                 :                :          * CID below that observed maximum value).
                               1635                 :                :          */
                               1636         [ -  + ]:            470 :         if (!resolved)
 1345 akapila@postgresql.o     1637                 :UBC           0 :             return false;
                               1638                 :                : 
 3695 rhaas@postgresql.org     1639         [ -  + ]:CBC         470 :         Assert(cmin != InvalidCommandId);
                               1640                 :                : 
                               1641         [ +  + ]:            470 :         if (cmin >= snapshot->curcid)
 3631 bruce@momjian.us         1642                 :             57 :             return false;       /* inserted after scan started */
                               1643                 :                :         /* fall through */
                               1644                 :                :     }
                               1645                 :                :     /* committed before our xmin horizon. Do a normal visibility check. */
 3695 rhaas@postgresql.org     1646         [ +  + ]:          29870 :     else if (TransactionIdPrecedes(xmin, snapshot->xmin))
                               1647                 :                :     {
                               1648   [ +  +  -  + ]:          26828 :         Assert(!(HeapTupleHeaderXminCommitted(tuple) &&
                               1649                 :                :                  !TransactionIdDidCommit(xmin)));
                               1650                 :                : 
                               1651                 :                :         /* check for hint bit first, consult clog afterwards */
                               1652         [ +  + ]:          26828 :         if (!HeapTupleHeaderXminCommitted(tuple) &&
                               1653         [ -  + ]:             59 :             !TransactionIdDidCommit(xmin))
 3695 rhaas@postgresql.org     1654                 :UBC           0 :             return false;
                               1655                 :                :         /* fall through */
                               1656                 :                :     }
                               1657                 :                :     /* beyond our xmax horizon, i.e. invisible */
 3695 rhaas@postgresql.org     1658         [ +  + ]:CBC        3042 :     else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))
                               1659                 :                :     {
                               1660                 :            119 :         return false;
                               1661                 :                :     }
                               1662                 :                :     /* check if it's a committed transaction in [xmin, xmax) */
 3631 bruce@momjian.us         1663         [ -  + ]:           2923 :     else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
                               1664                 :                :     {
                               1665                 :                :         /* fall through */
                               1666                 :                :     }
                               1667                 :                : 
                               1668                 :                :     /*
                               1669                 :                :      * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.
                               1670                 :                :      * invisible.
                               1671                 :                :      */
                               1672                 :                :     else
                               1673                 :                :     {
 3695 rhaas@postgresql.org     1674                 :UBC           0 :         return false;
                               1675                 :                :     }
                               1676                 :                : 
                               1677                 :                :     /* at this point we know xmin is visible, go on to check xmax */
                               1678                 :                : 
                               1679                 :                :     /* xid invalid or aborted */
 3695 rhaas@postgresql.org     1680         [ +  + ]:CBC       30164 :     if (tuple->t_infomask & HEAP_XMAX_INVALID)
                               1681                 :          25373 :         return true;
                               1682                 :                :     /* locked tuples are always visible */
                               1683   [ +  +  -  + ]:           4791 :     else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
                               1684                 :           1047 :         return true;
                               1685                 :                : 
                               1686                 :                :     /*
                               1687                 :                :      * We can see multis here if we're looking at user tables or if somebody
                               1688                 :                :      * SELECT ... FOR SHARE/UPDATE a system table.
                               1689                 :                :      */
                               1690         [ +  + ]:           3744 :     else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
                               1691                 :                :     {
                               1692                 :             49 :         xmax = HeapTupleGetUpdateXid(tuple);
                               1693                 :                :     }
                               1694                 :                : 
                               1695                 :                :     /* check if it's one of our txids, toplevel is also in there */
                               1696         [ +  + ]:           3744 :     if (TransactionIdInArray(xmax, snapshot->subxip, snapshot->subxcnt))
                               1697                 :                :     {
                               1698                 :                :         bool        resolved;
                               1699                 :                :         CommandId   cmin;
 3631 bruce@momjian.us         1700                 :            320 :         CommandId   cmax = HeapTupleHeaderGetRawCommandId(tuple);
                               1701                 :                : 
                               1702                 :                :         /* Lookup actual cmin/cmax values */
 3695 rhaas@postgresql.org     1703                 :            320 :         resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot,
                               1704                 :                :                                                  htup, buffer,
                               1705                 :                :                                                  &cmin, &cmax);
                               1706                 :                : 
                               1707                 :                :         /*
                               1708                 :                :          * If we haven't resolved the combo CID to cmin/cmax, that means we
                               1709                 :                :          * have not decoded the combo CID yet. That means the cmax is
                               1710                 :                :          * definitely in the future, and we're still supposed to see the
                               1711                 :                :          * tuple.
                               1712                 :                :          *
                               1713                 :                :          * XXX This only applies to decoding of in-progress transactions. In
                               1714                 :                :          * regular logical decoding we only execute this code at commit time,
                               1715                 :                :          * at which point we should have seen all relevant combo CIDs. So
                               1716                 :                :          * ideally, we should error out in this case but in practice, this
                               1717                 :                :          * won't happen. If we are too worried about this then we can add an
                               1718                 :                :          * elog inside ResolveCminCmaxDuringDecoding.
                               1719                 :                :          *
                               1720                 :                :          * XXX For the streaming case, we can track the largest combo CID
                               1721                 :                :          * assigned, and error out based on this (when unable to resolve combo
                               1722                 :                :          * CID below that observed maximum value).
                               1723                 :                :          */
 1345 akapila@postgresql.o     1724   [ +  +  -  + ]:            320 :         if (!resolved || cmax == InvalidCommandId)
                               1725                 :              9 :             return true;
                               1726                 :                : 
 3695 rhaas@postgresql.org     1727         [ +  + ]:            311 :         if (cmax >= snapshot->curcid)
 3631 bruce@momjian.us         1728                 :             74 :             return true;        /* deleted after scan started */
                               1729                 :                :         else
                               1730                 :            237 :             return false;       /* deleted before scan started */
                               1731                 :                :     }
                               1732                 :                :     /* below xmin horizon, normal transaction state is valid */
 3695 rhaas@postgresql.org     1733         [ +  + ]:           3424 :     else if (TransactionIdPrecedes(xmax, snapshot->xmin))
                               1734                 :                :     {
                               1735   [ +  +  -  + ]:           1693 :         Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED &&
                               1736                 :                :                  !TransactionIdDidCommit(xmax)));
                               1737                 :                : 
                               1738                 :                :         /* check hint bit first */
                               1739         [ +  + ]:           1693 :         if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
                               1740                 :           1627 :             return false;
                               1741                 :                : 
                               1742                 :                :         /* check clog */
                               1743                 :             66 :         return !TransactionIdDidCommit(xmax);
                               1744                 :                :     }
                               1745                 :                :     /* above xmax horizon, we cannot possibly see the deleting transaction */
                               1746         [ +  + ]:           1731 :     else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
                               1747                 :            226 :         return true;
                               1748                 :                :     /* xmax is between [xmin, xmax), check known committed array */
                               1749         [ +  - ]:           1505 :     else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
                               1750                 :           1505 :         return false;
                               1751                 :                :     /* xmax is between [xmin, xmax), but known not to have committed yet */
                               1752                 :                :     else
 3695 rhaas@postgresql.org     1753                 :UBC           0 :         return true;
                               1754                 :                : }
                               1755                 :                : 
                               1756                 :                : /*
                               1757                 :                :  * HeapTupleSatisfiesVisibility
                               1758                 :                :  *      True iff heap tuple satisfies a time qual.
                               1759                 :                :  *
                               1760                 :                :  * Notes:
                               1761                 :                :  *  Assumes heap tuple is valid, and buffer at least share locked.
                               1762                 :                :  *
                               1763                 :                :  *  Hint bits in the HeapTuple's t_infomask may be updated as a side effect;
                               1764                 :                :  *  if so, the indicated buffer is marked dirty.
                               1765                 :                :  */
                               1766                 :                : bool
  573 pg@bowt.ie               1767                 :CBC    80466956 : HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                               1768                 :                : {
 1910 andres@anarazel.de       1769   [ +  +  +  +  :       80466956 :     switch (snapshot->snapshot_type)
                                        +  +  +  - ]
                               1770                 :                :     {
                               1771                 :       66372578 :         case SNAPSHOT_MVCC:
  573 pg@bowt.ie               1772                 :       66372578 :             return HeapTupleSatisfiesMVCC(htup, snapshot, buffer);
 1910 andres@anarazel.de       1773                 :           2558 :         case SNAPSHOT_SELF:
  573 pg@bowt.ie               1774                 :           2558 :             return HeapTupleSatisfiesSelf(htup, snapshot, buffer);
 1910 andres@anarazel.de       1775                 :        7807042 :         case SNAPSHOT_ANY:
  573 pg@bowt.ie               1776                 :        7807042 :             return HeapTupleSatisfiesAny(htup, snapshot, buffer);
 1910 andres@anarazel.de       1777                 :          71239 :         case SNAPSHOT_TOAST:
  573 pg@bowt.ie               1778                 :          71239 :             return HeapTupleSatisfiesToast(htup, snapshot, buffer);
 1910 andres@anarazel.de       1779                 :        5879439 :         case SNAPSHOT_DIRTY:
  573 pg@bowt.ie               1780                 :        5879439 :             return HeapTupleSatisfiesDirty(htup, snapshot, buffer);
 1910 andres@anarazel.de       1781                 :          30415 :         case SNAPSHOT_HISTORIC_MVCC:
  573 pg@bowt.ie               1782                 :          30415 :             return HeapTupleSatisfiesHistoricMVCC(htup, snapshot, buffer);
 1910 andres@anarazel.de       1783                 :         303685 :         case SNAPSHOT_NON_VACUUMABLE:
  573 pg@bowt.ie               1784                 :         303685 :             return HeapTupleSatisfiesNonVacuumable(htup, snapshot, buffer);
                               1785                 :                :     }
                               1786                 :                : 
 1910 andres@anarazel.de       1787                 :UBC           0 :     return false;               /* keep compiler quiet */
                               1788                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622