📄 tqual.c
字号:
if (TransactionIdDidCommit(xvac)) { tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } } 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; SetBufferCommitInfoNeedsSave(buffer); } else { tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); 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. * * The possible return codes are: * * HeapTupleInvisible: the tuple didn't exist at all when the scan started, * e.g. it was created by a later CommandId. * * HeapTupleMayBeUpdated: The tuple is valid and visible, so it may be * updated. * * HeapTupleSelfUpdated: The tuple was updated by the current transaction, * after the current scan started. * * HeapTupleUpdated: The tuple was updated by a committed transaction. * * HeapTupleBeingUpdated: The tuple is being updated by an in-progress * transaction other than the current transaction. */HTSU_ResultHeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, Buffer buffer){ 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; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleInvisible; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } } 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; SetBufferCommitInfoNeedsSave(buffer); } else { tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); 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; if (tuple->t_infomask & HEAP_IS_LOCKED) /* not deleter */ return HeapTupleMayBeUpdated; Assert(!(tuple->t_infomask & HEAP_XMAX_IS_MULTI)); /* deleting subtransaction aborted? */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) { tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleMayBeUpdated; } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); if (HeapTupleHeaderGetCmax(tuple) >= curcid) return HeapTupleSelfUpdated; /* updated after scan started */ else return HeapTupleInvisible; /* updated before scan started */ } else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) return HeapTupleInvisible; else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) { tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } else { /* it must have aborted or crashed */ tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleInvisible; } } /* 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_IS_LOCKED) return HeapTupleMayBeUpdated; return HeapTupleUpdated; /* updated by other */ } if (tuple->t_infomask & HEAP_XMAX_IS_MULTI) { /* MultiXacts are currently only allowed to lock tuples */ Assert(tuple->t_infomask & HEAP_IS_LOCKED); if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple))) return HeapTupleBeingUpdated; tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleMayBeUpdated; } if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))) { if (tuple->t_infomask & HEAP_IS_LOCKED) return HeapTupleMayBeUpdated; if (HeapTupleHeaderGetCmax(tuple) >= curcid) return HeapTupleSelfUpdated; /* updated after scan started */ else return HeapTupleInvisible; /* updated before scan started */ } if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple))) return HeapTupleBeingUpdated; if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) { /* it must have aborted or crashed */ tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleMayBeUpdated; } /* xmax transaction committed */ if (tuple->t_infomask & HEAP_IS_LOCKED) { tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return HeapTupleMayBeUpdated; } tuple->t_infomask |= HEAP_XMAX_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); 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. SnapshotDirty->xmin * is set to InvalidTransactionId if xmin is either committed good or * committed dead; or to xmin if that transaction is still in progress. * Similarly for SnapshotDirty->xmax. */boolHeapTupleSatisfiesDirty(HeapTupleHeader tuple, Buffer buffer){ SnapshotDirty->xmin = SnapshotDirty->xmax = InvalidTransactionId; 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; SetBufferCommitInfoNeedsSave(buffer); return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } } 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; SetBufferCommitInfoNeedsSave(buffer); } else { tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); return false; } } } else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple))) { if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ return true; if (tuple->t_infomask & HEAP_IS_LOCKED) /* not deleter */ return true; Assert(!(tuple->t_infomask & HEAP_XMAX_IS_MULTI)); /* deleting subtransaction aborted? */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) { tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return true; } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); return false; } else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) { SnapshotDirty->xmin = HeapTupleHeaderGetXmin(tuple); /* XXX shouldn't we fall through to look at xmax? */ return true; /* in insertion by other */ } else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) { tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } else { /* it must have aborted or crashed */ tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); return false; } } /* 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_IS_LOCKED) return true; return false; /* updated by other */ } if (tuple->t_infomask & HEAP_XMAX_IS_MULTI) { /* MultiXacts are currently only allowed to lock tuples */ Assert(tuple->t_infomask & HEAP_IS_LOCKED); return true; } if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))) { if (tuple->t_infomask & HEAP_IS_LOCKED) return true; return false; } if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple))) { SnapshotDirty->xmax = HeapTupleHeaderGetXmax(tuple); return true; } if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) { /* it must have aborted or crashed */ tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return true; } /* xmax transaction committed */ if (tuple->t_infomask & HEAP_IS_LOCKED) { tuple->t_infomask |= HEAP_XMAX_INVALID; SetBufferCommitInfoNeedsSave(buffer); return true; } tuple->t_infomask |= HEAP_XMAX_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); 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, Buffer buffer){ 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; SetBufferCommitInfoNeedsSave(buffer); return false; } tuple->t_infomask |= HEAP_XMIN_COMMITTED; SetBufferCommitInfoNeedsSave(buffer); } } 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; SetBufferCommitInfoNeedsSave(buffer); } else { tuple->t_infomask |= HEAP_XMIN_INVALID; SetBufferCommitInfoNeedsSave(buffer); return false; } } } else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple))) { if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid) return false; /* inserted after scan started */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -