tqual.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 1,080 行 · 第 1/3 页

C
1,080
字号
			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}	}	/* otherwise assume the tuple is valid for TOAST. */	return true;}/* * HeapTupleSatisfiesUpdate * *	Same logic as HeapTupleSatisfiesNow, but returns a more detailed result *	code, since UPDATE needs to know more than "is it visible?".  Also, *	tuples of my own xact are tested against the passed CommandId not *	CurrentCommandId. */intHeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return HeapTupleInvisible;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HeapTupleInvisible;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return HeapTupleInvisible;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return HeapTupleInvisible;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return HeapTupleInvisible;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (HeapTupleHeaderGetCmin(tuple) >= curcid)				return HeapTupleInvisible;		/* inserted after scan												 * started */			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return HeapTupleMayBeUpdated;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return HeapTupleMayBeUpdated;			if (HeapTupleHeaderGetCmax(tuple) >= curcid)				return HeapTupleSelfUpdated;	/* updated after scan												 * started */			else				return HeapTupleInvisible;		/* updated before scan												 * started */		}		else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))		{			if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))				tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */			return HeapTupleInvisible;		}		else			tuple->t_infomask |= HEAP_XMIN_COMMITTED;	}	/* by here, the inserting transaction has committed */	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */		return HeapTupleMayBeUpdated;	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return HeapTupleMayBeUpdated;		return HeapTupleUpdated;	/* updated by other */	}	if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return HeapTupleMayBeUpdated;		if (HeapTupleHeaderGetCmax(tuple) >= curcid)			return HeapTupleSelfUpdated;		/* updated after scan												 * started */		else			return HeapTupleInvisible;	/* updated before scan started */	}	if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))	{		if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))		{			tuple->t_infomask |= HEAP_XMAX_INVALID;		/* aborted */			return HeapTupleMayBeUpdated;		}		/* running xact */		return HeapTupleBeingUpdated;	/* in updation by other */	}	/* xmax transaction committed */	if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)	{		tuple->t_infomask |= HEAP_XMAX_INVALID;		return HeapTupleMayBeUpdated;	}	tuple->t_infomask |= HEAP_XMAX_COMMITTED;	return HeapTupleUpdated;	/* updated by other */}/* * HeapTupleSatisfiesDirty *		True iff heap tuple is valid including effects of open transactions. * *	Here, we consider the effects of: *		all committed and in-progress transactions (as of the current instant) *		previous commands of this transaction *		changes made by the current command * * This is essentially like HeapTupleSatisfiesItself as far as effects of * the current transaction and committed/aborted xacts are concerned. * However, we also include the effects of other xacts still in progress. * * Returns extra information in the global variable SnapshotDirty, namely * xids of concurrent xacts that affected the tuple.  Also, the tuple's * t_ctid (forward link) is returned if it's being updated. */boolHeapTupleSatisfiesDirty(HeapTupleHeader tuple){	SnapshotDirty->xmin = SnapshotDirty->xmax = InvalidTransactionId;	ItemPointerSetInvalid(&(SnapshotDirty->tid));	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return true;			return false;		}		else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))		{			if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))			{				tuple->t_infomask |= HEAP_XMIN_INVALID;				return false;			}			SnapshotDirty->xmin = HeapTupleHeaderGetXmin(tuple);			/* XXX shouldn't we fall through to look at xmax? */			return true;		/* in insertion by other */		}		else			tuple->t_infomask |= HEAP_XMIN_COMMITTED;	}	/* by here, the inserting transaction has committed */	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */		return true;	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return true;		SnapshotDirty->tid = tuple->t_ctid;		return false;			/* updated by other */	}	if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return true;		return false;	}	if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))	{		if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))		{			tuple->t_infomask |= HEAP_XMAX_INVALID;		/* aborted */			return true;		}		/* running xact */		SnapshotDirty->xmax = HeapTupleHeaderGetXmax(tuple);		return true;			/* in updation by other */	}	/* xmax transaction committed */	if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)	{		tuple->t_infomask |= HEAP_XMAX_INVALID;		return true;	}	tuple->t_infomask |= HEAP_XMAX_COMMITTED;	SnapshotDirty->tid = tuple->t_ctid;	return false;				/* updated by other */}/* * HeapTupleSatisfiesSnapshot *		True iff heap tuple is valid for the given snapshot. * *	Here, we consider the effects of: *		all transactions committed as of the time of the given snapshot *		previous commands of this transaction * *	Does _not_ include: *		transactions shown as in-progress by the snapshot *		transactions started after the snapshot was taken *		changes made by the current command * * This is the same as HeapTupleSatisfiesNow, except that transactions that * were in progress or as yet unstarted when the snapshot was taken will * be treated as uncommitted, even if they have committed by now. * * (Notice, however, that the tuple status hint bits will be updated on the * basis of the true state of the transaction, even if we then pretend we * can't see it.) */boolHeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)				return false;	/* inserted after scan started */			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return true;			if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?