aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/time/tqual.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/time/tqual.c')
-rw-r--r--src/backend/utils/time/tqual.c161
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;
+
+}