PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tqual.h File Reference
#include "utils/snapshot.h"
#include "access/xlogdefs.h"
Include dependency graph for tqual.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SnapshotSelf   (&SnapshotSelfData)
 
#define SnapshotAny   (&SnapshotAnyData)
 
#define IsMVCCSnapshot(snapshot)
 
#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer)   ((*(snapshot)->satisfies) (tuple, snapshot, buffer))
 
#define InitDirtySnapshot(snapshotdata)   ((snapshotdata).satisfies = HeapTupleSatisfiesDirty)
 
#define InitToastSnapshot(snapshotdata, l, w)
 

Enumerations

enum  HTSV_Result {
  HEAPTUPLE_DEAD, HEAPTUPLE_LIVE, HEAPTUPLE_RECENTLY_DEAD, HEAPTUPLE_INSERT_IN_PROGRESS,
  HEAPTUPLE_DELETE_IN_PROGRESS
}
 

Functions

bool HeapTupleSatisfiesMVCC (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
bool HeapTupleSatisfiesSelf (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
bool HeapTupleSatisfiesAny (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
bool HeapTupleSatisfiesToast (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
bool HeapTupleSatisfiesDirty (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
bool HeapTupleSatisfiesHistoricMVCC (HeapTuple htup, Snapshot snapshot, Buffer buffer)
 
HTSU_Result HeapTupleSatisfiesUpdate (HeapTuple htup, CommandId curcid, Buffer buffer)
 
HTSV_Result HeapTupleSatisfiesVacuum (HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
 
bool HeapTupleIsSurelyDead (HeapTuple htup, TransactionId OldestXmin)
 
void HeapTupleSetHintBits (HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
 
bool HeapTupleHeaderIsOnlyLocked (HeapTupleHeader tuple)
 
bool ResolveCminCmaxDuringDecoding (struct HTAB *tuplecid_data, Snapshot snapshot, HeapTuple htup, Buffer buffer, CommandId *cmin, CommandId *cmax)
 

Variables

PGDLLIMPORT SnapshotData SnapshotSelfData
 
PGDLLIMPORT SnapshotData SnapshotAnyData
 
PGDLLIMPORT SnapshotData CatalogSnapshotData
 

Macro Definition Documentation

#define HeapTupleSatisfiesVisibility (   tuple,
  snapshot,
  buffer 
)    ((*(snapshot)->satisfies) (tuple, snapshot, buffer))
#define InitToastSnapshot (   snapshotdata,
  l,
 
)
Value:
((snapshotdata).satisfies = HeapTupleSatisfiesToast, \
(snapshotdata).lsn = (l), \
(snapshotdata).whenTaken = (w))
bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:366

Definition at line 107 of file tqual.h.

Referenced by init_toast_snapshot().

#define IsMVCCSnapshot (   snapshot)
Value:
((snapshot)->satisfies == HeapTupleSatisfiesMVCC || \
(snapshot)->satisfies == HeapTupleSatisfiesHistoricMVCC)
bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:1652
bool HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer)
Definition: tqual.c:963

Definition at line 31 of file tqual.h.

Referenced by _bt_drop_lock_and_maybe_pin(), ExecInitBitmapHeapScan(), heap_beginscan_internal(), heap_rescan_set_params(), index_fetch_heap(), index_restrpos(), SerializationNeededForRead(), and systable_recheck_tuple().

Enumeration Type Documentation

Enumerator
HEAPTUPLE_DEAD 
HEAPTUPLE_LIVE 
HEAPTUPLE_RECENTLY_DEAD 
HEAPTUPLE_INSERT_IN_PROGRESS 
HEAPTUPLE_DELETE_IN_PROGRESS 

Definition at line 49 of file tqual.h.

50 {
51  HEAPTUPLE_DEAD, /* tuple is dead and deletable */
52  HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */
53  HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */
54  HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */
55  HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */
56 } HTSV_Result;
HTSV_Result
Definition: tqual.h:49

Function Documentation

bool HeapTupleHeaderIsOnlyLocked ( HeapTupleHeader  tuple)

Definition at line 1585 of file tqual.c.

References Assert, HEAP_XMAX_INVALID, HEAP_XMAX_IS_MULTI, HEAP_XMAX_LOCK_ONLY, HeapTupleGetUpdateXid(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderData::t_infomask, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), and TransactionIdIsValid.

Referenced by heap_delete(), heap_get_latest_tid(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), HeapTupleSatisfiesVacuum(), and rewrite_heap_tuple().

1586 {
1587  TransactionId xmax;
1588 
1589  /* if there's no valid Xmax, then there's obviously no update either */
1590  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1591  return true;
1592 
1593  if (tuple->t_infomask & HEAP_XMAX_LOCK_ONLY)
1594  return true;
1595 
1596  /* invalid xmax means no update */
1598  return true;
1599 
1600  /*
1601  * if HEAP_XMAX_LOCK_ONLY is not set and not a multi, then this must
1602  * necessarily have been updated
1603  */
1604  if (!(tuple->t_infomask & HEAP_XMAX_IS_MULTI))
1605  return false;
1606 
1607  /* ... but if it's a multi, then perhaps the updating Xid aborted. */
1608  xmax = HeapTupleGetUpdateXid(tuple);
1609 
1610  /* not LOCKED_ONLY, so it has to have an xmax */
1612 
1614  return false;
1615  if (TransactionIdIsInProgress(xmax))
1616  return false;
1617  if (TransactionIdDidCommit(xmax))
1618  return false;
1619 
1620  /*
1621  * not current, not in progress, not committed -- must have aborted or
1622  * crashed
1623  */
1624  return true;
1625 }
#define HEAP_XMAX_LOCK_ONLY
Definition: htup_details.h:182
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define Assert(condition)
Definition: c.h:671
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool HeapTupleIsSurelyDead ( HeapTuple  htup,
TransactionId  OldestXmin 
)

Definition at line 1409 of file tqual.c.

References Assert, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HeapTupleHeaderGetRawXmax, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, InvalidOid, ItemPointerIsValid, HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, and TransactionIdPrecedes().

Referenced by heap_hot_search_buffer().

1410 {
1411  HeapTupleHeader tuple = htup->t_data;
1412 
1413  Assert(ItemPointerIsValid(&htup->t_self));
1414  Assert(htup->t_tableOid != InvalidOid);
1415 
1416  /*
1417  * If the inserting transaction is marked invalid, then it aborted, and
1418  * the tuple is definitely dead. If it's marked neither committed nor
1419  * invalid, then we assume it's still alive (since the presumption is that
1420  * all relevant hint bits were just set moments ago).
1421  */
1422  if (!HeapTupleHeaderXminCommitted(tuple))
1423  return HeapTupleHeaderXminInvalid(tuple) ? true : false;
1424 
1425  /*
1426  * If the inserting transaction committed, but any deleting transaction
1427  * aborted, the tuple is still alive.
1428  */
1429  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1430  return false;
1431 
1432  /*
1433  * If the XMAX is just a lock, the tuple is still alive.
1434  */
1436  return false;
1437 
1438  /*
1439  * If the Xmax is a MultiXact, it might be dead or alive, but we cannot
1440  * know without checking pg_multixact.
1441  */
1442  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1443  return false;
1444 
1445  /* If deleter isn't known to have committed, assume it's still running. */
1446  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1447  return false;
1448 
1449  /* Deleter committed, so tuple is dead if the XID is old enough. */
1451 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
static TransactionId OldestXmin
Definition: vacuumlazy.c:138
Oid t_tableOid
Definition: htup.h:66
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:671
bool HeapTupleSatisfiesAny ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 346 of file tqual.c.

347 {
348  return true;
349 }
bool HeapTupleSatisfiesDirty ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 739 of file tqual.c.

References Assert, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HeapTupleGetUpdateXid(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, HeapTupleHeaderGetSpeculativeToken, HeapTupleHeaderGetXvac, HeapTupleHeaderIsSpeculative, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, InvalidOid, InvalidTransactionId, ItemPointerIsValid, SetHintBits(), SnapshotData::speculativeToken, HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdIsValid, SnapshotData::xmax, and SnapshotData::xmin.

741 {
742  HeapTupleHeader tuple = htup->t_data;
743 
745  Assert(htup->t_tableOid != InvalidOid);
746 
747  snapshot->xmin = snapshot->xmax = InvalidTransactionId;
748  snapshot->speculativeToken = 0;
749 
750  if (!HeapTupleHeaderXminCommitted(tuple))
751  {
752  if (HeapTupleHeaderXminInvalid(tuple))
753  return false;
754 
755  /* Used by pre-9.0 binary upgrades */
756  if (tuple->t_infomask & HEAP_MOVED_OFF)
757  {
759 
761  return false;
762  if (!TransactionIdIsInProgress(xvac))
763  {
764  if (TransactionIdDidCommit(xvac))
765  {
766  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
768  return false;
769  }
770  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
772  }
773  }
774  /* Used by pre-9.0 binary upgrades */
775  else if (tuple->t_infomask & HEAP_MOVED_IN)
776  {
778 
780  {
781  if (TransactionIdIsInProgress(xvac))
782  return false;
783  if (TransactionIdDidCommit(xvac))
784  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
786  else
787  {
788  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
790  return false;
791  }
792  }
793  }
795  {
796  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
797  return true;
798 
799  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
800  return true;
801 
802  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
803  {
804  TransactionId xmax;
805 
806  xmax = HeapTupleGetUpdateXid(tuple);
807 
808  /* not LOCKED_ONLY, so it has to have an xmax */
810 
811  /* updating subtransaction must have aborted */
813  return true;
814  else
815  return false;
816  }
817 
819  {
820  /* deleting subtransaction must have aborted */
821  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
823  return true;
824  }
825 
826  return false;
827  }
829  {
830  /*
831  * Return the speculative token to caller. Caller can worry about
832  * xmax, since it requires a conclusively locked row version, and
833  * a concurrent update to this tuple is a conflict of its
834  * purposes.
835  */
836  if (HeapTupleHeaderIsSpeculative(tuple))
837  {
838  snapshot->speculativeToken =
840 
841  Assert(snapshot->speculativeToken != 0);
842  }
843 
844  snapshot->xmin = HeapTupleHeaderGetRawXmin(tuple);
845  /* XXX shouldn't we fall through to look at xmax? */
846  return true; /* in insertion by other */
847  }
849  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
851  else
852  {
853  /* it must have aborted or crashed */
854  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
856  return false;
857  }
858  }
859 
860  /* by here, the inserting transaction has committed */
861 
862  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
863  return true;
864 
865  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
866  {
868  return true;
869  return false; /* updated by other */
870  }
871 
872  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
873  {
874  TransactionId xmax;
875 
877  return true;
878 
879  xmax = HeapTupleGetUpdateXid(tuple);
880 
881  /* not LOCKED_ONLY, so it has to have an xmax */
883 
885  return false;
886  if (TransactionIdIsInProgress(xmax))
887  {
888  snapshot->xmax = xmax;
889  return true;
890  }
891  if (TransactionIdDidCommit(xmax))
892  return false;
893  /* it must have aborted or crashed */
894  return true;
895  }
896 
898  {
900  return true;
901  return false;
902  }
903 
905  {
907  snapshot->xmax = HeapTupleHeaderGetRawXmax(tuple);
908  return true;
909  }
910 
912  {
913  /* it must have aborted or crashed */
914  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
916  return true;
917  }
918 
919  /* xmax transaction committed */
920 
922  {
923  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
925  return true;
926  }
927 
928  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
930  return false; /* updated by other */
931 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
#define HeapTupleHeaderGetSpeculativeToken(tup)
Definition: htup_details.h:428
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
#define HeapTupleHeaderIsSpeculative(tup)
Definition: htup_details.h:423
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
Oid t_tableOid
Definition: htup.h:66
TransactionId xmax
Definition: snapshot.h:67
TransactionId xmin
Definition: snapshot.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
uint32 speculativeToken
Definition: snapshot.h:102
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool HeapTupleSatisfiesHistoricMVCC ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 1652 of file tqual.c.

References Assert, SnapshotData::curcid, elog, ERROR, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HeapTupleGetUpdateXid(), HeapTupleHeaderGetRawCommandId, HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetXmin, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, HistoricSnapshotGetTupleCids(), InvalidCommandId, InvalidOid, ItemPointerIsValid, ResolveCminCmaxDuringDecoding(), SnapshotData::subxcnt, SnapshotData::subxip, HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdFollowsOrEquals(), TransactionIdInArray(), TransactionIdPrecedes(), SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by SnapBuildBuildSnapshot(), SnapBuildFreeSnapshot(), and SnapBuildSnapDecRefcount().

1654 {
1655  HeapTupleHeader tuple = htup->t_data;
1656  TransactionId xmin = HeapTupleHeaderGetXmin(tuple);
1658 
1659  Assert(ItemPointerIsValid(&htup->t_self));
1660  Assert(htup->t_tableOid != InvalidOid);
1661 
1662  /* inserting transaction aborted */
1663  if (HeapTupleHeaderXminInvalid(tuple))
1664  {
1666  return false;
1667  }
1668  /* check if it's one of our txids, toplevel is also in there */
1669  else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))
1670  {
1671  bool resolved;
1673  CommandId cmax = InvalidCommandId;
1674 
1675  /*
1676  * another transaction might have (tried to) delete this tuple or
1677  * cmin/cmax was stored in a combocid. So we need to lookup the actual
1678  * values externally.
1679  */
1681  htup, buffer,
1682  &cmin, &cmax);
1683 
1684  if (!resolved)
1685  elog(ERROR, "could not resolve cmin/cmax of catalog tuple");
1686 
1687  Assert(cmin != InvalidCommandId);
1688 
1689  if (cmin >= snapshot->curcid)
1690  return false; /* inserted after scan started */
1691  /* fall through */
1692  }
1693  /* committed before our xmin horizon. Do a normal visibility check. */
1694  else if (TransactionIdPrecedes(xmin, snapshot->xmin))
1695  {
1697  !TransactionIdDidCommit(xmin)));
1698 
1699  /* check for hint bit first, consult clog afterwards */
1700  if (!HeapTupleHeaderXminCommitted(tuple) &&
1701  !TransactionIdDidCommit(xmin))
1702  return false;
1703  /* fall through */
1704  }
1705  /* beyond our xmax horizon, i.e. invisible */
1706  else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))
1707  {
1708  return false;
1709  }
1710  /* check if it's a committed transaction in [xmin, xmax) */
1711  else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
1712  {
1713  /* fall through */
1714  }
1715 
1716  /*
1717  * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.
1718  * invisible.
1719  */
1720  else
1721  {
1722  return false;
1723  }
1724 
1725  /* at this point we know xmin is visible, go on to check xmax */
1726 
1727  /* xid invalid or aborted */
1728  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1729  return true;
1730  /* locked tuples are always visible */
1731  else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
1732  return true;
1733 
1734  /*
1735  * We can see multis here if we're looking at user tables or if somebody
1736  * SELECT ... FOR SHARE/UPDATE a system table.
1737  */
1738  else if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1739  {
1740  xmax = HeapTupleGetUpdateXid(tuple);
1741  }
1742 
1743  /* check if it's one of our txids, toplevel is also in there */
1744  if (TransactionIdInArray(xmax, snapshot->subxip, snapshot->subxcnt))
1745  {
1746  bool resolved;
1747  CommandId cmin;
1749 
1750  /* Lookup actual cmin/cmax values */
1752  htup, buffer,
1753  &cmin, &cmax);
1754 
1755  if (!resolved)
1756  elog(ERROR, "could not resolve combocid to cmax");
1757 
1758  Assert(cmax != InvalidCommandId);
1759 
1760  if (cmax >= snapshot->curcid)
1761  return true; /* deleted after scan started */
1762  else
1763  return false; /* deleted before scan started */
1764  }
1765  /* below xmin horizon, normal transaction state is valid */
1766  else if (TransactionIdPrecedes(xmax, snapshot->xmin))
1767  {
1768  Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED &&
1769  !TransactionIdDidCommit(xmax)));
1770 
1771  /* check hint bit first */
1772  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
1773  return false;
1774 
1775  /* check clog */
1776  return !TransactionIdDidCommit(xmax);
1777  }
1778  /* above xmax horizon, we cannot possibly see the deleting transaction */
1779  else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
1780  return true;
1781  /* xmax is between [xmin, xmax), check known committed array */
1782  else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
1783  return false;
1784  /* xmax is between [xmin, xmax), but known not to have committed yet */
1785  else
1786  return true;
1787 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 CommandId
Definition: c.h:408
uint32 TransactionId
Definition: c.h:394
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define ERROR
Definition: elog.h:43
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
Oid t_tableOid
Definition: htup.h:66
static bool TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
Definition: tqual.c:1631
TransactionId xmax
Definition: snapshot.h:67
TransactionId xmin
Definition: snapshot.h:66
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TransactionId * xip
Definition: snapshot.h:77
#define InvalidCommandId
Definition: c.h:411
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define InvalidOid
Definition: postgres_ext.h:36
CommandId curcid
Definition: snapshot.h:96
#define Assert(condition)
Definition: c.h:671
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:385
HTAB * HistoricSnapshotGetTupleCids(void)
Definition: snapmgr.c:1978
uint32 xcnt
Definition: snapshot.h:78
#define elog
Definition: elog.h:219
TransactionId * subxip
Definition: snapshot.h:89
int32 subxcnt
Definition: snapshot.h:90
bool ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data, Snapshot snapshot, HeapTuple htup, Buffer buffer, CommandId *cmin, CommandId *cmax)
bool HeapTupleSatisfiesMVCC ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 963 of file tqual.c.

