Refactor logic to deal with HEAP_MOVED tuples to a separate function.
authorHeikki Linnakangas <[email protected]>
Thu, 4 Aug 2016 08:42:04 +0000 (11:42 +0300)
committerHeikki Linnakangas <[email protected]>
Mon, 22 Aug 2016 18:21:58 +0000 (21:21 +0300)
src/backend/utils/time/tqual.c

index 26a3be3a618748f3b402bcff22179d147971238f..1aff2e9f2d1b1fa7b8e14f5b06cdc70bac8001ad 100644 (file)
@@ -81,6 +81,7 @@ SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
 
 /* local functions */
 static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
+static bool IsMovedTupleVisible(HeapTuple htup, Buffer buffer);
 
 /*
  * SetHintBits()
@@ -186,44 +187,8 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
                        return false;
 
                /* Used by pre-9.0 binary upgrades */
-               if (tuple->t_infomask & HEAP_MOVED_OFF)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return false;
-                       if (!TransactionIdIsInProgress(xvac))
-                       {
-                               if (TransactionIdDidCommit(xvac))
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
-                       }
-               }
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (!TransactionIdIsCurrentTransactionId(xvac))
-                       {
-                               if (TransactionIdIsInProgress(xvac))
-                                       return false;
-                               if (TransactionIdDidCommit(xvac))
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                               InvalidTransactionId);
-                               else
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                       }
-               }
+               if (tuple->t_infomask & HEAP_MOVED)
+                       return IsMovedTupleVisible(htup, buffer);
                else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                {
                        if (tuple->t_infomask & HEAP_XMAX_INVALID)      /* xid invalid */
@@ -377,51 +342,15 @@ HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
                        return false;
 
                /* Used by pre-9.0 binary upgrades */
-               if (tuple->t_infomask & HEAP_MOVED_OFF)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return false;
-                       if (!TransactionIdIsInProgress(xvac))
-                       {
-                               if (TransactionIdDidCommit(xvac))
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
-                       }
-               }
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (!TransactionIdIsCurrentTransactionId(xvac))
-                       {
-                               if (TransactionIdIsInProgress(xvac))
-                                       return false;
-                               if (TransactionIdDidCommit(xvac))
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                               InvalidTransactionId);
-                               else
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                       }
-               }
+               if (tuple->t_infomask & HEAP_MOVED)
+                       return IsMovedTupleVisible(htup, buffer);
 
                /*
                 * An invalid Xmin can be left behind by a speculative insertion that
                 * is canceled by super-deleting the tuple.  This also applies to
                 * TOAST tuples created during speculative insertion.
                 */
-               else if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple)))
+               if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple)))
                        return false;
        }
 
@@ -471,45 +400,15 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
                        return HeapTupleInvisible;
 
                /* Used by pre-9.0 binary upgrades */
-               if (tuple->t_infomask & HEAP_MOVED_OFF)
+               if (tuple->t_infomask & HEAP_MOVED)
                {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (TransactionIdIsCurrentTransactionId(xvac))
+                       if (IsMovedTupleVisible(htup, buffer))
+                               return HeapTupleMayBeUpdated;
+                       else
                                return HeapTupleInvisible;
-                       if (!TransactionIdIsInProgress(xvac))
-                       {
-                               if (TransactionIdDidCommit(xvac))
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return HeapTupleInvisible;
-                               }
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
-                       }
                }
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
 
