src/backend/utils/adt/xid8funcs.c
static bool
TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid)
{
	uint32		xid_epoch = EpochFromFullTransactionId(fxid);
	TransactionId xid = XidFromFullTransactionId(fxid);
	uint32		now_epoch;
	TransactionId now_epoch_next_xid;
	FullTransactionId now_fullxid;

	now_fullxid = ReadNextFullTransactionId();
	now_epoch_next_xid = XidFromFullTransactionId(now_fullxid);
	now_epoch = EpochFromFullTransactionId(now_fullxid);

	if (extracted_xid != NULL)
		*extracted_xid = xid;

	if (!TransactionIdIsValid(xid))
		return false;

	/* For non-normal transaction IDs, we can ignore the epoch. */
	if (!TransactionIdIsNormal(xid))
		return true;

	/* If the transaction ID is in the future, throw an error. */
	if (!FullTransactionIdPrecedes(fxid, now_fullxid))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("transaction ID %s is in the future",
						psprintf(UINT64_FORMAT,
								 U64FromFullTransactionId(fxid)))));

	/*
	 * ShmemVariableCache->oldestClogXid is protected by XactTruncationLock,
	 * but we don't acquire that lock here.  Instead, we require the caller to
	 * acquire it, because the caller is presumably going to look up the
	 * returned XID.  If we took and released the lock within this function, a
	 * CLOG truncation could occur before the caller finished with the XID.
	 */
	Assert(LWLockHeldByMe(XactTruncationLock));

	/*
	 * If the transaction ID has wrapped around, it's definitely too old to
	 * determine the commit status.  Otherwise, we can compare it to
	 * ShmemVariableCache->oldestClogXid to determine whether the relevant
	 * CLOG entry is guaranteed to still exist.
	 */
	if (xid_epoch + 1 < now_epoch
		|| (xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid)
		|| TransactionIdPrecedes(xid, ShmemVariableCache->oldestClogXid))
		return false;

	return true;
}
/*
 * Helper to get a TransactionId from a 64-bit xid with wraparound detection.
 *
 * It is an ERROR if the xid is in the future.  Otherwise, returns true if
 * the transaction is still new enough that we can determine whether it
 * committed and false otherwise.  If *extracted_xid is not NULL, it is set
 * to the low 32 bits of the transaction ID (i.e. the actual XID, without the
 * epoch).
 *
 * The caller must hold XactTruncationLock since it's dealing with arbitrary
 * XIDs, and must continue to hold it until it's done with any clog lookups
 * relating to those XIDs.
 */
Helper to get a TransactionId from a 64-bit xid with wraparound detection.
It is an ERROR if the xid is in the future.  Otherwise, returns true if
the transaction is still new enough that we can determine whether it
committed and false otherwise.  If *extracted_xid is not NULL, it is set
to the low 32 bits of the transaction ID .

The caller must hold XactTruncationLock since it's dealing with arbitrary
XIDs, and must continue to hold it until it's done with any clog lookups
relating to those XIDs.
Helper to get a TransactionId from a 64 - bit xid with wraparound detection . It is an ERROR if the xid is in the future . Otherwise returns true if the transaction is still new enough that we can determine whether it committed and false otherwise . If * extracted_xid is not NULL it is set to the low 32 bits of the transaction ID . The caller must hold XactTruncationLock since it ' s dealing with arbitrary XIDs and must continue to hold it until it ' s done with any clog lookups relating to those XIDs .
static bool
TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid)
{
	uint32		xid_epoch = EpochFromFullTransactionId(fxid);
	TransactionId xid = XidFromFullTransactionId(fxid);
	uint32		now_epoch;
	TransactionId now_epoch_next_xid;
	FullTransactionId now_fullxid;
	now_fullxid = ReadNextFullTransactionId();
	now_epoch_next_xid = XidFromFullTransactionId(now_fullxid);
	now_epoch = EpochFromFullTransactionId(now_fullxid);
	if (extracted_xid != NULL)
		*extracted_xid = xid;
	if (!TransactionIdIsValid(xid))
		return false;
	if (!TransactionIdIsNormal(xid))
		return true;
	if (!FullTransactionIdPrecedes(fxid, now_fullxid))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("transaction ID %s is in the future",
						psprintf(UINT64_FORMAT,
								 U64FromFullTransactionId(fxid)))));
	Assert(LWLockHeldByMe(XactTruncationLock));
	if (xid_epoch + 1 < now_epoch
		|| (xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid)
		|| TransactionIdPrecedes(xid, ShmemVariableCache->oldestClogXid))
		return false;
	return true;
}
static bool TransactionIdInRecentPast ( FullTransactionId fxid , TransactionId * extracted_xid ) { uint32 xid_epoch = EpochFromFullTransactionId ( fxid ) ; TransactionId xid = XidFromFullTransactionId ( fxid ) ; uint32 now_epoch ; TransactionId now_epoch_next_xid ; FullTransactionId now_fullxid ; now_fullxid = ReadNextFullTransactionId ( ) ; now_epoch_next_xid = XidFromFullTransactionId ( now_fullxid ) ; now_epoch = EpochFromFullTransactionId ( now_fullxid ) ; if ( extracted_xid != NULL ) * extracted_xid = xid ; if ( ! TransactionIdIsValid ( xid ) ) return false ; if ( ! TransactionIdIsNormal ( xid ) ) return true ; if ( ! FullTransactionIdPrecedes ( fxid , now_fullxid ) ) ereport ( ERROR , ( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) , errmsg ( " " , psprintf ( UINT64_FORMAT , U64FromFullTransactionId ( fxid ) ) ) ) ) ; Assert ( LWLockHeldByMe ( XactTruncationLock ) ) ; if ( xid_epoch + 1 < now_epoch || ( xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid ) || TransactionIdPrecedes ( xid , ShmemVariableCache -> oldestClogXid ) ) return false ; return true ; }
Helper to get a TransactionId from a 64-bit xid with wraparound detection.
Helper to get a TransactionId from a 64 - bit xid with wraparound detection .
/* For non-normal transaction IDs, we can ignore the epoch. */ /* If the transaction ID is in the future, throw an error. */ /*
	 * ShmemVariableCache->oldestClogXid is protected by XactTruncationLock,
	 * but we don't acquire that lock here.  Instead, we require the caller to
	 * acquire it, because the caller is presumably going to look up the
	 * returned XID.  If we took and released the lock within this function, a
	 * CLOG truncation could occur before the caller finished with the XID.
	 */ /*
	 * If the transaction ID has wrapped around, it's definitely too old to
	 * determine the commit status.  Otherwise, we can compare it to
	 * ShmemVariableCache->oldestClogXid to determine whether the relevant
	 * CLOG entry is guaranteed to still exist.
	 */