References Assert, SnapshotData::curcid, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HeapTupleGetUpdateXid(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, HeapTupleHeaderGetXvac, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminFrozen, HeapTupleHeaderXminInvalid, InvalidOid, InvalidTransactionId, ItemPointerIsValid, SetHintBits(), HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsValid, and XidInMVCCSnapshot().

Referenced by EstimateSnapshotSpace(), RestoreSnapshot(), and TestForOldSnapshot().

965 {
966  HeapTupleHeader tuple = htup->t_data;
967 
969  Assert(htup->t_tableOid != InvalidOid);
970 
971  if (!HeapTupleHeaderXminCommitted(tuple))
972  {
973  if (HeapTupleHeaderXminInvalid(tuple))
974  return false;
975 
976  /* Used by pre-9.0 binary upgrades */
977  if (tuple->t_infomask & HEAP_MOVED_OFF)
978  {
980 
982  return false;
983  if (!XidInMVCCSnapshot(xvac, snapshot))
984  {
985  if (TransactionIdDidCommit(xvac))
986  {
987  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
989  return false;
990  }
991  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
993  }
994  }
995  /* Used by pre-9.0 binary upgrades */
996  else if (tuple->t_infomask & HEAP_MOVED_IN)
997  {
999 
1001  {
1002  if (XidInMVCCSnapshot(xvac, snapshot))
1003  return false;
1004  if (TransactionIdDidCommit(xvac))
1005  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1007  else
1008  {
1009  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1011  return false;
1012  }
1013  }
1014  }
1016  {
1017  if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
1018  return false; /* inserted after scan started */
1019 
1020  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
1021  return true;
1022 
1023  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
1024  return true;
1025 
1026  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1027  {
1028  TransactionId xmax;
1029 
1030  xmax = HeapTupleGetUpdateXid(tuple);
1031 
1032  /* not LOCKED_ONLY, so it has to have an xmax */
1034 
1035  /* updating subtransaction must have aborted */
1037  return true;
1038  else if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1039  return true; /* updated after scan started */
1040  else
1041  return false; /* updated before scan started */
1042  }
1043 
1045  {
1046  /* deleting subtransaction must have aborted */
1047  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1049  return true;
1050  }
1051 
1052  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1053  return true; /* deleted after scan started */
1054  else
1055  return false; /* deleted before scan started */
1056  }
1057  else if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
1058  return false;
1060  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1061  HeapTupleHeaderGetRawXmin(tuple));
1062  else
1063  {
1064  /* it must have aborted or crashed */
1065  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1067  return false;
1068  }
1069  }
1070  else
1071  {
1072  /* xmin is committed, but maybe not according to our snapshot */
1073  if (!HeapTupleHeaderXminFrozen(tuple) &&
1074  XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), snapshot))
1075  return false; /* treat as still in progress */
1076  }
1077 
1078  /* by here, the inserting transaction has committed */
1079 
1080  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
1081  return true;
1082 
1084  return true;
1085 
1086  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1087  {
1088  TransactionId xmax;
1089 
1090  /* already checked above */
1092 
1093  xmax = HeapTupleGetUpdateXid(tuple);
1094 
1095  /* not LOCKED_ONLY, so it has to have an xmax */
1097 
1099  {
1100  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1101  return true; /* deleted after scan started */
1102  else
1103  return false; /* deleted before scan started */
1104  }
1105  if (XidInMVCCSnapshot(xmax, snapshot))
1106  return true;
1107  if (TransactionIdDidCommit(xmax))
1108  return false; /* updating transaction committed */
1109  /* it must have aborted or crashed */
1110  return true;
1111  }
1112 
1113  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1114  {
1116  {
1117  if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
1118  return true; /* deleted after scan started */
1119  else
1120  return false; /* deleted before scan started */
1121  }
1122 
1123  if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
1124  return true;
1125 
1127  {
1128  /* it must have aborted or crashed */
1129  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1131  return true;
1132  }
1133 
1134  /* xmax transaction committed */
1135  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
1136  HeapTupleHeaderGetRawXmax(tuple));
1137  }
1138  else
1139  {
1140  /* xmax is committed, but maybe not according to our snapshot */
1141  if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
1142  return true; /* treat as still in progress */
1143  }
1144 
1145  /* xmax transaction committed */
1146 
1147  return false;
1148 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
Definition: tqual.c:1464
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
Oid t_tableOid
Definition: htup.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HeapTupleHeaderXminFrozen(tup)
Definition: htup_details.h:329
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
CommandId curcid
Definition: snapshot.h:96
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup)
Definition: combocid.c:119
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool HeapTupleSatisfiesSelf ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 176 of file tqual.c.