-                       if (!TransactionIdIsCurrentTransactionId(xvac))
-                       {
-                               if (TransactionIdIsInProgress(xvac))
-                                       return HeapTupleInvisible;
-                               if (TransactionIdDidCommit(xvac))
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                               InvalidTransactionId);
-                               else
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return HeapTupleInvisible;
-                               }
-                       }
-               }
-               else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
+               if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                {
                        if (HeapTupleHeaderGetCmin(tuple) >= curcid)
                                return HeapTupleInvisible;              /* inserted after scan started */
@@ -753,45 +652,10 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
                        return false;
 
                /* Used by pre-9.0 binary upgrades */
-               if (tuple->t_infomask & HEAP_MOVED_OFF)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
+               if (tuple->t_infomask & HEAP_MOVED)
+                       return IsMovedTupleVisible(htup, buffer);
 
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return false;
-                       if (!TransactionIdIsInProgress(xvac))
-                       {
-                               if (TransactionIdDidCommit(xvac))
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
-                       }
-               }
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (!TransactionIdIsCurrentTransactionId(xvac))
-                       {
-                               if (TransactionIdIsInProgress(xvac))
-                                       return false;
-                               if (TransactionIdDidCommit(xvac))
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                               InvalidTransactionId);
-                               else
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                       }
-               }
-               else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
+               if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                {
                        if (tuple->t_infomask & HEAP_XMAX_INVALID)      /* xid invalid */
                                return true;
@@ -974,45 +838,10 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
                        return false;
 
                /* Used by pre-9.0 binary upgrades */
-               if (tuple->t_infomask & HEAP_MOVED_OFF)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
+               if (tuple->t_infomask & HEAP_MOVED)
+                       return IsMovedTupleVisible(htup, buffer);
 
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return false;
-                       if (!XidInMVCCSnapshot(xvac, snapshot))
-                       {
-                               if (TransactionIdDidCommit(xvac))
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
-                       }
-               }
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (!TransactionIdIsCurrentTransactionId(xvac))
-                       {
-                               if (XidInMVCCSnapshot(xvac, snapshot))
-                                       return false;
-                               if (TransactionIdDidCommit(xvac))
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                               InvalidTransactionId);
-                               else
-                               {
-                                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                               InvalidTransactionId);
-                                       return false;
-                               }
-                       }
-               }
-               else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
+               if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                {
                        if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
                                return false;   /* inserted after scan started */
@@ -1179,44 +1008,17 @@ HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
        {
                if (HeapTupleHeaderXminInvalid(tuple))
                        return HEAPTUPLE_DEAD;
-               /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_OFF)
-               {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
 
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return HEAPTUPLE_DELETE_IN_PROGRESS;
-                       if (TransactionIdIsInProgress(xvac))
-                               return HEAPTUPLE_DELETE_IN_PROGRESS;
-                       if (TransactionIdDidCommit(xvac))
-                       {
-                               SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                       InvalidTransactionId);
-                               return HEAPTUPLE_DEAD;
-                       }
-                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                               InvalidTransactionId);
-               }
                /* Used by pre-9.0 binary upgrades */
-               else if (tuple->t_infomask & HEAP_MOVED_IN)
+               if (tuple->t_infomask & HEAP_MOVED)
                {
-                       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
-
-                       if (TransactionIdIsCurrentTransactionId(xvac))
-                               return HEAPTUPLE_INSERT_IN_PROGRESS;
-                       if (TransactionIdIsInProgress(xvac))
-                               return HEAPTUPLE_INSERT_IN_PROGRESS;
-                       if (TransactionIdDidCommit(xvac))
-                               SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
-                                                       InvalidTransactionId);
+                       if (IsMovedTupleVisible(htup, buffer))
+                               return HEAPTUPLE_LIVE;
                        else
-                       {
-                               SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
-                                                       InvalidTransactionId);
                                return HEAPTUPLE_DEAD;
-                       }
                }
-               else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
+
+               if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
                {
                        if (tuple->t_infomask & HEAP_XMAX_INVALID)      /* xid invalid */
                                return HEAPTUPLE_INSERT_IN_PROGRESS;
@@ -1785,3 +1587,65 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
        else
                return true;
 }
+
+
+/*
+ * Check the visibility on a tuple with HEAP_MOVED flags set.
+ *
+ * Returns true if the tuple is visible, false otherwise. These flags are
+ * no longer used, any such tuples must've come from binary upgrade of a
+ * pre-9.0 system, so we can assume that the xid is long finished by now.
+ */
+static bool
+IsMovedTupleVisible(HeapTuple htup, Buffer buffer)
+{
+       HeapTupleHeader tuple = htup->t_data;
+       TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
+
+       /*
+        * Check that the xvac is not a live transaction. This should never
+        * happen, because HEAP_MOVED flags are not set by current code.
+        */
+       if (TransactionIdIsCurrentTransactionId(xvac) ||
+               TransactionIdIsInProgress(xvac))
+       {
+               elog(ERROR, "HEAP_MOVED tuple with in-progress xvac: %u", xvac);
+       }
+
+       if (tuple->t_infomask & HEAP_MOVED_OFF)
+       {
+               if (TransactionIdDidCommit(xvac))
+               {
+                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
+                                               InvalidTransactionId);
+                       return false;
+               }
+               else
+               {
+                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
+                                               InvalidTransactionId);
+                       return true;
+               }
+       }
+       /* Used by pre-9.0 binary upgrades */
+       else if (tuple->t_infomask & HEAP_MOVED_IN)
+       {
+               if (TransactionIdDidCommit(xvac))
+               {
+                       SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
+                                               InvalidTransactionId);
+                       return true;
+               }
+               else
+               {
+                       SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
+                                               InvalidTransactionId);
+                       return false;
+               }
+       }
+       else
+       {
+               elog(ERROR, "IsMovedTupleVisible() called on a non-moved tuple");
+               return true; /* keep compiler quiet */
+       }
+}