diff options
Diffstat (limited to 'src/backend/utils/time/tqual.c')
-rw-r--r-- | src/backend/utils/time/tqual.c | 1263 |
1 files changed, 673 insertions, 590 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 1fcf3679fe4..2a85ecd712b 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * tqual.c-- - * POSTGRES time qualification code. + * POSTGRES time qualification code. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.4 1997/08/29 09:04:54 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.5 1997/09/07 04:54:20 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -29,23 +29,23 @@ static AbsoluteTime TimeQualGetEndTime(TimeQual qual); static AbsoluteTime TimeQualGetSnapshotTime(TimeQual qual); static AbsoluteTime TimeQualGetStartTime(TimeQual qual); -static bool TimeQualIncludesNow(TimeQual qual); -static bool TimeQualIndicatesDisableValidityChecking(TimeQual qual); -static bool TimeQualIsLegal(TimeQual qual); -static bool TimeQualIsRanged(TimeQual qual); -static bool TimeQualIsSnapshot(TimeQual qual); -static bool TimeQualIsValid(TimeQual qual); +static bool TimeQualIncludesNow(TimeQual qual); +static bool TimeQualIndicatesDisableValidityChecking(TimeQual qual); +static bool TimeQualIsLegal(TimeQual qual); +static bool TimeQualIsRanged(TimeQual qual); +static bool TimeQualIsSnapshot(TimeQual qual); +static bool TimeQualIsValid(TimeQual qual); /* * TimeQualMode -- - * Mode indicator for treatment of time qualifications. + * Mode indicator for treatment of time qualifications. */ typedef uint16 TimeQualMode; -#define TimeQualAt 0x1 +#define TimeQualAt 0x1 #define TimeQualNewer 0x2 #define TimeQualOlder 0x4 -#define TimeQualAll 0x8 +#define TimeQualAll 0x8 #define TimeQualMask 0xf @@ -53,820 +53,903 @@ typedef uint16 TimeQualMode; #define TimeQualRange (TimeQualNewer | TimeQualOlder) #define TimeQualAllAt (TimeQualAt | TimeQualAll) -typedef struct TimeQualData { - AbsoluteTime start; - AbsoluteTime end; - TimeQualMode mode; -} TimeQualData; +typedef struct TimeQualData +{ + AbsoluteTime start; + AbsoluteTime end; + TimeQualMode mode; +} TimeQualData; -typedef TimeQualData *InternalTimeQual; +typedef TimeQualData *InternalTimeQual; -static TimeQualData SelfTimeQualData; -TimeQual SelfTimeQual = (Pointer)&SelfTimeQualData; +static TimeQualData SelfTimeQualData; +TimeQual SelfTimeQual = (Pointer) & SelfTimeQualData; extern bool PostgresIsInitialized; /* * XXX Transaction system override hacks start here */ -#ifndef GOODAMI +#ifndef GOODAMI -static TransactionId HeapSpecialTransactionId = InvalidTransactionId; -static CommandId HeapSpecialCommandId = FirstCommandId; +static TransactionId HeapSpecialTransactionId = InvalidTransactionId; +static CommandId HeapSpecialCommandId = FirstCommandId; void setheapoverride(bool on) { - if (on) { - TransactionIdStore(GetCurrentTransactionId(), - &HeapSpecialTransactionId); - HeapSpecialCommandId = GetCurrentCommandId(); - } else { - HeapSpecialTransactionId = InvalidTransactionId; - } + if (on) + { + TransactionIdStore(GetCurrentTransactionId(), + &HeapSpecialTransactionId); + HeapSpecialCommandId = GetCurrentCommandId(); + } + else + { + HeapSpecialTransactionId = InvalidTransactionId; + } } /* static */ bool heapisoverride() { - if (!TransactionIdIsValid(HeapSpecialTransactionId)) { - return (false); - } - - if (!TransactionIdEquals(GetCurrentTransactionId(), - HeapSpecialTransactionId) || - GetCurrentCommandId() != HeapSpecialCommandId) { - HeapSpecialTransactionId = InvalidTransactionId; - - return (false); - } - return (true); + if (!TransactionIdIsValid(HeapSpecialTransactionId)) + { + return (false); + } + + if (!TransactionIdEquals(GetCurrentTransactionId(), + HeapSpecialTransactionId) || + GetCurrentCommandId() != HeapSpecialCommandId) + { + HeapSpecialTransactionId = InvalidTransactionId; + + return (false); + } + return (true); } -#endif /* !defined(GOODAMI) */ +#endif /* !defined(GOODAMI) */ /* * XXX Transaction system override hacks end here */ -static bool HeapTupleSatisfiesItself(HeapTuple tuple); -static bool HeapTupleSatisfiesNow(HeapTuple tuple); -static bool HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual); -static bool HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual); -static bool HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual); +static bool HeapTupleSatisfiesItself(HeapTuple tuple); +static bool HeapTupleSatisfiesNow(HeapTuple tuple); +static bool +HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple, + InternalTimeQual qual); +static bool +HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple, + InternalTimeQual qual); +static bool +HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple, + InternalTimeQual qual); + - /* * TimeQualIsValid -- - * True iff time qualification is valid. + * True iff time qualification is valid. */ -static bool +static bool TimeQualIsValid(TimeQual qual) { - bool hasStartTime; - - if (!PointerIsValid(qual) || qual == SelfTimeQual) { + bool hasStartTime; + + if (!PointerIsValid(qual) || qual == SelfTimeQual) + { + return (true); + } + + if (((InternalTimeQual) qual)->mode & ~TimeQualMask) + { + return (false); + } + + if (((InternalTimeQual) qual)->mode & TimeQualAt) + { + return (AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->start)); + } + + hasStartTime = false; + + if (((InternalTimeQual) qual)->mode & TimeQualNewer) + { + if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->start)) + { + return (false); + } + hasStartTime = true; + } + + if (((InternalTimeQual) qual)->mode & TimeQualOlder) + { + if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->end)) + { + return (false); + } + if (hasStartTime) + { + return ((bool) ! AbsoluteTimeIsBefore( + ((InternalTimeQual) qual)->end, + ((InternalTimeQual) qual)->start)); + } + } return (true); - } - - if (((InternalTimeQual)qual)->mode & ~TimeQualMask) { - return (false); - } - - if (((InternalTimeQual)qual)->mode & TimeQualAt) { - return (AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->start)); - } - - hasStartTime = false; - - if (((InternalTimeQual)qual)->mode & TimeQualNewer) { - if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->start)) { - return (false); - } - hasStartTime = true; - } - - if (((InternalTimeQual)qual)->mode & TimeQualOlder) { - if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->end)) { - return (false); - } - if (hasStartTime) { - return ((bool)!AbsoluteTimeIsBefore( - ((InternalTimeQual)qual)->end, - ((InternalTimeQual)qual)->start)); - } - } - return (true); } /* * TimeQualIsLegal -- - * True iff time qualification is legal. - * I.e., true iff time qualification does not intersects the future, - * relative to the transaction start time. + * True iff time qualification is legal. + * I.e., true iff time qualification does not intersects the future, + * relative to the transaction start time. * * Note: - * Assumes time qualification is valid. + * Assumes time qualification is valid. */ -static bool +static bool TimeQualIsLegal(TimeQual qual) { - Assert(TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (true); + } + + /* TimeQualAt */ + if (((InternalTimeQual) qual)->mode & TimeQualAt) + { + AbsoluteTime a, + b; + + a = ((InternalTimeQual) qual)->start; + b = GetCurrentTransactionStartTime(); + + if (AbsoluteTimeIsAfter(a, b)) + return (false); + else + return (true); + } + + /* TimeQualOlder or TimeQualRange */ + if (((InternalTimeQual) qual)->mode & TimeQualOlder) + { + AbsoluteTime a, + b; + + a = ((InternalTimeQual) qual)->end; + b = GetCurrentTransactionStartTime(); + + if (AbsoluteTimeIsAfter(a, b)) + return (false); + else + return (true); + } + + /* TimeQualNewer */ + if (((InternalTimeQual) qual)->mode & TimeQualNewer) + { + AbsoluteTime a, + b; + + a = ((InternalTimeQual) qual)->start; + b = GetCurrentTransactionStartTime(); + + if (AbsoluteTimeIsAfter(a, b)) + return (false); + else + return (true); + } + + /* TimeQualEvery */ return (true); - } - - /* TimeQualAt */ - if (((InternalTimeQual)qual)->mode & TimeQualAt) { - AbsoluteTime a, b; - - a = ((InternalTimeQual)qual)->start; - b = GetCurrentTransactionStartTime(); - - if (AbsoluteTimeIsAfter(a, b)) - return (false); - else - return (true); - } - - /* TimeQualOlder or TimeQualRange */ - if (((InternalTimeQual)qual)->mode & TimeQualOlder) { - AbsoluteTime a, b; - - a = ((InternalTimeQual)qual)->end; - b = GetCurrentTransactionStartTime(); - - if (AbsoluteTimeIsAfter(a, b)) - return (false); - else - return (true); - } - - /* TimeQualNewer */ - if (((InternalTimeQual)qual)->mode & TimeQualNewer) { - AbsoluteTime a, b; - - a = ((InternalTimeQual)qual)->start; - b = GetCurrentTransactionStartTime(); - - if (AbsoluteTimeIsAfter(a, b)) - return (false); - else - return (true); - } - - /* TimeQualEvery */ - return (true); } /* * TimeQualIncludesNow -- - * True iff time qualification includes "now." + * True iff time qualification includes "now." * * Note: - * Assumes time qualification is valid. + * Assumes time qualification is valid. */ -static bool +static bool TimeQualIncludesNow(TimeQual qual) { - Assert(TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (true); + } + + if (((InternalTimeQual) qual)->mode & TimeQualAt) + { + return (false); + } + if (((InternalTimeQual) qual)->mode & TimeQualOlder && + !AbsoluteTimeIsAfter( + ((InternalTimeQual) qual)->end, + GetCurrentTransactionStartTime())) + { + + return (false); + } return (true); - } - - if (((InternalTimeQual)qual)->mode & TimeQualAt) { - return (false); - } - if (((InternalTimeQual)qual)->mode & TimeQualOlder && - !AbsoluteTimeIsAfter( - ((InternalTimeQual)qual)->end, - GetCurrentTransactionStartTime())) { - - return (false); - } - return (true); } /* * TimeQualIncludesPast -- - * True iff time qualification includes some time in the past. + * True iff time qualification includes some time in the past. * * Note: - * Assumes time qualification is valid. - * XXX may not be needed? + * Assumes time qualification is valid. + * XXX may not be needed? */ #ifdef NOT_USED bool TimeQualIncludesPast(TimeQual qual) { - Assert(TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { - return (false); - } - - /* otherwise, must check archive (setting locks as appropriate) */ - return (true); + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (false); + } + + /* otherwise, must check archive (setting locks as appropriate) */ + return (true); } + #endif /* * TimeQualIsSnapshot -- - * True iff time qualification is a snapshot qualification. + * True iff time qualification is a snapshot qualification. * * Note: - * Assumes time qualification is valid. + * Assumes time qualification is valid. */ -static bool +static bool TimeQualIsSnapshot(TimeQual qual) { - Assert(TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { - return (false); - } - - return ((bool)!!(((InternalTimeQual)qual)->mode & TimeQualAt)); + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (false); + } + + return ((bool) ! !(((InternalTimeQual) qual)->mode & TimeQualAt)); } /* * TimeQualIsRanged -- - * True iff time qualification is a ranged qualification. + * True iff time qualification is a ranged qualification. * * Note: - * Assumes time qualification is valid. + * Assumes time qualification is valid. */ -static bool +static bool TimeQualIsRanged(TimeQual qual) { - Assert(TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { - return (false); - } - - return ((bool)!(((InternalTimeQual)qual)->mode & TimeQualAt)); + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (false); + } + + return ((bool) ! (((InternalTimeQual) qual)->mode & TimeQualAt)); } /* * TimeQualIndicatesDisableValidityChecking -- - * True iff time qualification indicates validity checking should be - * disabled. + * True iff time qualification indicates validity checking should be + * disabled. * * Note: - * XXX This should not be implemented since this does not make sense. + * XXX This should not be implemented since this does not make sense. */ -static bool +static bool TimeQualIndicatesDisableValidityChecking(TimeQual qual) { - Assert (TimeQualIsValid(qual)); - - if (qual == NowTimeQual || qual == SelfTimeQual) { + Assert(TimeQualIsValid(qual)); + + if (qual == NowTimeQual || qual == SelfTimeQual) + { + return (false); + } + + if (((InternalTimeQual) qual)->mode & TimeQualAll) + { + return (true); + } return (false); - } - - if (((InternalTimeQual)qual)->mode & TimeQualAll) { - return (true); - } - return (false); } /* * TimeQualGetSnapshotTime -- - * Returns time for a snapshot time qual. + * Returns time for a snapshot time qual. * * Note: - * Assumes time qual is valid snapshot time qual. + * Assumes time qual is valid snapshot time qual. */ -static AbsoluteTime +static AbsoluteTime TimeQualGetSnapshotTime(TimeQual qual) { - Assert(TimeQualIsSnapshot(qual)); - - return (((InternalTimeQual)qual)->start); + Assert(TimeQualIsSnapshot(qual)); + + return (((InternalTimeQual) qual)->start); } /* * TimeQualGetStartTime -- - * Returns start time for a ranged time qual. + * Returns start time for a ranged time qual. * * Note: - * Assumes time qual is valid ranged time qual. + * Assumes time qual is valid ranged time qual. */ -static AbsoluteTime +static AbsoluteTime TimeQualGetStartTime(TimeQual qual) { - Assert(TimeQualIsRanged(qual)); - - return (((InternalTimeQual)qual)->start); + Assert(TimeQualIsRanged(qual)); + + return (((InternalTimeQual) qual)->start); } /* * TimeQualGetEndTime -- - * Returns end time for a ranged time qual. + * Returns end time for a ranged time qual. * * Note: - * Assumes time qual is valid ranged time qual. + * Assumes time qual is valid ranged time qual. */ -static AbsoluteTime +static AbsoluteTime TimeQualGetEndTime(TimeQual qual) { - Assert(TimeQualIsRanged(qual)); - - return (((InternalTimeQual)qual)->end); + Assert(TimeQualIsRanged(qual)); + + return (((InternalTimeQual) qual)->end); } /* * TimeFormSnapshotTimeQual -- - * Returns snapshot time qual for a time. + * Returns snapshot time qual for a time. * * Note: - * Assumes time is valid. + * Assumes time is valid. */ TimeQual TimeFormSnapshotTimeQual(AbsoluteTime time) { - InternalTimeQual qual; - - Assert(AbsoluteTimeIsBackwardCompatiblyValid(time)); - - qual = (InternalTimeQual)palloc(sizeof *qual); - - qual->start = time; - qual->end = INVALID_ABSTIME; - qual->mode = TimeQualAt; - - return ((TimeQual)qual); + InternalTimeQual qual; + + Assert(AbsoluteTimeIsBackwardCompatiblyValid(time)); + + qual = (InternalTimeQual) palloc(sizeof *qual); + + qual->start = time; + qual->end = INVALID_ABSTIME; + qual->mode = TimeQualAt; + + return ((TimeQual) qual); } /* * TimeFormRangedTimeQual -- - * Returns ranged time qual for a pair of times. + * Returns ranged time qual for a pair of times. * * Note: - * If start time is invalid, it is regarded as the epoch. - * If end time is invalid, it is regarded as "now." - * Assumes start time is before (or the same as) end time. + * If start time is invalid, it is regarded as the epoch. + * If end time is invalid, it is regarded as "now." + * Assumes start time is before (or the same as) end time. */ TimeQual TimeFormRangedTimeQual(AbsoluteTime startTime, - AbsoluteTime endTime) + AbsoluteTime endTime) { - InternalTimeQual qual; - - qual = (InternalTimeQual)palloc(sizeof *qual); - - qual->start = startTime; - qual->end = endTime; - qual->mode = TimeQualEvery; - - if (AbsoluteTimeIsBackwardCompatiblyValid(startTime)) { - qual->mode |= TimeQualNewer; - } - if (AbsoluteTimeIsBackwardCompatiblyValid(endTime)) { - qual->mode |= TimeQualOlder; - } - - return ((TimeQual)qual); + InternalTimeQual qual; + + qual = (InternalTimeQual) palloc(sizeof *qual); + + qual->start = startTime; + qual->end = endTime; + qual->mode = TimeQualEvery; + + if (AbsoluteTimeIsBackwardCompatiblyValid(startTime)) + { + qual->mode |= TimeQualNewer; + } + if (AbsoluteTimeIsBackwardCompatiblyValid(endTime)) + { + qual->mode |= TimeQualOlder; + } + + return ((TimeQual) qual); } /* * HeapTupleSatisfiesTimeQual -- - * True iff heap tuple satsifies a time qual. + * True iff heap tuple satsifies a time qual. * * Note: - * Assumes heap tuple is valid. - * Assumes time qual is valid. - * XXX Many of the checks may be simplified and still remain correct. - * XXX Partial answers to the checks may be cached in an ItemId. + * Assumes heap tuple is valid. + * Assumes time qual is valid. + * XXX Many of the checks may be simplified and still remain correct. + * XXX Partial answers to the checks may be cached in an ItemId. */ bool HeapTupleSatisfiesTimeQual(HeapTuple tuple, TimeQual qual) { -/* extern TransactionId AmiTransactionId; */ - - Assert(HeapTupleIsValid(tuple)); - Assert(TimeQualIsValid(qual)); - - if (TransactionIdEquals(tuple->t_xmax, AmiTransactionId)) - return(false); - - if (qual == SelfTimeQual || heapisoverride()) { - return (HeapTupleSatisfiesItself(tuple)); - } - - if (qual == NowTimeQual) { - return (HeapTupleSatisfiesNow(tuple)); - } - - if (!TimeQualIsLegal(qual)) { - elog(WARN, "HeapTupleSatisfiesTimeQual: illegal time qual"); - } - - if (TimeQualIndicatesDisableValidityChecking(qual)) { - elog(WARN, "HeapTupleSatisfiesTimeQual: no disabled validity checking (yet)"); - } - - if (TimeQualIsSnapshot(qual)) { - return (HeapTupleSatisfiesSnapshotInternalTimeQual(tuple, - (InternalTimeQual)qual)); - } - - if (TimeQualIncludesNow(qual)) { - return (HeapTupleSatisfiesUpperUnboundedInternalTimeQual(tuple, - (InternalTimeQual)qual)); - } - - return (HeapTupleSatisfiesUpperBoundedInternalTimeQual(tuple, - (InternalTimeQual)qual)); +/* extern TransactionId AmiTransactionId; */ + + Assert(HeapTupleIsValid(tuple)); + Assert(TimeQualIsValid(qual)); + + if (TransactionIdEquals(tuple->t_xmax, AmiTransactionId)) + return (false); + + if (qual == SelfTimeQual || heapisoverride()) + { + return (HeapTupleSatisfiesItself(tuple)); + } + + if (qual == NowTimeQual) + { + return (HeapTupleSatisfiesNow(tuple)); + } + + if (!TimeQualIsLegal(qual)) + { + elog(WARN, "HeapTupleSatisfiesTimeQual: illegal time qual"); + } + + if (TimeQualIndicatesDisableValidityChecking(qual)) + { + elog(WARN, "HeapTupleSatisfiesTimeQual: no disabled validity checking (yet)"); + } + + if (TimeQualIsSnapshot(qual)) + { + return (HeapTupleSatisfiesSnapshotInternalTimeQual(tuple, + (InternalTimeQual) qual)); + } + + if (TimeQualIncludesNow(qual)) + { + return (HeapTupleSatisfiesUpperUnboundedInternalTimeQual(tuple, + (InternalTimeQual) qual)); + } + + return (HeapTupleSatisfiesUpperBoundedInternalTimeQual(tuple, + (InternalTimeQual) qual)); } /* * HeapTupleSatisfiesItself -- - * True iff heap tuple is valid for "itself." - * "{it}self" means valid as of everything that's happened - * in the current transaction, _including_ the current command. + * True iff heap tuple is valid for "itself." + * "{it}self" means valid as of everything that's happened + * in the current transaction, _including_ the current command. * * Note: - * Assumes heap tuple is valid. + * Assumes heap tuple is valid. */ /* * The satisfaction of "itself" requires the following: * - * ((Xmin == my-transaction && the row was updated by the current transaction, and - * (Xmax is null it was not deleted - * [|| Xmax != my-transaction)]) [or it was deleted by another transaction] + * ((Xmin == my-transaction && the row was updated by the current transaction, and + * (Xmax is null it was not deleted + * [|| Xmax != my-transaction)]) [or it was deleted by another transaction] * || * - * (Xmin is committed && the row was modified by a committed transaction, and - * (Xmax is null || the row has not been deleted, or - * (Xmax != my-transaction && the row was deleted by another transaction - * Xmax is not committed))) that has not been committed + * (Xmin is committed && the row was modified by a committed transaction, and + * (Xmax is null || the row has not been deleted, or + * (Xmax != my-transaction && the row was deleted by another transaction + * Xmax is not committed))) that has not been committed */ -static bool +static bool HeapTupleSatisfiesItself(HeapTuple tuple) { - /* - * XXX Several evil casts are made in this routine. Casting XID to be - * TransactionId works only because TransactionId->data is the first - * (and only) field of the structure. - */ - if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && - !TransactionIdIsValid((TransactionId)tuple->t_xmax)) { - return (true); - } - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { - return (false); - } - - tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); - } - /* the tuple was inserted validly */ - - if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) { - return (false); - } - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { - return (true); - } - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) { - return (false); - } - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { - return (true); - } - - /* by here, deleting transaction has committed */ - tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + /* + * XXX Several evil casts are made in this routine. Casting XID to be + * TransactionId works only because TransactionId->data is the first + * (and only) field of the structure. + */ + if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) + { + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) && + !TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin)) + { + return (false); + } + + tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); + } + /* the tuple was inserted validly */ - return (false); + if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) + { + return (false); + } + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax)) + { + return (false); + } + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax)) + { + return (true); + } + + /* by here, deleting transaction has committed */ + tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + + return (false); } /* * HeapTupleSatisfiesNow -- - * True iff heap tuple is valid "now." - * "now" means valid including everything that's happened - * in the current transaction _up to, but not including,_ - * the current command. + * True iff heap tuple is valid "now." + * "now" means valid including everything that's happened + * in the current transaction _up to, but not including,_ + * the current command. * * Note: - * Assumes heap tuple is valid. + * Assumes heap tuple is valid. */ /* * The satisfaction of "now" requires the following: * - * ((Xmin == my-transaction && changed by the current transaction - * Cmin != my-command && but not by this command, and - * (Xmax is null || the row has not been deleted, or - * (Xmax == my-transaction && it was deleted by the current transaction - * Cmax != my-command))) but not by this command, - * || or + * ((Xmin == my-transaction && changed by the current transaction + * Cmin != my-command && but not by this command, and + * (Xmax is null || the row has not been deleted, or + * (Xmax == my-transaction && it was deleted by the current transaction + * Cmax != my-command))) but not by this command, + * || or * - * (Xmin is committed && the row was modified by a committed transaction, and - * (Xmax is null || the row has not been deleted, or - * (Xmax == my-transaction && the row is being deleted by this command, or - * Cmax == my-command) || - * (Xmax is not committed && the row was deleted by another transaction - * Xmax != my-transaction)))) that has not been committed + * (Xmin is committed && the row was modified by a committed transaction, and + * (Xmax is null || the row has not been deleted, or + * (Xmax == my-transaction && the row is being deleted by this command, or + * Cmax == my-command) || + * (Xmax is not committed && the row was deleted by another transaction + * Xmax != my-transaction)))) that has not been committed * * XXX - * CommandId stuff didn't work properly if one used SQL-functions in - * UPDATE/INSERT(fromSELECT)/DELETE scans: SQL-funcs call - * CommandCounterIncrement and made tuples changed/inserted by - * current command visible to command itself (so we had multiple - * update of updated tuples, etc). - vadim 08/29/97 - * - * mao says 17 march 1993: the tests in this routine are correct; - * if you think they're not, you're wrong, and you should think - * about it again. i know, it happened to me. we don't need to - * check commit time against the start time of this transaction - * because 2ph locking protects us from doing the wrong thing. - * if you mess around here, you'll break serializability. the only - * problem with this code is that it does the wrong thing for system - * catalog updates, because the catalogs aren't subject to 2ph, so - * the serializability guarantees we provide don't extend to xacts - * that do catalog accesses. this is unfortunate, but not critical. + * CommandId stuff didn't work properly if one used SQL-functions in + * UPDATE/INSERT(fromSELECT)/DELETE scans: SQL-funcs call + * CommandCounterIncrement and made tuples changed/inserted by + * current command visible to command itself (so we had multiple + * update of updated tuples, etc). - vadim 08/29/97 + * + * mao says 17 march 1993: the tests in this routine are correct; + * if you think they're not, you're wrong, and you should think + * about it again. i know, it happened to me. we don't need to + * check commit time against the start time of this transaction + * because 2ph locking protects us from doing the wrong thing. + * if you mess around here, you'll break serializability. the only + * problem with this code is that it does the wrong thing for system + * catalog updates, because the catalogs aren't subject to 2ph, so + * the serializability guarantees we provide don't extend to xacts + * that do catalog accesses. this is unfortunate, but not critical. */ -static bool +static bool HeapTupleSatisfiesNow(HeapTuple tuple) { - if (AMI_OVERRIDE) - return true; - /* - * If the transaction system isn't yet initialized, then we assume - * that transactions committed. We only look at system catalogs - * during startup, so this is less awful than it seems, but it's - * still pretty awful. - */ - - if (!PostgresIsInitialized) - return ((bool)(TransactionIdIsValid((TransactionId)tuple->t_xmin) && - !TransactionIdIsValid((TransactionId)tuple->t_xmax))); - - /* - * XXX Several evil casts are made in this routine. Casting XID to be - * TransactionId works only because TransactionId->data is the first - * (and only) field of the structure. - */ - if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) - && CommandIdGEScanCommandId(tuple->t_cmin)) { - - return (false); - } - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) - && !CommandIdGEScanCommandId(tuple->t_cmin)) { - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { - return (true); - } - - Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); - - if (CommandIdGEScanCommandId(tuple->t_cmax)) { - return (true); - } - } - + if (AMI_OVERRIDE) + return true; + /* - * this call is VERY expensive - requires a log table lookup. + * If the transaction system isn't yet initialized, then we assume + * that transactions committed. We only look at system catalogs + * during startup, so this is less awful than it seems, but it's still + * pretty awful. */ - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { - return (false); - } - /* - * the transaction has been committed--store the commit time _now_ - * instead of waiting for a vacuum so we avoid the expensive call - * next time. + if (!PostgresIsInitialized) + return ((bool) (TransactionIdIsValid((TransactionId) tuple->t_xmin) && + !TransactionIdIsValid((TransactionId) tuple->t_xmax))); + + /* + * XXX Several evil casts are made in this routine. Casting XID to be + * TransactionId works only because TransactionId->data is the first + * (and only) field of the structure. */ - tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); - } - - /* by here, the inserting transaction has committed */ - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { - return (true); - } - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) { - return (false); - } + if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) + { + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) + && CommandIdGEScanCommandId(tuple->t_cmin)) + { + + return (false); + } + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) + && !CommandIdGEScanCommandId(tuple->t_cmin)) + { + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } + + Assert(TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax)); + + if (CommandIdGEScanCommandId(tuple->t_cmax)) + { + return (true); + } + } + + /* + * this call is VERY expensive - requires a log table lookup. + */ + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin)) + { + return (false); + } + + /* + * the transaction has been committed--store the commit time _now_ + * instead of waiting for a vacuum so we avoid the expensive call + * next time. + */ + tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); + } - if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) { - return (false); - } + /* by here, the inserting transaction has committed */ + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { - return (true); - } + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax)) + { + return (false); + } + + if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) + { + return (false); + } - /* xmax transaction committed, but no tmax set. so set it. */ - tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax)) + { + return (true); + } + + /* xmax transaction committed, but no tmax set. so set it. */ + tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); - return (false); + return (false); } /* * HeapTupleSatisfiesSnapshotInternalTimeQual -- - * True iff heap tuple is valid at the snapshot time qualification. + * True iff heap tuple is valid at the snapshot time qualification. * * Note: - * Assumes heap tuple is valid. - * Assumes internal time qualification is valid snapshot qualification. + * Assumes heap tuple is valid. + * Assumes internal time qualification is valid snapshot qualification. */ /* * The satisfaction of Rel[T] requires the following: * * (Xmin is committed && Tmin <= T && - * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) || - * Tmax >= T)) + * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) || + * Tmax >= T)) */ -static bool +static bool HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual) + InternalTimeQual qual) { - /* - * XXX Several evil casts are made in this routine. Casting XID to be - * TransactionId works only because TransactionId->data is the first - * (and only) field of the structure. - */ - if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { - return (false); - } - - tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); - } - - if (AbsoluteTimeIsBefore(TimeQualGetSnapshotTime((TimeQual)qual), tuple->t_tmin)) { - return (false); - } - /* the tuple was inserted validly before the snapshot time */ - - if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) { - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax) || - !TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { - - return (true); - } - - tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); - } - - return ((bool) - AbsoluteTimeIsAfter(tuple->t_tmax, - TimeQualGetSnapshotTime((TimeQual)qual))); + + /* + * XXX Several evil casts are made in this routine. Casting XID to be + * TransactionId works only because TransactionId->data is the first + * (and only) field of the structure. + */ + if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) + { + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin)) + { + return (false); + } + + tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); + } + + if (AbsoluteTimeIsBefore(TimeQualGetSnapshotTime((TimeQual) qual), tuple->t_tmin)) + { + return (false); + } + /* the tuple was inserted validly before the snapshot time */ + + if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) + { + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax) || + !TransactionIdDidCommit((TransactionId) tuple->t_xmax)) + { + + return (true); + } + + tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + } + + return ((bool) + AbsoluteTimeIsAfter(tuple->t_tmax, + TimeQualGetSnapshotTime((TimeQual) qual))); } /* * HeapTupleSatisfiesUpperBoundedInternalTimeQual -- - * True iff heap tuple is valid within a upper bounded time qualification. + * True iff heap tuple is valid within a upper bounded time qualification. * * Note: - * Assumes heap tuple is valid. - * Assumes time qualification is valid ranged qualification with fixed - * upper bound. + * Assumes heap tuple is valid. + * Assumes time qualification is valid ranged qualification with fixed + * upper bound. */ /* * The satisfaction of [T1,T2] requires the following: * * (Xmin is committed && Tmin <= T2 && - * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) || - * T1 is null || Tmax >= T1)) + * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) || + * T1 is null || Tmax >= T1)) */ -static bool +static bool HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual) + InternalTimeQual qual) { - /* - * XXX Several evil casts are made in this routine. Casting XID to be - * TransactionId works only because TransactionId->data is the first - * (and only) field of the structure. - */ - if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { - return (false); - } - - tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); - } - - if (AbsoluteTimeIsBefore(TimeQualGetEndTime((TimeQual)qual), tuple->t_tmin)) { - return (false); - } - /* the tuple was inserted validly before the range end */ - - if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual)qual))) { - return (true); - } - - if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) { - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax) || - !TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { - - return (true); - } - - tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); - } - - return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax, - TimeQualGetStartTime((TimeQual)qual))); + + /* + * XXX Several evil casts are made in this routine. Casting XID to be + * TransactionId works only because TransactionId->data is the first + * (and only) field of the structure. + */ + if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) + { + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin)) + { + return (false); + } + + tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); + } + + if (AbsoluteTimeIsBefore(TimeQualGetEndTime((TimeQual) qual), tuple->t_tmin)) + { + return (false); + } + /* the tuple was inserted validly before the range end */ + + if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual) qual))) + { + return (true); + } + + if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) + { + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax) || + !TransactionIdDidCommit((TransactionId) tuple->t_xmax)) + { + + return (true); + } + + tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + } + + return ((bool) AbsoluteTimeIsAfter(tuple->t_tmax, + TimeQualGetStartTime((TimeQual) qual))); } /* * HeapTupleSatisfiesUpperUnboundedInternalTimeQual -- - * True iff heap tuple is valid within a upper bounded time qualification. + * True iff heap tuple is valid within a upper bounded time qualification. * * Note: - * Assumes heap tuple is valid. - * Assumes time qualification is valid ranged qualification with no - * upper bound. + * Assumes heap tuple is valid. + * Assumes time qualification is valid ranged qualification with no + * upper bound. */ /* * The satisfaction of [T1,] requires the following: * * ((Xmin == my-transaction && Cmin != my-command && - * (Xmax is null || (Xmax == my-transaction && Cmax != my-command))) + * (Xmax is null || (Xmax == my-transaction && Cmax != my-command))) * || * * (Xmin is committed && - * (Xmax is null || (Xmax == my-transaction && Cmax == my-command) || - * (Xmax is not committed && Xmax != my-transaction) || - * T1 is null || Tmax >= T1))) + * (Xmax is null || (Xmax == my-transaction && Cmax == my-command) || + * (Xmax is not committed && Xmax != my-transaction) || + * T1 is null || Tmax >= T1))) */ -static bool +static bool HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple, - InternalTimeQual qual) + InternalTimeQual qual) { - if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && - CommandIdGEScanCommandId(tuple->t_cmin)) { - - return (false); - } - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && - !CommandIdGEScanCommandId(tuple->t_cmin)) { - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { + if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) + { + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) && + CommandIdGEScanCommandId(tuple->t_cmin)) + { + + return (false); + } + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) && + !CommandIdGEScanCommandId(tuple->t_cmin)) + { + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } + + Assert(TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax)); + + return ((bool) ! CommandIdGEScanCommandId(tuple->t_cmax)); + } + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin)) + { + return (false); + } + + tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); + } + /* the tuple was inserted validly */ + + if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual) qual))) + { return (true); - } - - Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); - - return ((bool) !CommandIdGEScanCommandId(tuple->t_cmax)); - } - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { - return (false); - } - - tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); - } - /* the tuple was inserted validly */ - - if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual)qual))) { - return (true); - } - - if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) { - - if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { - return (true); - } - - if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) { - return (CommandIdGEScanCommandId(tuple->t_cmin)); - /* it looks like error ^^^^ */ - } - - if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { - return (true); - } - - tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); - } - - return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax, - TimeQualGetStartTime((TimeQual)qual))); + } + + if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) + { + + if (!TransactionIdIsValid((TransactionId) tuple->t_xmax)) + { + return (true); + } + + if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax)) + { + return (CommandIdGEScanCommandId(tuple->t_cmin)); + /* it looks like error ^^^^ */ + } + + if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax)) + { + return (true); + } + + tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); + } + + return ((bool) AbsoluteTimeIsAfter(tuple->t_tmax, + TimeQualGetStartTime((TimeQual) qual))); } |