References Assert, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HeapTupleGetUpdateXid(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, HeapTupleHeaderGetXvac, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, InvalidOid, InvalidTransactionId, ItemPointerIsValid, SetHintBits(), HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), and TransactionIdIsValid.

177 {
178  HeapTupleHeader tuple = htup->t_data;
179 
181  Assert(htup->t_tableOid != InvalidOid);
182 
183  if (!HeapTupleHeaderXminCommitted(tuple))
184  {
185  if (HeapTupleHeaderXminInvalid(tuple))
186  return false;
187 
188  /* Used by pre-9.0 binary upgrades */
189  if (tuple->t_infomask & HEAP_MOVED_OFF)
190  {
192 
194  return false;
195  if (!TransactionIdIsInProgress(xvac))
196  {
197  if (TransactionIdDidCommit(xvac))
198  {
199  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
201  return false;
202  }
203  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
205  }
206  }
207  /* Used by pre-9.0 binary upgrades */
208  else if (tuple->t_infomask & HEAP_MOVED_IN)
209  {
211 
213  {
214  if (TransactionIdIsInProgress(xvac))
215  return false;
216  if (TransactionIdDidCommit(xvac))
217  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
219  else
220  {
221  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
223  return false;
224  }
225  }
226  }
228  {
229  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
230  return true;
231 
232  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
233  return true;
234 
235  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
236  {
237  TransactionId xmax;
238 
239  xmax = HeapTupleGetUpdateXid(tuple);
240 
241  /* not LOCKED_ONLY, so it has to have an xmax */
243 
244  /* updating subtransaction must have aborted */
246  return true;
247  else
248  return false;
249  }
250 
252  {
253  /* deleting subtransaction must have aborted */
254  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
256  return true;
257  }
258 
259  return false;
260  }
262  return false;
264  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
266  else
267  {
268  /* it must have aborted or crashed */
269  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
271  return false;
272  }
273  }
274 
275  /* by here, the inserting transaction has committed */
276 
277  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
278  return true;
279 
280  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
281  {
283  return true;
284  return false; /* updated by other */
285  }
286 
287  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
288  {
289  TransactionId xmax;
290 
292  return true;
293 
294  xmax = HeapTupleGetUpdateXid(tuple);
295 
296  /* not LOCKED_ONLY, so it has to have an xmax */
298 
300  return false;
301  if (TransactionIdIsInProgress(xmax))
302  return true;
303  if (TransactionIdDidCommit(xmax))
304  return false;
305  /* it must have aborted or crashed */
306  return true;
307  }
308 
310  {
312  return true;
313  return false;
314  }
315 
317  return true;
318 
320  {
321  /* it must have aborted or crashed */
322  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
324  return true;
325  }
326 
327  /* xmax transaction committed */
328 
330  {
331  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
333  return true;
334  }
335 
336  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
338  return false;
339 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
Oid t_tableOid
Definition: htup.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool HeapTupleSatisfiesToast ( HeapTuple  htup,
Snapshot  snapshot,
Buffer  buffer 
)

Definition at line 366 of file tqual.c.

References Assert, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HeapTupleHeaderGetXmin, HeapTupleHeaderGetXvac, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, InvalidOid, InvalidTransactionId, ItemPointerIsValid, SetHintBits(), HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), and TransactionIdIsValid.

Referenced by TestForOldSnapshot().

368 {
369  HeapTupleHeader tuple = htup->t_data;
370 
372  Assert(htup->t_tableOid != InvalidOid);
373 
374  if (!HeapTupleHeaderXminCommitted(tuple))
375  {
376  if (HeapTupleHeaderXminInvalid(tuple))
377  return false;
378 
379  /* Used by pre-9.0 binary upgrades */
380  if (tuple->t_infomask & HEAP_MOVED_OFF)
381  {
383 
385  return false;
386  if (!TransactionIdIsInProgress(xvac))
387  {
388  if (TransactionIdDidCommit(xvac))
389  {
390  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
392  return false;
393  }
394  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
396  }
397  }
398  /* Used by pre-9.0 binary upgrades */
399  else if (tuple->t_infomask & HEAP_MOVED_IN)
400  {
402 
404  {
405  if (TransactionIdIsInProgress(xvac))
406  return false;
407  if (TransactionIdDidCommit(xvac))
408  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
410  else
411  {
412  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
414  return false;
415  }
416  }
417  }
418 
419  /*
420  * An invalid Xmin can be left behind by a speculative insertion that
421  * is canceled by super-deleting the tuple. This also applies to
422  * TOAST tuples created during speculative insertion.
423  */
425  return false;
426  }
427 
428  /* otherwise assume the tuple is valid for TOAST. */
429  return true;
430 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
Oid t_tableOid
Definition: htup.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
#define TransactionIdIsValid(xid)
Definition: transam.h:41
HTSU_Result HeapTupleSatisfiesUpdate ( HeapTuple  htup,
CommandId  curcid,
Buffer  buffer 
)

Definition at line 460 of file tqual.c.

References Assert, HEAP_LOCKED_UPGRADED, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HeapTupleBeingUpdated, HeapTupleGetUpdateXid(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, HeapTupleHeaderGetXvac, HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, HeapTupleInvisible, HeapTupleMayBeUpdated, HeapTupleSelfUpdated, HeapTupleUpdated, InvalidOid, InvalidTransactionId, ItemPointerIsValid, MultiXactIdIsRunning(), SetHintBits(), HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), and TransactionIdIsValid.

Referenced by heap_delete(), heap_lock_tuple(), heap_update(), and pgrowlocks().

462 {
463  HeapTupleHeader tuple = htup->t_data;
464 
466  Assert(htup->t_tableOid != InvalidOid);
467 
468  if (!HeapTupleHeaderXminCommitted(tuple))
469  {
470  if (HeapTupleHeaderXminInvalid(tuple))
471  return HeapTupleInvisible;
472 
473  /* Used by pre-9.0 binary upgrades */
474  if (tuple->t_infomask & HEAP_MOVED_OFF)
475  {
477 
479  return HeapTupleInvisible;
480  if (!TransactionIdIsInProgress(xvac))
481  {
482  if (TransactionIdDidCommit(xvac))
483  {
484  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
486  return HeapTupleInvisible;
487  }
488  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
490  }
491  }
492  /* Used by pre-9.0 binary upgrades */
493  else if (tuple->t_infomask & HEAP_MOVED_IN)
494  {
496 
498  {
499  if (TransactionIdIsInProgress(xvac))
500  return HeapTupleInvisible;
501  if (TransactionIdDidCommit(xvac))
502  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
504  else
505  {
506  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
508  return HeapTupleInvisible;
509  }
510  }
511  }
513  {
514  if (HeapTupleHeaderGetCmin(tuple) >= curcid)
515  return HeapTupleInvisible; /* inserted after scan started */
516 
517  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
518  return HeapTupleMayBeUpdated;
519 
521  {
522  TransactionId xmax;
523 
524  xmax = HeapTupleHeaderGetRawXmax(tuple);
525 
526  /*
527  * Careful here: even though this tuple was created by our own
528  * transaction, it might be locked by other transactions, if
529  * the original version was key-share locked when we updated
530  * it.
531  */
532 
533  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
534  {
535  if (MultiXactIdIsRunning(xmax, true))
536  return HeapTupleBeingUpdated;
537  else
538  return HeapTupleMayBeUpdated;
539  }
540 
541  /*
542  * If the locker is gone, then there is nothing of interest
543  * left in this Xmax; otherwise, report the tuple as
544  * locked/updated.
545  */
546  if (!TransactionIdIsInProgress(xmax))
547  return HeapTupleMayBeUpdated;
548  return HeapTupleBeingUpdated;
549  }
550 
551  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
552  {
553  TransactionId xmax;
554 
555  xmax = HeapTupleGetUpdateXid(tuple);
556 
557  /* not LOCKED_ONLY, so it has to have an xmax */
559 
560  /* deleting subtransaction must have aborted */
562  {
564  false))
565  return HeapTupleBeingUpdated;
566  return HeapTupleMayBeUpdated;
567  }
568  else
569  {
570  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
571  return HeapTupleSelfUpdated; /* updated after scan
572  * started */
573  else
574  return HeapTupleInvisible; /* updated before scan
575  * started */
576  }
577  }
578 
580  {
581  /* deleting subtransaction must have aborted */
582  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
584  return HeapTupleMayBeUpdated;
585  }
586 
587  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
588  return HeapTupleSelfUpdated; /* updated after scan started */
589  else
590  return HeapTupleInvisible; /* updated before scan started */
591  }
593  return HeapTupleInvisible;
595  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
597  else
598  {
599  /* it must have aborted or crashed */
600  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
602  return HeapTupleInvisible;
603  }
604  }
605 
606  /* by here, the inserting transaction has committed */
607 
608  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
609  return HeapTupleMayBeUpdated;
610 
611  if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
612  {
614  return HeapTupleMayBeUpdated;
615  return HeapTupleUpdated; /* updated by other */
616  }
617 
618  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
619  {
620  TransactionId xmax;
621 
622  if (HEAP_LOCKED_UPGRADED(tuple->t_infomask))
623  return HeapTupleMayBeUpdated;
624 
626  {
628  return HeapTupleBeingUpdated;
629 
631  return HeapTupleMayBeUpdated;
632  }
633 
634  xmax = HeapTupleGetUpdateXid(tuple);
635  if (!TransactionIdIsValid(xmax))
636  {
638  return HeapTupleBeingUpdated;
639  }
640 
641  /* not LOCKED_ONLY, so it has to have an xmax */
643 
645  {
646  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
647  return HeapTupleSelfUpdated; /* updated after scan started */
648  else
649  return HeapTupleInvisible; /* updated before scan started */
650  }
651 
653  return HeapTupleBeingUpdated;
654 
655  if (TransactionIdDidCommit(xmax))
656  return HeapTupleUpdated;
657 
658  /*
659  * By here, the update in the Xmax is either aborted or crashed, but
660  * what about the other members?
661  */
662 
664  {
665  /*
666  * There's no member, even just a locker, alive anymore, so we can
667  * mark the Xmax as invalid.
668  */
669  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
671  return HeapTupleMayBeUpdated;
672  }
673  else
674  {
675  /* There are lockers running */
676  return HeapTupleBeingUpdated;
677  }
678  }
679 
681  {
683  return HeapTupleBeingUpdated;
684  if (HeapTupleHeaderGetCmax(tuple) >= curcid)
685  return HeapTupleSelfUpdated; /* updated after scan started */
686  else
687  return HeapTupleInvisible; /* updated before scan started */
688  }
689 
691  return HeapTupleBeingUpdated;
692 
694  {
695  /* it must have aborted or crashed */
696  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
698  return HeapTupleMayBeUpdated;
699  }
700 
701  /* xmax transaction committed */
702 
704  {
705  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
707  return HeapTupleMayBeUpdated;
708  }
709 
710  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
712  return HeapTupleUpdated; /* updated by other */
713 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
#define HEAP_LOCKED_UPGRADED(infomask)
Definition: htup_details.h:238
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
Oid t_tableOid
Definition: htup.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup)
Definition: combocid.c:119
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly)
Definition: multixact.c:549
HTSV_Result HeapTupleSatisfiesVacuum ( HeapTuple  htup,
TransactionId  OldestXmin,
Buffer  buffer 
)

