head 1.24; access; symbols release_4_2:1.24 aix_ok:1.22 Version_2_1:1.7 C_Demo_1:1.5; locks; strict; comment @ * @; 1.24 date 93.11.03.08.24.31; author aoki; state Exp; branches; next 1.23; 1.23 date 93.10.26.21.51.55; author paxson; state Exp; branches; next 1.22; 1.22 date 93.09.01.01.21.01; author avi; state Exp; branches; next 1.21; 1.21 date 93.07.16.18.57.40; author avi; state Exp; branches; next 1.20; 1.20 date 93.07.06.18.18.04; author avi; state Exp; branches; next 1.19; 1.19 date 93.07.01.22.50.17; author avi; state Exp; branches; next 1.18; 1.18 date 93.03.23.00.49.47; author mao; state Exp; branches; next 1.17; 1.17 date 92.08.07.00.43.55; author mao; state Exp; branches; next 1.16; 1.16 date 92.08.03.21.00.52; author mer; state Exp; branches; next 1.15; 1.15 date 92.08.03.17.42.52; author mao; state Exp; branches; next 1.14; 1.14 date 92.05.28.21.16.36; author mer; state Exp; branches; next 1.13; 1.13 date 92.02.19.01.51.53; author mer; state Exp; branches; next 1.12; 1.12 date 91.11.12.20.20.29; author mer; state Exp; branches; next 1.11; 1.11 date 91.10.04.12.51.05; author hong; state Exp; branches; next 1.10; 1.10 date 91.06.04.17.18.31; author mao; state Exp; branches; next 1.9; 1.9 date 91.06.03.21.41.34; author kemnitz; state Exp; branches; next 1.8; 1.8 date 91.03.17.16.24.53; author sp; state Exp; branches; next 1.7; 1.7 date 90.09.25.16.54.12; author kemnitz; state Exp; branches; next 1.6; 1.6 date 90.05.15.13.05.03; author mao; state Exp; branches; next 1.5; 1.5 date 89.09.05.17.29.51; author mao; state C_Demo_1; branches; next 1.4; 1.4 date 89.07.19.09.24.14; author hirohama; state Exp; branches; next 1.3; 1.3 date 89.03.08.15.36.22; author goh; state Stab; branches; next 1.2; 1.2 date 89.02.13.18.07.53; author hirohama; state Exp; branches; next 1.1; 1.1 date 89.01.17.05.59.07; author cimarron; state Exp; branches; next ; desc @@ 1.24 log @fix broken prs2 protos remove rules/rlock.h, access/xcxt.h, access/newam.h (dead headers with residual dependencies) @ text @/* ---------------------------------------------------------------- * FILE * tqual.c * * DESCRIPTION * POSTGRES time qualification code. * * NOTES * * IDENTIFICATION * $Header$ * ---------------------------------------------------------------- */ /* #define TQUALDEBUG 1 */ #include "tmp/postgres.h" RcsId("$Header: /faerie/aoki/postgres/src/backend/utils/time/RCS/tqual.c,v 1.23 1993/10/26 21:51:55 paxson Exp aoki $"); #include "access/htup.h" #include "access/xlog.h" #include "access/xact.h" #include "access/transam.h" #include "utils/log.h" #include "utils/nabstime.h" #include "access/tqual.h" /* * TimeQualMode -- * Mode indicator for treatment of time qualifications. */ typedef uint16 TimeQualMode; #define TimeQualAt 0x1 #define TimeQualNewer 0x2 #define TimeQualOlder 0x4 #define TimeQualAll 0x8 #define TimeQualMask 0xf #define TimeQualEvery 0x0 #define TimeQualRange (TimeQualNewer | TimeQualOlder) #define TimeQualAllAt (TimeQualAt | TimeQualAll) typedef struct TimeQualData { AbsoluteTime start; AbsoluteTime end; TimeQualMode mode; } TimeQualData; typedef TimeQualData *InternalTimeQual; static TimeQualData SelfTimeQualData; TimeQual SelfTimeQual = (Pointer)&SelfTimeQualData; extern bool PostgresIsInitialized; /* * XXX Transaction system override hacks start here */ #ifndef GOODAMI static TransactionId HeapSpecialTransactionId = InvalidTransactionId; static CommandId HeapSpecialCommandId = FirstCommandId; void setheapoverride(on) bool on; { 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); } #endif /* !defined(GOODAMI) */ /* * XXX Transaction system override hacks end here */ /* * HeapTupleSatisfiesItself -- * True iff heap tuple is valid for "itself." * * Note: * Assumes heap tuple is valid. */ static bool HeapTupleSatisfiesItself ARGS(( HeapTuple tuple )); /* * HeapTupleSatisfiesNow -- * True iff heap tuple is valid "now." * * Note: * Assumes heap tuple is valid. */ static bool HeapTupleSatisfiesNow ARGS(( HeapTuple tuple )); /* * HeapTupleSatisfiesSnapshotInternalTimeQual -- * 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. */ static bool HeapTupleSatisfiesSnapshotInternalTimeQual ARGS(( HeapTuple tuple, InternalTimeQual qual )); /* * HeapTupleSatisfiesUpperBoundedInternalTimeQual -- * 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. */ static bool HeapTupleSatisfiesUpperBoundedInternalTimeQual ARGS(( HeapTuple tuple, InternalTimeQual qual )); /* * HeapTupleSatisfiesUpperUnboundedInternalTimeQual -- * 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. */ static bool HeapTupleSatisfiesUpperUnboundedInternalTimeQual ARGS(( HeapTuple tuple, InternalTimeQual qual )); bool TimeQualIsValid(qual) TimeQual qual; { bool hasStartTime; if (!PointerIsValid(qual) || qual == SelfTimeQual) { return (true); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (true); } #endif /* !defined(GOODAMI) */ 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); } bool TimeQualIsLegal(qual) TimeQual qual; { Assert(TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (true); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (true); } #endif /* !defined(GOODAMI) */ /* 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); } bool TimeQualIncludesNow(qual) TimeQual qual; { Assert(TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (true); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (false); } #endif /* !defined(GOODAMI) */ if (((InternalTimeQual)qual)->mode & TimeQualAt) { return (false); } if (((InternalTimeQual)qual)->mode & TimeQualOlder && !AbsoluteTimeIsAfter( ((InternalTimeQual)qual)->end, GetCurrentTransactionStartTime())) { return (false); } return (true); } bool TimeQualIncludesPast(qual) TimeQual qual; { Assert(TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (false); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (false); } #endif /* !defined(GOODAMI) */ /* otherwise, must check archive (setting locks as appropriate) */ return (true); } bool TimeQualIsSnapshot(qual) TimeQual qual; { Assert(TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (false); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (false); } #endif /* !defined(GOODAMI) */ return ((bool)!!(((InternalTimeQual)qual)->mode & TimeQualAt)); } bool TimeQualIsRanged(qual) TimeQual qual; { Assert(TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (false); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (false); } #endif /* !defined(GOODAMI) */ return ((bool)!(((InternalTimeQual)qual)->mode & TimeQualAt)); } bool TimeQualIndicatesDisableValidityChecking(qual) TimeQual qual; { Assert (TimeQualIsValid(qual)); if (qual == NowTimeQual || qual == SelfTimeQual) { return (false); } #ifndef GOODAMI if (qual == LispSelfTimeQual) { return (false); } #endif /* !defined(GOODAMI) */ if (((InternalTimeQual)qual)->mode & TimeQualAll) { return (true); } return (false); } AbsoluteTime TimeQualGetSnapshotTime(qual) TimeQual qual; { Assert(TimeQualIsSnapshot(qual)); return (((InternalTimeQual)qual)->start); } AbsoluteTime TimeQualGetStartTime(qual) TimeQual qual; { Assert(TimeQualIsRanged(qual)); return (((InternalTimeQual)qual)->start); } AbsoluteTime TimeQualGetEndTime(qual) TimeQual qual; { Assert(TimeQualIsRanged(qual)); return (((InternalTimeQual)qual)->end); } TimeQual TimeFormSnapshotTimeQual(time) AbsoluteTime time; { InternalTimeQual qual; Assert(AbsoluteTimeIsBackwardCompatiblyValid(time)); qual = LintCast(InternalTimeQual, palloc(sizeof *qual)); qual->start = time; qual->end = INVALID_ABSTIME; qual->mode = TimeQualAt; return ((TimeQual)qual); } TimeQual TimeFormRangedTimeQual(startTime, endTime) AbsoluteTime startTime; AbsoluteTime endTime; { InternalTimeQual qual; qual = LintCast(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); } #if 0 TimeQual TimeFormDebuggingTimeQual(time) AbsoluteTime time; { InternalTimeQual qual; Assert(AbsoluteTimeIsBackwardCompatiblyValid(time)); qual = LintCast(InternalTimeQual, palloc(sizeof *qual)); qual->start = time; qual->mode = TimeQualAllAt; return ((TimeQual)qual); } #endif 0 /* * Note: * 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(tuple, qual) 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() #ifndef GOODAMI || qual == LispSelfTimeQual #endif /* !defined(GOODAMI) */ ) { 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)); } /* * The satisfaction of "itself" requires the following: * * ((Xmin == my-transaction && (Xmax is null [|| Xmax != my-transaction)]) * || * * (Xmin is committed && * (Xmax is null || (Xmax != my-transaction && Xmax is not committed))) */ static bool HeapTupleSatisfiesItself(tuple) 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); } } /* 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); } return ((bool)!TransactionIdDidCommit((TransactionId)tuple->t_xmax)); } /* * The satisfaction of "now" requires the following: * * ((Xmin == my-transaction && Cmin != 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)))) * * 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 HeapTupleSatisfiesNow(tuple) HeapTuple tuple; { AbsoluteTime curtime; 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) && CommandIdIsCurrentCommandId(tuple->t_cmin)) { return (false); } if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && !CommandIdIsCurrentCommandId(tuple->t_cmin)) { if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { return (true); } Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); if (CommandIdIsCurrentCommandId(tuple->t_cmax)) { return (true); } } /* * this call is VERY expensive - requires a log table lookup. */ if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { return (false); } } /* by here, the inserting transaction has committed */ 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 */ return (false); } /* * 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)) */ static bool HeapTupleSatisfiesSnapshotInternalTimeQual(tuple, qual) HeapTuple tuple; 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))); } /* * 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)) */ static bool HeapTupleSatisfiesUpperBoundedInternalTimeQual(tuple, qual) HeapTuple tuple; 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))); } /* * The satisfaction of [T1,] requires the following: * * ((Xmin == my-transaction && Cmin != 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))) */ static bool HeapTupleSatisfiesUpperUnboundedInternalTimeQual(tuple, qual) HeapTuple tuple; InternalTimeQual qual; { if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && CommandIdIsCurrentCommandId(tuple->t_cmin)) { return (false); } if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && !CommandIdIsCurrentCommandId(tuple->t_cmin)) { if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { return (true); } Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); return ((bool) !CommandIdIsCurrentCommandId(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 (CommandIdIsCurrentCommandId(tuple->t_cmin)); } if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { return (true); } tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); } return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax, TimeQualGetStartTime((TimeQual)qual))); } @ 1.23 log @added Paul's change for bootstrapping system catalogs: if Postgres isn't initialized, assume the xact committed. @ text @d1 5 a5 2 /* * tqual.c -- d7 6 d19 2 a21 1 #include "access/xcxt.h" a28 2 RcsId("$Header: /faerie/aoki/postgres/src/backend/utils/time/RCS/tqual.c,v 1.22 1993/09/01 01:21:01 avi Exp aoki $"); @ 1.22 log @backward compatible time checking @ text @d20 1 a20 1 RcsId("$Header: /private/src/postgres/src/backend/utils/time/RCS/tqual.c,v 1.21 1993/07/16 18:57:40 avi Exp avi $"); d478 2 d483 3 @ 1.21 log @time cleanup @ text @d20 1 a20 1 RcsId("$Header: /usr/local/devel/postgres/src/backend/utils/time/RCS/tqual.c,v 1.20 1993/07/06 18:18:04 avi Exp avi $"); d190 1 a190 1 return (AbsoluteTimeIsValid(((InternalTimeQual)qual)->start)); d196 1 a196 1 if (!AbsoluteTimeIsValid(((InternalTimeQual)qual)->start)) { d203 1 a203 1 if (!AbsoluteTimeIsValid(((InternalTimeQual)qual)->end)) { d416 1 a416 1 Assert(AbsoluteTimeIsValid(time)); d440 1 a440 1 if (AbsoluteTimeIsValid(startTime)) { d443 1 a443 1 if (AbsoluteTimeIsValid(endTime)) { d457 1 a457 1 Assert(AbsoluteTimeIsValid(time)); d534 1 a534 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d546 1 a546 1 if (AbsoluteTimeIsReal(tuple->t_tmax)) { d608 1 a608 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d674 1 a674 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d688 1 a688 1 if (!AbsoluteTimeIsReal(tuple->t_tmax)) { d722 1 a722 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d736 1 a736 1 if (!AbsoluteTimeIsValid(TimeQualGetStartTime((TimeQual)qual))) { d740 1 a740 1 if (!AbsoluteTimeIsReal(tuple->t_tmax)) { d773 1 a773 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d801 1 a801 1 if (!AbsoluteTimeIsValid(TimeQualGetStartTime((TimeQual)qual))) { d805 1 a805 1 if (!AbsoluteTimeIsReal(tuple->t_tmax)) { @ 1.20 log @replaced TimeIsBefore with AbsoluteTimeIsBefore @ text @d20 1 a20 1 RcsId("$Header: /private/src/postgres/src/backend/utils/time/RCS/tqual.c,v 1.19 1993/07/01 22:50:17 avi Exp avi $"); d203 1 a203 1 if (!TimeIsValid(((InternalTimeQual)qual)->end)) { d383 1 a383 1 Time d392 1 a392 1 Time d401 1 a401 1 Time d416 1 a416 1 Assert(TimeIsValid(time)); d440 1 a440 1 if (TimeIsValid(startTime)) { d443 1 a443 1 if (TimeIsValid(endTime)) { d453 1 a453 1 Time time; d457 1 a457 1 Assert(TimeIsValid(time)); @ 1.19 log @got rid of InvalidAbsoluteTime @ text @d20 1 a20 1 RcsId("$Header: /private/src/postgres/src/backend/utils/time/RCS/tqual.c,v 1.18 1993/03/23 00:49:47 mao Exp avi $"); d207 1 a207 1 return ((bool)!TimeIsBefore( d683 1 a683 1 if (TimeIsBefore(TimeQualGetSnapshotTime((TimeQual)qual), tuple->t_tmin)) { d731 1 a731 1 if (TimeIsBefore(TimeQualGetEndTime((TimeQual)qual), tuple->t_tmin)) { @ 1.18 log @the change i made in 1.15 was wrong. it introduced a serializability error on user tables that was pretty awful (and was discovered by the folks at miro). i reverted to the previous behavior. accesses to system catalogs are not guaranteed to be serializable, but user data accesses are. @ text @d20 1 a20 1 RcsId("$Header: /private/src/postgres/src/backend/utils/time/RCS/tqual.c,v 1.17 1992/08/07 00:43:55 mao Exp mao $"); d421 1 a421 1 qual->end = InvalidAbsoluteTime; @ 1.17 log @get rid of a spurious elog(NOTICE, ...) @ text @d20 1 a20 1 RcsId("$Header: /private/mao/postgres/src/utils/time/RCS/tqual.c,v 1.16 1992/08/03 21:00:52 mer Exp mao $"); d571 11 a636 16 tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); } curtime = GetCurrentTransactionStartTime(); if (AbsoluteTimeIsAfter(tuple->t_tmin, curtime)) { return (false); } /* we can see the insert */ if (AbsoluteTimeIsReal(tuple->t_tmax)) { if (AbsoluteTimeIsAfter(tuple->t_tmax, curtime)) return (true); return (false); d639 1 d652 1 a652 5 tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); if (AbsoluteTimeIsAfter(tuple->t_tmax, curtime)) return (true); @ 1.16 log @all tuples satisfy the "NOW" time qual when AMI_OVERRIDE is set @ text @d20 1 a20 1 RcsId("$Header: /private/mer/pg/src/utils/time/RCS/tqual.c,v 1.15 1992/08/03 17:42:52 mao Exp mer $"); a632 2 elog(NOTICE, "cur xact start %ld tup commit %ld", curtime, tuple->t_tmin); @ 1.15 log @HeapTupleSatisfiesNow fixed -- considers commit time, not just commit state, of transactions when computing visibility. sort of surprising we never noticed this bug before. @ text @d14 1 d20 1 a20 1 RcsId("$Header: /private/mao/postgres/src/utils/time/RCS/tqual.c,v 1.14 1992/05/28 21:16:36 mer Exp mao $"); d579 2 @ 1.14 log @TransactionIdData type no longer exists, xids are longs - remove casts @ text @d19 1 a19 1 RcsId("$Header: /private/mer/pg.latest/src/utils/time/RCS/tqual.c,v 1.13 1992/02/19 01:51:53 mer Exp mer $"); d49 2 d576 13 d596 2 a597 5 #ifndef ELOGTIME /* XXX this should be removable with anything breaking */ /* system bootstrapping might break without this */ if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && CommandIdIsCurrentCommandId(tuple->t_cmin)) { a600 1 #endif /* !defined(ELOGTIME) */ d602 2 a603 2 if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && !CommandIdIsCurrentCommandId(tuple->t_cmin)) { d623 10 a633 1 /* the tuple was inserted validly */ d635 1 d637 4 a640 1 return (false); d644 1 a644 1 return (true); d648 5 a652 1 return (false); d655 6 a660 1 return ((bool)!TransactionIdDidCommit((TransactionId)tuple->t_xmax)); a781 3 #ifndef ELOGTIME /* XXX this should be removable with anything breaking */ /* system bootstrapping might break without this */ a786 1 #endif /* !defined(ELOGTIME) */ @ 1.13 log @changes for the new abstime implementation @ text @d19 1 a19 1 RcsId("$Header: /u/mer/pg/src/utils/time/RCS/tqual.c,v 1.12 1991/11/12 20:20:29 mer Exp mer $"); a53 2 static TransactionIdData HeapSpecialTransactionIdData; a61 1 HeapSpecialTransactionId = &HeapSpecialTransactionIdData; d63 1 a63 1 (Pointer)HeapSpecialTransactionId); @ 1.12 log @prototyping changes @ text @d15 1 d19 1 a19 1 RcsId("$Header: /users/mer/postgres/src/utils/time/RCS/tqual.c,v 1.11 1991/10/04 12:51:05 hong Exp mer $"); d546 1 a546 1 if (AbsoluteTimeIsValid(tuple->t_tmax)) { d618 1 a618 1 if (AbsoluteTimeIsValid(tuple->t_tmax)) { d665 1 a665 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { d717 1 a717 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { d786 1 a786 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { @ 1.11 log @if a tuple was deleted by the current transaction, then it is always invisible to the current xact. fix to HeapTupleSatisfiesNow. @ text @d13 1 d18 1 a18 1 RcsId("$Header: RCS/tqual.c,v 1.10 91/06/04 17:18:31 mao Exp $"); d449 1 a449 1 /* This does not make any sense d465 1 a465 1 */ d528 8 a535 3 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { if (TransactionIdIsCurrentTransactionId(tuple->t_xmin) && !TransactionIdIsValid(tuple->t_xmax)) { d537 1 a537 1 } d539 1 a539 1 if (!TransactionIdDidCommit(tuple->t_xmin)) { a540 1 } d542 2 a543 1 /* the tuple was inserted validly */ d545 3 a547 3 if (AbsoluteTimeIsValid(tuple->t_tmax)) { return (false); } d549 3 a551 3 if (!TransactionIdIsValid(tuple->t_xmax)) { return (true); } d553 3 a555 3 if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) { return (false); } d557 1 a557 1 return ((bool)!TransactionIdDidCommit(tuple->t_xmax)); d576 6 a581 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d584 7 a590 6 /* XXX this should be removable with anything breaking */ /* system bootstrapping might break without this */ if (TransactionIdIsCurrentTransactionId(tuple->t_xmin) && CommandIdIsCurrentCommandId(tuple->t_cmin)) { return (false); } d593 8 a600 2 if (TransactionIdIsCurrentTransactionId(tuple->t_xmin) && !CommandIdIsCurrentCommandId(tuple->t_cmin)) { d602 4 a605 10 if (!TransactionIdIsValid(tuple->t_xmax)) { return (true); } Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax)); if (CommandIdIsCurrentCommandId(tuple->t_cmax)) { return (true); } } d607 3 a609 3 /* * this call is VERY expensive - requires a log table lookup. */ d611 2 a612 3 if (!TransactionIdDidCommit(tuple->t_xmin)) { return (false); } d614 2 a615 1 /* the tuple was inserted validly */ d617 1 a617 1 if (AbsoluteTimeIsValid(tuple->t_tmax)) { d619 1 a619 1 } d621 1 a621 1 if (!TransactionIdIsValid(tuple->t_xmax)) { d623 1 a623 1 } d625 1 a625 1 if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) { d627 1 a627 1 } d629 1 a629 1 return ((bool)!TransactionIdDidCommit(tuple->t_xmax)); d645 6 a650 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d652 2 a653 5 if (!TransactionIdDidCommit(tuple->t_xmin)) { return (false); } tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); d656 2 a657 4 if (TimeIsBefore(TimeQualGetSnapshotTime(qual), tuple->t_tmin)) { return (false); } /* the tuple was inserted validly before the snapshot time */ d659 4 a662 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { d664 1 a664 2 if (!TransactionIdIsValid(tuple->t_xmax) || !TransactionIdDidCommit(tuple->t_xmax)) { d666 2 a667 2 return (true); } d669 1 a669 1 tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); d672 6 a677 3 return ((bool) AbsoluteTimeIsAfter(tuple->t_tmax, TimeQualGetSnapshotTime(qual))); d693 6 a698 5 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { if (!TransactionIdDidCommit(tuple->t_xmin)) { return (false); } d700 2 a701 1 tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); d704 2 a705 4 if (TimeIsBefore(TimeQualGetEndTime(qual), tuple->t_tmin)) { return (false); } /* the tuple was inserted validly before the range end */ d707 4 a710 3 if (!AbsoluteTimeIsValid(TimeQualGetStartTime(qual))) { return (true); } d712 3 a714 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { d716 1 a716 2 if (!TransactionIdIsValid(tuple->t_xmax) || !TransactionIdDidCommit(tuple->t_xmax)) { d718 2 a719 2 return (true); } d721 1 a721 1 tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); d724 5 a728 2 return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax, TimeQualGetStartTime(qual))); d749 1 a749 1 if (!AbsoluteTimeIsValid(tuple->t_tmin)) { d752 7 a758 6 /* XXX this should be removable with anything breaking */ /* system bootstrapping might break without this */ if (TransactionIdIsCurrentTransactionId(tuple->t_xmin) && CommandIdIsCurrentCommandId(tuple->t_cmin)) { return (false); } d761 2 a762 2 if (TransactionIdIsCurrentTransactionId(tuple->t_xmin) && !CommandIdIsCurrentCommandId(tuple->t_cmin)) { d764 3 a766 3 if (!TransactionIdIsValid(tuple->t_xmax)) { return (true); } d768 1 a768 1 Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax)); d770 2 a771 7 return ((bool) !CommandIdIsCurrentCommandId(tuple->t_cmax)); } if (!TransactionIdDidCommit(tuple->t_xmin)) { return (false); } d773 2 a774 1 tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin); a775 1 /* the tuple was inserted validly */ d777 3 a779 3 if (!AbsoluteTimeIsValid(TimeQualGetStartTime(qual))) { return (true); } d781 3 a783 1 if (!AbsoluteTimeIsValid(tuple->t_tmax)) { d785 1 a785 3 if (!TransactionIdIsValid(tuple->t_xmax)) { return (true); } d787 3 a789 3 if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) { return (CommandIdIsCurrentCommandId(tuple->t_cmin)); } d791 3 a793 3 if (!TransactionIdDidCommit(tuple->t_xmax)) { return (true); } d795 2 a796 1 tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax); d799 5 a803 2 return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax, TimeQualGetStartTime(qual))); @ 1.10 log @fixed greg's fix -- can't assume that a deleting xact committed, just because it has a valid xact id. have to go to the log anyway. @ text @d17 1 a17 1 RcsId("$Header: RCS/tqual.c,v 1.9 91/06/03 21:41:34 kemnitz Exp Locker: mao $"); d614 1 a614 1 return (CommandIdIsCurrentCommandId(tuple->t_cmax)); @ 1.9 log @changed around tests in HeapTupleSatisfiesNow somewhat to avoid a log lookup unless it is absolutely necessary. @ text @d17 1 a17 1 RcsId("$Header: RCS/tqual.c,v 1.8 91/03/17 16:24:53 sp Exp Locker: kemnitz $"); a594 4 if (TransactionIdIsValid(tuple->t_xmax)) { return (false); } d596 1 a596 1 * note: this call is VERY expensive - requires a log table lookup. @ 1.8 log @Minor (?) bug fix in HeapTupleStatisfiesNow.. @ text @d17 1 a17 1 RcsId("$Header: RCS/tqual.c,v 1.7 90/09/25 16:54:12 kemnitz Exp $"); d594 8 @ 1.7 log @Updating from revision 1.6 to revision 1.8 @ text @d17 1 a17 1 RcsId("$Header: RCS/tqual.c,v 1.8 90/08/18 00:42:55 cimarron Exp $"); d610 1 a610 1 return (CommandIdIsCurrentCommandId(tuple->t_cmin)); @ 1.6 log @TimeIsBefore is now strictly before @ text @d8 1 a8 1 #include "c.h" d10 4 a13 6 #include "htup.h" #include "log.h" #include "tim.h" #include "xcxt.h" #include "xid.h" #include "xlog.h" d15 1 a15 1 #include "tqual.h" d17 1 a17 1 RcsId("$Header: RCS/tqual.c,v 1.5 89/09/05 17:29:51 mao C_Demo_1 Locker: mao $"); @ 1.5 log @Working version of C-only demo @ text @d19 1 a19 1 RcsId("$Header: /usr6/postgres/mao/postgres/src/utils/time/RCS/tqual.c,v 1.4 89/07/19 09:24:14 hirohama Exp $"); d233 9 a241 2 return (AbsoluteTimeIsBefore(((InternalTimeQual)qual)->start, GetCurrentTransactionStartTime())); d246 9 a254 2 return (AbsoluteTimeIsBefore(((InternalTimeQual)qual)->end, GetCurrentTransactionStartTime())); d259 9 a267 2 return (AbsoluteTimeIsBefore(((InternalTimeQual)qual)->start, GetCurrentTransactionStartTime())); d294 1 a294 1 AbsoluteTimeIsBefore( d657 2 a658 1 !TimeIsBefore(tuple->t_tmax, TimeQualGetSnapshotTime(qual))); d703 2 a704 1 return ((bool)!TimeIsBefore(tuple->t_tmax, TimeQualGetStartTime(qual))); d778 2 a779 1 return ((bool)!TimeIsBefore(tuple->t_tmax, TimeQualGetStartTime(qual))); @ 1.4 log @bug fixes and robustness added upper unbounded time ranges are now processed correctly @ text @d19 1 a19 1 RcsId("$Header: tqual.c,v 1.3 89/03/08 15:36:22 hirohama Locked $"); @ 1.3 log @sequent port @ text @d19 1 a19 1 RcsId("$Header: tqual.c,v 1.2 89/02/13 18:07:53 hirohama Exp $"); d400 1 d415 2 a419 1 qual->start = startTime; a422 1 qual->end = endTime; d722 2 a723 3 if (CommandIdIsCurrentCommandId(tuple->t_cmax)) { return (true); } @ 1.2 log @xfer from oldtree @ text @d19 1 a19 1 RcsId("$Header: tqual.c,v 1.1 89/01/17 05:59:07 hirohama Locked $"); d568 1 a568 2 Assert(TransactionIdIsCurrentTransactionId( tuple->t_xmax)); d719 1 a719 2 Assert(TransactionIdIsCurrentTransactionId( tuple->t_xmax)); @ 1.1 log @Initial revision @ text @a0 1 a1 26 * * POSTGRES Data Base Management System * * Copyright (c) 1988 Regents of the University of California * * Permission to use, copy, modify, and distribute this software and its * documentation for educational, research, and non-profit purposes and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of the University of California not be used in advertising * or publicity pertaining to distribution of the software without * specific, written prior permission. Permission to incorporate this * software into commercial products can be obtained from the Campus * Software Office, 295 Evans Hall, University of California, Berkeley, * Ca., 94720 provided only that the the requestor give the University * of California a free licence to any derived software for educational * and research purposes. The University of California makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /* d19 1 a19 1 RcsId("$Header: tqual.c,v 1.1 88/11/11 16:35:37 postgres Exp $"); @