diff options
Diffstat (limited to 'src/backend/utils/time/tqual.c')
-rw-r--r-- | src/backend/utils/time/tqual.c | 161 |
1 files changed, 160 insertions, 1 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index f53fdd72720..b1c4bcae9c5 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.21 1998/12/15 12:46:40 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.22 1998/12/16 11:53:55 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -29,6 +29,9 @@ extern bool PostgresIsInitialized; SnapshotData SnapshotDirtyData; Snapshot SnapshotDirty = &SnapshotDirtyData; +Snapshot QuerySnapshot = NULL; +static Snapshot SerializedSnapshot = NULL; + /* * XXX Transaction system override hacks start here */ @@ -436,3 +439,159 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) return false; /* updated by other */ } + +bool +HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) +{ + if (AMI_OVERRIDE) + return true; + + if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)) + { + if (tuple->t_infomask & HEAP_XMIN_INVALID) /* xid invalid or + * aborted */ + return false; + + if (TransactionIdIsCurrentTransactionId(tuple->t_xmin)) + { + if (CommandIdGEScanCommandId(tuple->t_cmin)) + return false; /* inserted after scan started */ + + if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ + return true; + + Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax)); + + if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE) + return true; + + if (CommandIdGEScanCommandId(tuple->t_cmax)) + return true; /* deleted after scan started */ + else + return false; /* deleted before scan started */ + } + + /* + * this call is VERY expensive - requires a log table lookup. + */ + + if (!TransactionIdDidCommit(tuple->t_xmin)) + { + if (TransactionIdDidAbort(tuple->t_xmin)) + tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ + return false; + } + + tuple->t_infomask |= HEAP_XMIN_COMMITTED; + } + + /* + * By here, the inserting transaction has committed - + * have to check when... + */ + + if (tuple->t_xmin >= snapshot->xmax) + return false; + if (tuple->t_xmin >= snapshot->xmin) + { + uint32 i; + + for (i = 0; i < snapshot->xcnt; i++) + { + if (tuple->t_xmin == snapshot->xip[i]) + return false; + } + } + + if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */ + return true; + + if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE) + return true; + + if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED)) + { + if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) + { + if (CommandIdGEScanCommandId(tuple->t_cmax)) + return true; /* deleted after scan started */ + else + return false; /* deleted before scan started */ + } + + if (!TransactionIdDidCommit(tuple->t_xmax)) + { + if (TransactionIdDidAbort(tuple->t_xmax)) + tuple->t_infomask |= HEAP_XMAX_INVALID; /* aborted */ + return true; + } + + /* xmax transaction committed */ + tuple->t_infomask |= HEAP_XMAX_COMMITTED; + } + + if (tuple->t_xmax >= snapshot->xmax) + return true; + if (tuple->t_xmax >= snapshot->xmin) + { + uint32 i; + + for (i = 0; i < snapshot->xcnt; i++) + { + if (tuple->t_xmax == snapshot->xip[i]) + return true; + } + } + + return false; +} + +void +SetQuerySnapshot(void) +{ + + /* 1st call in xaction */ + if (SerializedSnapshot == NULL) + { + SerializedSnapshot = GetSnapshotData(); + QuerySnapshot = SerializedSnapshot; + Assert(QuerySnapshot != NULL); + return; + } + + if (QuerySnapshot != SerializedSnapshot) + { + free(QuerySnapshot->xip); + free(QuerySnapshot); + } + + if (XactIsoLevel == XACT_SERIALIZED) + QuerySnapshot = SerializedSnapshot; + else + QuerySnapshot = GetSnapshotData(); + + Assert(QuerySnapshot != NULL); + +} + +void +FreeXactSnapshot(void) +{ + + if (QuerySnapshot != NULL && QuerySnapshot != SerializedSnapshot) + { + free(QuerySnapshot->xip); + free(QuerySnapshot); + } + + QuerySnapshot = NULL; + + if (SerializedSnapshot != NULL) + { + free(SerializedSnapshot->xip); + free(SerializedSnapshot); + } + + SerializedSnapshot = NULL; + +} |