Definition at line 1164 of file tqual.c.

References Assert, HEAP_LOCKED_UPGRADED, HEAP_MOVED_IN, HEAP_MOVED_OFF, HEAP_XMAX_COMMITTED, HEAP_XMAX_INVALID, HEAP_XMAX_IS_LOCKED_ONLY, HEAP_XMAX_IS_MULTI, HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HEAPTUPLE_DEAD, HEAPTUPLE_DELETE_IN_PROGRESS, HEAPTUPLE_INSERT_IN_PROGRESS, HEAPTUPLE_LIVE, HEAPTUPLE_RECENTLY_DEAD, HeapTupleGetUpdateXid(), HeapTupleHeaderGetRawXmax, HeapTupleHeaderGetRawXmin, HeapTupleHeaderGetUpdateXid, HeapTupleHeaderGetXvac, HeapTupleHeaderIsOnlyLocked(), HeapTupleHeaderXminCommitted, HeapTupleHeaderXminInvalid, InvalidOid, InvalidTransactionId, ItemPointerIsValid, MultiXactIdIsRunning(), SetHintBits(), HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, HeapTupleData::t_self, HeapTupleData::t_tableOid, TransactionIdDidCommit(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdIsValid, and TransactionIdPrecedes().

Referenced by acquire_sample_rows(), CheckForSerializableConflictOut(), copy_heap_data(), heap_page_is_all_visible(), heap_prune_chain(), IndexBuildHeapRangeScan(), lazy_scan_heap(), statapprox_heap(), and tuple_all_visible().

1166 {
1167  HeapTupleHeader tuple = htup->t_data;
1168 
1169  Assert(ItemPointerIsValid(&htup->t_self));
1170  Assert(htup->t_tableOid != InvalidOid);
1171 
1172  /*
1173  * Has inserting transaction committed?
1174  *
1175  * If the inserting transaction aborted, then the tuple was never visible
1176  * to any other transaction, so we can delete it immediately.
1177  */
1178  if (!HeapTupleHeaderXminCommitted(tuple))
1179  {
1180  if (HeapTupleHeaderXminInvalid(tuple))
1181  return HEAPTUPLE_DEAD;
1182  /* Used by pre-9.0 binary upgrades */
1183  else if (tuple->t_infomask & HEAP_MOVED_OFF)
1184  {
1185  TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
1186 
1189  if (TransactionIdIsInProgress(xvac))
1191  if (TransactionIdDidCommit(xvac))
1192  {
1193  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1195  return HEAPTUPLE_DEAD;
1196  }
1197  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1199  }
1200  /* Used by pre-9.0 binary upgrades */
1201  else if (tuple->t_infomask & HEAP_MOVED_IN)
1202  {
1203  TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
1204 
1207  if (TransactionIdIsInProgress(xvac))
1209  if (TransactionIdDidCommit(xvac))
1210  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1212  else
1213  {
1214  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1216  return HEAPTUPLE_DEAD;
1217  }
1218  }
1220  {
1221  if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
1223  /* only locked? run infomask-only check first, for performance */
1224  if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
1227  /* inserted and then deleted by same xact */
1230  /* deleting subtransaction must have aborted */
1232  }
1234  {
1235  /*
1236  * It'd be possible to discern between INSERT/DELETE in progress
1237  * here by looking at xmax - but that doesn't seem beneficial for
1238  * the majority of callers and even detrimental for some. We'd
1239  * rather have callers look at/wait for xmin than xmax. It's
1240  * always correct to return INSERT_IN_PROGRESS because that's
1241  * what's happening from the view of other backends.
1242  */
1244  }
1246  SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
1247  HeapTupleHeaderGetRawXmin(tuple));
1248  else
1249  {
1250  /*
1251  * Not in Progress, Not Committed, so either Aborted or crashed
1252  */
1253  SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
1255  return HEAPTUPLE_DEAD;
1256  }
1257 
1258  /*
1259  * At this point the xmin is known committed, but we might not have
1260  * been able to set the hint bit yet; so we can no longer Assert that
1261  * it's set.
1262  */
1263  }
1264 
1265  /*
1266  * Okay, the inserter committed, so it was good at some point. Now what
1267  * about the deleting transaction?
1268  */
1269  if (tuple->t_infomask & HEAP_XMAX_INVALID)
1270  return HEAPTUPLE_LIVE;
1271 
1273  {
1274  /*
1275  * "Deleting" xact really only locked it, so the tuple is live in any
1276  * case. However, we should make sure that either XMAX_COMMITTED or
1277  * XMAX_INVALID gets set once the xact is gone, to reduce the costs of
1278  * examining the tuple for future xacts.
1279  */
1280  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1281  {
1282  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1283  {
1284  /*
1285  * If it's a pre-pg_upgrade tuple, the multixact cannot
1286  * possibly be running; otherwise have to check.
1287  */
1288  if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
1290  true))
1291  return HEAPTUPLE_LIVE;
1293  }
1294  else
1295  {
1297  return HEAPTUPLE_LIVE;
1298  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1300  }
1301  }
1302 
1303  /*
1304  * We don't really care whether xmax did commit, abort or crash. We
1305  * know that xmax did lock the tuple, but it did not and will never
1306  * actually update it.
1307  */
1308 
1309  return HEAPTUPLE_LIVE;
1310  }
1311 
1312  if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
1313  {
1314  TransactionId xmax;
1315 
1317  {
1318  /* already checked above */
1320 
1321  xmax = HeapTupleGetUpdateXid(tuple);
1322 
1323  /* not LOCKED_ONLY, so it has to have an xmax */
1325 
1326  if (TransactionIdIsInProgress(xmax))
1328  else if (TransactionIdDidCommit(xmax))
1329  /* there are still lockers around -- can't return DEAD here */
1330  return HEAPTUPLE_RECENTLY_DEAD;
1331  /* updating transaction aborted */
1332  return HEAPTUPLE_LIVE;
1333  }
1334 
1335  Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED));
1336 
1337  xmax = HeapTupleGetUpdateXid(tuple);
1338 
1339  /* not LOCKED_ONLY, so it has to have an xmax */
1341 
1342  /* multi is not running -- updating xact cannot be */
1344  if (TransactionIdDidCommit(xmax))
1345  {
1346  if (!TransactionIdPrecedes(xmax, OldestXmin))
1347  return HEAPTUPLE_RECENTLY_DEAD;
1348  else
1349  return HEAPTUPLE_DEAD;
1350  }
1351 
1352  /*
1353  * Not in Progress, Not Committed, so either Aborted or crashed.
1354  * Remove the Xmax.
1355  */
1357  return HEAPTUPLE_LIVE;
1358  }
1359 
1360  if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1361  {
1365  SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
1366  HeapTupleHeaderGetRawXmax(tuple));
1367  else
1368  {
1369  /*
1370  * Not in Progress, Not Committed, so either Aborted or crashed
1371  */
1372  SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
1374  return HEAPTUPLE_LIVE;
1375  }
1376 
1377  /*
1378  * At this point the xmax is known committed, but we might not have
1379  * been able to set the hint bit yet; so we can no longer Assert that
1380  * it's set.
1381  */
1382  }
1383 
1384  /*
1385  * Deleter committed, but perhaps it was recent enough that some open
1386  * transactions could still see the tuple.
1387  */
1389  return HEAPTUPLE_RECENTLY_DEAD;
1390 
1391  /* Otherwise, it's dead and removable */
1392  return HEAPTUPLE_DEAD;
1393 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:359
bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
Definition: tqual.c:1585
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
uint32 TransactionId
Definition: c.h:394
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:995
TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple)
Definition: heapam.c:6968
#define HEAP_LOCKED_UPGRADED(infomask)
Definition: htup_details.h:238
#define HeapTupleHeaderXminInvalid(tup)
Definition: htup_details.h:323
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:192
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
HeapTupleHeader t_data
Definition: htup.h:67
#define HEAP_XMIN_INVALID
Definition: htup_details.h:190
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:369
#define HEAP_XMAX_INVALID
Definition: htup_details.h:193
ItemPointerData t_self
Definition: htup.h:65
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
#define InvalidTransactionId
Definition: transam.h:31
#define HeapTupleHeaderGetXvac(tup)
Definition: htup_details.h:409
static TransactionId OldestXmin
Definition: vacuumlazy.c:138
Oid t_tableOid
Definition: htup.h:66
#define HEAP_MOVED_IN
Definition: htup_details.h:199
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define HEAP_XMAX_IS_LOCKED_ONLY(infomask)
Definition: htup_details.h:216
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:194
#define HEAP_XMIN_COMMITTED
Definition: htup_details.h:189
#define InvalidOid
Definition: postgres_ext.h:36
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
#define HEAP_MOVED_OFF
Definition: htup_details.h:196
#define Assert(condition)
Definition: c.h:671
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:302
#define TransactionIdIsValid(xid)
Definition: transam.h:41
bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly)
Definition: multixact.c:549
void HeapTupleSetHintBits ( HeapTupleHeader  tuple,
Buffer  buffer,
uint16  infomask,
TransactionId  xid 
)

Definition at line 144 of file tqual.c.

References SetHintBits().

Referenced by UpdateXmaxHintBits().

146 {
147  SetHintBits(tuple, buffer, infomask, xid);
148 }
static void SetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
Definition: tqual.c:117
bool ResolveCminCmaxDuringDecoding ( struct HTAB tuplecid_data,
Snapshot  snapshot,
HeapTuple  htup,
Buffer  buffer,
CommandId cmin,
CommandId cmax 
)

Definition at line 3274 of file reorderbuffer.c.

References Assert, BufferGetTag(), BufferIsLocal, ReorderBufferTupleCidEnt::cmax, ReorderBufferTupleCidEnt::cmin, HASH_FIND, hash_search(), ItemPointerCopy, ItemPointerGetBlockNumber, MAIN_FORKNUM, NULL, ReorderBufferTupleCidKey::relnode, HeapTupleData::t_self, HeapTupleData::t_tableOid, ReorderBufferTupleCidKey::tid, and UpdateLogicalMappings().

Referenced by HeapTupleSatisfiesHistoricMVCC().

3278 {
3281  ForkNumber forkno;
3282  BlockNumber blockno;
3283  bool updated_mapping = false;
3284 
3285  /* be careful about padding */
3286  memset(&key, 0, sizeof(key));
3287 
3288  Assert(!BufferIsLocal(buffer));
3289 
3290  /*
3291  * get relfilenode from the buffer, no convenient way to access it other
3292  * than that.
3293  */
3294  BufferGetTag(buffer, &key.relnode, &forkno, &blockno);
3295 
3296  /* tuples can only be in the main fork */
3297  Assert(forkno == MAIN_FORKNUM);
3298  Assert(blockno == ItemPointerGetBlockNumber(&htup->t_self));
3299 
3300  ItemPointerCopy(&htup->t_self,
3301  &key.tid);
3302 
3303 restart:
3304  ent = (ReorderBufferTupleCidEnt *)
3305  hash_search(tuplecid_data,
3306  (void *) &key,
3307  HASH_FIND,
3308  NULL);
3309 
3310  /*
3311  * failed to find a mapping, check whether the table was rewritten and
3312  * apply mapping if so, but only do that once - there can be no new
3313  * mappings while we are in here since we have to hold a lock on the
3314  * relation.
3315  */
3316  if (ent == NULL && !updated_mapping)
3317  {
3318  UpdateLogicalMappings(tuplecid_data, htup->t_tableOid, snapshot);
3319  /* now check but don't update for a mapping again */
3320  updated_mapping = true;
3321  goto restart;
3322  }
3323  else if (ent == NULL)
3324  return false;
3325 
3326  if (cmin)
3327  *cmin = ent->cmin;
3328  if (cmax)
3329  *cmax = ent->cmax;
3330  return true;
3331 }
uint32 BlockNumber
Definition: block.h:31
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66
ForkNumber
Definition: relpath.h:24
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define BufferIsLocal(buffer)
Definition: buf.h:37
static void UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot)
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2609
#define ItemPointerCopy(fromPointer, toPointer)
Definition: itemptr.h:120

Variable Documentation

PGDLLIMPORT SnapshotData CatalogSnapshotData

Definition at line 146 of file snapmgr.c.

PGDLLIMPORT SnapshotData SnapshotAnyData

Definition at line 80 of file tqual.c.

PGDLLIMPORT SnapshotData SnapshotSelfData

Definition at line 79 of file tqual.c.