HeapTupleHeader accessor macros - Mailing list pgsql-patches

From Manfred Koizar
Subject HeapTupleHeader accessor macros
Date
Msg-id jcfrdu40qpg6cm6mllklb1ug3p90ugkmd1@4ax.com
Whole thread Raw
Responses HeapTupleHeader accessor macros II  (Manfred Koizar <mkoi-pg@aon.at>)
Re: HeapTupleHeader accessor macros  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
This patch wraps all accesses to t_xmin, t_cmin, t_xmax, and t_cmax in
HeapTupleHeaderData in setter and getter macros called
HeapTupleHeaderGetXmin, HeapTupleHeaderSetXmin etc.

It also introduces a "virtual" field xvac by defining
HeapTupleHeaderGetXvac and HeapTupleHeaderSetXvac.  Xvac is used by
VACUUM, in fact it is stored in t_cmin.

This patch doesn't change any behaviour, it just (hopefully) makes the
source code more readable.  It is meant as a first step toward an
upcoming change in HeapTupleHeader, which will reduce on-disk tuple
size by four bytes.

Regression tests have been passed (except geometry, which always fails
on my machine).  Please apply this patch (after my bitmaplen patch)
for 7.3.

It worked for 7.2 before I updated my cvs HEAD revision and recreated
the patch.  If cosmetic changes are wanted for 7.2, I'll make a 7.2
version available.

Servus
 Manfred
diff -c -r ../orig/src/backend/access/common/heaptuple.c src/backend/access/common/heaptuple.c
*** ../orig/src/backend/access/common/heaptuple.c    Thu Oct 25 07:49:20 2001
--- src/backend/access/common/heaptuple.c    Sat May 11 14:54:50 2002
***************
*** 439,454 ****
              result = ObjectIdGetDatum(tup->t_data->t_oid);
              break;
          case MinTransactionIdAttributeNumber:
!             result = TransactionIdGetDatum(tup->t_data->t_xmin);
              break;
          case MinCommandIdAttributeNumber:
!             result = CommandIdGetDatum(tup->t_data->t_cmin);
              break;
          case MaxTransactionIdAttributeNumber:
!             result = TransactionIdGetDatum(tup->t_data->t_xmax);
              break;
          case MaxCommandIdAttributeNumber:
!             result = CommandIdGetDatum(tup->t_data->t_cmax);
              break;
          case TableOidAttributeNumber:
              result = ObjectIdGetDatum(tup->t_tableOid);
--- 439,454 ----
              result = ObjectIdGetDatum(tup->t_data->t_oid);
              break;
          case MinTransactionIdAttributeNumber:
!             result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));
              break;
          case MinCommandIdAttributeNumber:
!             result = CommandIdGetDatum(HeapTupleHeaderGetCmin(tup->t_data));
              break;
          case MaxTransactionIdAttributeNumber:
!             result = TransactionIdGetDatum(HeapTupleHeaderGetXmax(tup->t_data));
              break;
          case MaxCommandIdAttributeNumber:
!             result = CommandIdGetDatum(HeapTupleHeaderGetCmax(tup->t_data));
              break;
          case TableOidAttributeNumber:
              result = ObjectIdGetDatum(tup->t_tableOid);
diff -c -r ../orig/src/backend/access/heap/heapam.c src/backend/access/heap/heapam.c
*** ../orig/src/backend/access/heap/heapam.c    Wed May  1 03:23:37 2002
--- src/backend/access/heap/heapam.c    Sat May 11 18:13:45 2002
***************
*** 1118,1128 ****
              CheckMaxObjectId(tup->t_data->t_oid);
      }

-     TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin));
-     tup->t_data->t_cmin = GetCurrentCommandId();
-     StoreInvalidTransactionId(&(tup->t_data->t_xmax));
      tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
      tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
      tup->t_tableOid = relation->rd_id;

  #ifdef TUPLE_TOASTER_ACTIVE
--- 1118,1128 ----
              CheckMaxObjectId(tup->t_data->t_oid);
      }

      tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
      tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
+     HeapTupleHeaderSetXmin(tup->t_data, GetCurrentTransactionId());
+     HeapTupleHeaderSetCmin(tup->t_data, GetCurrentCommandId());
+     HeapTupleHeaderSetXmaxInvalid(tup->t_data);
      tup->t_tableOid = relation->rd_id;

  #ifdef TUPLE_TOASTER_ACTIVE
***************
*** 1251,1257 ****
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = tp.t_data->t_xmax;

          /* sleep until concurrent transaction ends */
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
--- 1251,1257 ----
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = HeapTupleHeaderGetXmax(tp.t_data);

          /* sleep until concurrent transaction ends */
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
***************
*** 1266,1272 ****
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(tp.t_data->t_xmax, xwait))
              goto l1;
          if (!(tp.t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
--- 1266,1272 ----
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(HeapTupleHeaderGetXmax(tp.t_data), xwait))
              goto l1;
          if (!(tp.t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
***************
*** 1290,1299 ****

      START_CRIT_SECTION();
      /* store transaction information of xact deleting the tuple */
-     TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
-     tp.t_data->t_cmax = GetCurrentCommandId();
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                               HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
      /* XLOG stuff */
      {
          xl_heap_delete xlrec;
--- 1290,1299 ----

      START_CRIT_SECTION();
      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                               HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
+     HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId());
+     HeapTupleHeaderSetCmax(tp.t_data, GetCurrentCommandId());
      /* XLOG stuff */
      {
          xl_heap_delete xlrec;
***************
*** 1443,1449 ****
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = oldtup.t_data->t_xmax;

          /* sleep untill concurrent transaction ends */
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
--- 1443,1449 ----
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = HeapTupleHeaderGetXmax(oldtup.t_data);

          /* sleep untill concurrent transaction ends */
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
***************
*** 1458,1464 ****
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(oldtup.t_data->t_xmax, xwait))
              goto l2;
          if (!(oldtup.t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
--- 1458,1464 ----
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(HeapTupleHeaderGetXmax(oldtup.t_data), xwait))
              goto l2;
          if (!(oldtup.t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
***************
*** 1482,1492 ****

      /* Fill in OID and transaction status data for newtup */
      newtup->t_data->t_oid = oldtup.t_data->t_oid;
-     TransactionIdStore(GetCurrentTransactionId(), &(newtup->t_data->t_xmin));
-     newtup->t_data->t_cmin = GetCurrentCommandId();
-     StoreInvalidTransactionId(&(newtup->t_data->t_xmax));
      newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
      newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED);

      /*
       * If the toaster needs to be activated, OR if the new tuple will not
--- 1482,1492 ----

      /* Fill in OID and transaction status data for newtup */
      newtup->t_data->t_oid = oldtup.t_data->t_oid;
      newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
      newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED);
+     HeapTupleHeaderSetXmin(newtup->t_data, GetCurrentTransactionId());
+     HeapTupleHeaderSetCmin(newtup->t_data, GetCurrentCommandId());
+     HeapTupleHeaderSetXmaxInvalid(newtup->t_data);

      /*
       * If the toaster needs to be activated, OR if the new tuple will not
***************
*** 1520,1532 ****
          _locked_tuple_.tid = oldtup.t_self;
          XactPushRollback(_heap_unlock_tuple, (void *) &_locked_tuple_);

-         TransactionIdStore(GetCurrentTransactionId(),
-                            &(oldtup.t_data->t_xmax));
-         oldtup.t_data->t_cmax = GetCurrentCommandId();
          oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                         HEAP_XMAX_INVALID |
                                         HEAP_MARKED_FOR_UPDATE);
          oldtup.t_data->t_infomask |= HEAP_XMAX_UNLOGGED;
          already_marked = true;
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);

--- 1520,1531 ----
          _locked_tuple_.tid = oldtup.t_self;
          XactPushRollback(_heap_unlock_tuple, (void *) &_locked_tuple_);

          oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                         HEAP_XMAX_INVALID |
                                         HEAP_MARKED_FOR_UPDATE);
          oldtup.t_data->t_infomask |= HEAP_XMAX_UNLOGGED;
+         HeapTupleHeaderSetXmax(oldtup.t_data, GetCurrentTransactionId());
+         HeapTupleHeaderSetCmax(oldtup.t_data, GetCurrentCommandId());
          already_marked = true;
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);

***************
*** 1612,1623 ****
      }
      else
      {
-         TransactionIdStore(GetCurrentTransactionId(),
-                            &(oldtup.t_data->t_xmax));
-         oldtup.t_data->t_cmax = GetCurrentCommandId();
          oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                         HEAP_XMAX_INVALID |
                                         HEAP_MARKED_FOR_UPDATE);
      }

      /* record address of new tuple in t_ctid of old one */
--- 1611,1621 ----
      }
      else
      {
          oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                         HEAP_XMAX_INVALID |
                                         HEAP_MARKED_FOR_UPDATE);
+         HeapTupleHeaderSetXmax(oldtup.t_data, GetCurrentTransactionId());
+         HeapTupleHeaderSetCmax(oldtup.t_data, GetCurrentCommandId());
      }

      /* record address of new tuple in t_ctid of old one */
***************
*** 1740,1746 ****
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = tuple->t_data->t_xmax;

          /* sleep untill concurrent transaction ends */
          LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
--- 1738,1744 ----
      }
      else if (result == HeapTupleBeingUpdated)
      {
!         TransactionId xwait = HeapTupleHeaderGetXmax(tuple->t_data);

          /* sleep untill concurrent transaction ends */
          LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
***************
*** 1755,1761 ****
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(tuple->t_data->t_xmax, xwait))
              goto l3;
          if (!(tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
--- 1753,1759 ----
           * update then some other xaction could update this tuple before
           * we got to this point.
           */
!         if (!TransactionIdEquals(HeapTupleHeaderGetXmax(tuple->t_data), xwait))
              goto l3;
          if (!(tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED))
          {
***************
*** 1783,1792 ****
      ((PageHeader) BufferGetPage(*buffer))->pd_sui = ThisStartUpID;

      /* store transaction information of xact marking the tuple */
-     TransactionIdStore(GetCurrentTransactionId(), &(tuple->t_data->t_xmax));
-     tuple->t_data->t_cmax = GetCurrentCommandId();
      tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
      tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE;

      LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);

--- 1781,1790 ----
      ((PageHeader) BufferGetPage(*buffer))->pd_sui = ThisStartUpID;

      /* store transaction information of xact marking the tuple */
      tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
      tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE;
+     HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId());
+     HeapTupleHeaderSetCmax(tuple->t_data, GetCurrentCommandId());

      LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);

***************
*** 1962,1976 ****
      if (move)                    /* remember xmin & xmax */
      {
          TransactionId xmax;

          if (newtup->t_data->t_infomask & HEAP_XMAX_INVALID ||
              newtup->t_data->t_infomask & HEAP_MARKED_FOR_UPDATE)
              xmax = InvalidTransactionId;
          else
!             xmax = newtup->t_data->t_xmax;
          memcpy((char *) &xlhdr + hsize, &xmax, sizeof(TransactionId));
          memcpy((char *) &xlhdr + hsize + sizeof(TransactionId),
!                &(newtup->t_data->t_xmin), sizeof(TransactionId));
          hsize += 2 * sizeof(TransactionId);
      }
      rdata[2].buffer = newbuf;
--- 1960,1976 ----
      if (move)                    /* remember xmin & xmax */
      {
          TransactionId xmax;
+         TransactionId xmin;

          if (newtup->t_data->t_infomask & HEAP_XMAX_INVALID ||
              newtup->t_data->t_infomask & HEAP_MARKED_FOR_UPDATE)
              xmax = InvalidTransactionId;
          else
!             xmax = HeapTupleHeaderGetXmax(newtup->t_data);
!         xmin = HeapTupleHeaderGetXmin(newtup->t_data);
          memcpy((char *) &xlhdr + hsize, &xmax, sizeof(TransactionId));
          memcpy((char *) &xlhdr + hsize + sizeof(TransactionId),
!                &xmin, sizeof(TransactionId));
          hsize += 2 * sizeof(TransactionId);
      }
      rdata[2].buffer = newbuf;
***************
*** 2107,2116 ****

      if (redo)
      {
-         htup->t_xmax = record->xl_xid;
-         htup->t_cmax = FirstCommandId;
          htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
          PageSetLSN(page, lsn);
          PageSetSUI(page, ThisStartUpID);
          UnlockAndWriteBuffer(buffer);
--- 2107,2116 ----

      if (redo)
      {
          htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                                HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
+         HeapTupleHeaderSetXmax(htup, record->xl_xid);
+         HeapTupleHeaderSetCmax(htup, FirstCommandId);
          PageSetLSN(page, lsn);
          PageSetSUI(page, ThisStartUpID);
          UnlockAndWriteBuffer(buffer);
***************
*** 2182,2192 ****
          htup->t_oid = xlhdr.t_oid;
          htup->t_natts = xlhdr.t_natts;
          htup->t_hoff = xlhdr.t_hoff;
-         htup->t_xmin = record->xl_xid;
-         htup->t_cmin = FirstCommandId;
-         htup->t_xmax = InvalidTransactionId;
-         htup->t_cmax = FirstCommandId;
          htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;

          offnum = PageAddItem(page, (Item) htup, newlen, offnum,
                               LP_USED | OverwritePageMode);
--- 2182,2192 ----
          htup->t_oid = xlhdr.t_oid;
          htup->t_natts = xlhdr.t_natts;
          htup->t_hoff = xlhdr.t_hoff;
          htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
+         HeapTupleHeaderSetXmin(htup, record->xl_xid);
+         HeapTupleHeaderSetCmin(htup, FirstCommandId);
+         HeapTupleHeaderSetXmax(htup, InvalidTransactionId);
+         HeapTupleHeaderSetCmax(htup, FirstCommandId);

          offnum = PageAddItem(page, (Item) htup, newlen, offnum,
                               LP_USED | OverwritePageMode);
***************
*** 2267,2283 ****
      {
          if (move)
          {
-             TransactionIdStore(record->xl_xid, (TransactionId *) &(htup->t_cmin));
              htup->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
              htup->t_infomask |= HEAP_MOVED_OFF;
          }
          else
          {
-             htup->t_xmax = record->xl_xid;
-             htup->t_cmax = FirstCommandId;
              htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                               HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
          }
          if (samepage)
              goto newsame;
--- 2267,2283 ----
      {
          if (move)
          {
              htup->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
              htup->t_infomask |= HEAP_MOVED_OFF;
+             HeapTupleHeaderSetXvac(htup, record->xl_xid);
          }
          else
          {
              htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
                               HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
+             HeapTupleHeaderSetXmax(htup, record->xl_xid);
+             HeapTupleHeaderSetCmax(htup, FirstCommandId);
          }
          if (samepage)
              goto newsame;
***************
*** 2353,2378 ****
          htup->t_hoff = xlhdr.t_hoff;
          if (move)
          {
              hsize = SizeOfHeapUpdate + SizeOfHeapHeader;
!             memcpy(&(htup->t_xmax),
!                    (char *) xlrec + hsize,
!                    sizeof(TransactionId));
!             memcpy(&(htup->t_xmin),
!                    (char *) xlrec + hsize + sizeof(TransactionId),
!                    sizeof(TransactionId));
!             TransactionIdStore(record->xl_xid, (TransactionId *) &(htup->t_cmin));
              htup->t_infomask = xlhdr.mask;
              htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
                                    HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
              htup->t_infomask |= HEAP_MOVED_IN;
          }
          else
          {
-             htup->t_xmin = record->xl_xid;
-             htup->t_cmin = FirstCommandId;
-             htup->t_xmax = InvalidTransactionId;
-             htup->t_cmax = FirstCommandId;
              htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
          }

          offnum = PageAddItem(page, (Item) htup, newlen, offnum,
--- 2353,2379 ----
          htup->t_hoff = xlhdr.t_hoff;
          if (move)
          {
+             TransactionId xmax;
+             TransactionId xmin;
+
              hsize = SizeOfHeapUpdate + SizeOfHeapHeader;
!             memcpy(&xmax, (char *) xlrec + hsize, sizeof(TransactionId));
!             memcpy(&xmin, (char *) xlrec + hsize + sizeof(TransactionId), sizeof(TransactionId));
              htup->t_infomask = xlhdr.mask;
              htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
                                    HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
              htup->t_infomask |= HEAP_MOVED_IN;
+             HeapTupleHeaderSetXmin(htup, xmin);
+             HeapTupleHeaderSetXmax(htup, xmax);
+             HeapTupleHeaderSetXvac(htup, record->xl_xid);
          }
          else
          {
              htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
+             HeapTupleHeaderSetXmin(htup, record->xl_xid);
+             HeapTupleHeaderSetCmin(htup, FirstCommandId);
+             HeapTupleHeaderSetXmaxInvalid(htup);
+             HeapTupleHeaderSetCmax(htup, FirstCommandId);
          }

          offnum = PageAddItem(page, (Item) htup, newlen, offnum,
***************
*** 2426,2433 ****

      htup = (HeapTupleHeader) PageGetItem(page, lp);

!     if (!TransactionIdEquals(htup->t_xmax, GetCurrentTransactionId()) ||
!         htup->t_cmax != GetCurrentCommandId())
          elog(PANIC, "_heap_unlock_tuple: invalid xmax/cmax in rollback");
      htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
      htup->t_infomask |= HEAP_XMAX_INVALID;
--- 2427,2434 ----

      htup = (HeapTupleHeader) PageGetItem(page, lp);

!     if (!TransactionIdEquals(HeapTupleHeaderGetXmax(htup), GetCurrentTransactionId()) ||
!         HeapTupleHeaderGetCmax(htup) != GetCurrentCommandId())
          elog(PANIC, "_heap_unlock_tuple: invalid xmax/cmax in rollback");
      htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
      htup->t_infomask |= HEAP_XMAX_INVALID;
diff -c -r ../orig/src/backend/access/transam/xlogutils.c src/backend/access/transam/xlogutils.c
*** ../orig/src/backend/access/transam/xlogutils.c    Sun Mar 31 08:26:29 2002
--- src/backend/access/transam/xlogutils.c    Sat May 11 15:16:40 2002
***************
*** 73,79 ****
      htup = (HeapTupleHeader) PageGetItem(page, lp);

      Assert(PageGetSUI(page) == ThisStartUpID);
!     if (!TransactionIdEquals(htup->t_xmin, xid) || htup->t_cmin != cid)
      {
          UnlockAndReleaseBuffer(buffer);
          return (-1);
--- 73,80 ----
      htup = (HeapTupleHeader) PageGetItem(page, lp);

      Assert(PageGetSUI(page) == ThisStartUpID);
!     if (!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), xid) ||
!         HeapTupleHeaderGetCmin(htup) != cid)
      {
          UnlockAndReleaseBuffer(buffer);
          return (-1);
***************
*** 137,144 ****
      {
          if (htup->t_infomask & HEAP_XMIN_INVALID ||
              (htup->t_infomask & HEAP_MOVED_IN &&
!              TransactionIdDidAbort((TransactionId) htup->t_cmin)) ||
!             TransactionIdDidAbort(htup->t_xmin))
          {
              UnlockAndReleaseBuffer(buffer);
              return (false);
--- 138,145 ----
      {
          if (htup->t_infomask & HEAP_XMIN_INVALID ||
              (htup->t_infomask & HEAP_MOVED_IN &&
!              TransactionIdDidAbort(HeapTupleHeaderGetXvac(htup))) ||
!             TransactionIdDidAbort(HeapTupleHeaderGetXmin(htup)))
          {
              UnlockAndReleaseBuffer(buffer);
              return (false);
diff -c -r ../orig/src/backend/catalog/index.c src/backend/catalog/index.c
*** ../orig/src/backend/catalog/index.c    Sat Apr 27 23:24:34 2002
--- src/backend/catalog/index.c    Sat May 11 15:34:12 2002
***************
*** 1622,1628 ****
                       * (Consider INSERT followed by CREATE INDEX within a
                       * transaction.)
                       */
!                     if (!TransactionIdIsCurrentTransactionId(heapTuple->t_data->t_xmin))
                          elog(ERROR, "IndexBuildHeapScan: concurrent insert in progress");
                      indexIt = true;
                      tupleIsAlive = true;
--- 1622,1629 ----
                       * (Consider INSERT followed by CREATE INDEX within a
                       * transaction.)
                       */
!                     if (!TransactionIdIsCurrentTransactionId(
!                             HeapTupleHeaderGetXmin(heapTuple->t_data)))
                          elog(ERROR, "IndexBuildHeapScan: concurrent insert in progress");
                      indexIt = true;
                      tupleIsAlive = true;
***************
*** 1636,1642 ****
                       * (Consider DELETE followed by CREATE INDEX within a
                       * transaction.)
                       */
!                     if (!TransactionIdIsCurrentTransactionId(heapTuple->t_data->t_xmax))
                          elog(ERROR, "IndexBuildHeapScan: concurrent delete in progress");
                      indexIt = true;
                      tupleIsAlive = false;
--- 1637,1644 ----
                       * (Consider DELETE followed by CREATE INDEX within a
                       * transaction.)
                       */
!                     if (!TransactionIdIsCurrentTransactionId(
!                             HeapTupleHeaderGetXmax(heapTuple->t_data)))
                          elog(ERROR, "IndexBuildHeapScan: concurrent delete in progress");
                      indexIt = true;
                      tupleIsAlive = false;
diff -c -r ../orig/src/backend/commands/sequence.c src/backend/commands/sequence.c
*** ../orig/src/backend/commands/sequence.c    Mon Apr 15 07:22:03 2002
--- src/backend/commands/sequence.c    Sat May 11 15:36:05 2002
***************
*** 233,242 ****
          itemId = PageGetItemId((Page) page, FirstOffsetNumber);
          item = PageGetItem((Page) page, itemId);

!         ((HeapTupleHeader) item)->t_xmin = FrozenTransactionId;
          ((HeapTupleHeader) item)->t_infomask |= HEAP_XMIN_COMMITTED;

!         tuple->t_data->t_xmin = FrozenTransactionId;
          tuple->t_data->t_infomask |= HEAP_XMIN_COMMITTED;
      }

--- 233,242 ----
          itemId = PageGetItemId((Page) page, FirstOffsetNumber);
          item = PageGetItem((Page) page, itemId);

!         HeapTupleHeaderSetXmin((HeapTupleHeader) item, FrozenTransactionId);
          ((HeapTupleHeader) item)->t_infomask |= HEAP_XMIN_COMMITTED;

!         HeapTupleHeaderSetXmin(tuple->t_data, FrozenTransactionId);
          tuple->t_data->t_infomask |= HEAP_XMIN_COMMITTED;
      }

diff -c -r ../orig/src/backend/commands/vacuum.c src/backend/commands/vacuum.c
*** ../orig/src/backend/commands/vacuum.c    Tue Apr 16 01:39:42 2002
--- src/backend/commands/vacuum.c    Sat May 11 18:05:22 2002
***************
*** 1062,1072 ****
                       * Tuple is good.  Consider whether to replace its
                       * xmin value with FrozenTransactionId.
                       */
!                     if (TransactionIdIsNormal(tuple.t_data->t_xmin) &&
!                         TransactionIdPrecedes(tuple.t_data->t_xmin,
                                                FreezeLimit))
                      {
!                         tuple.t_data->t_xmin = FrozenTransactionId;
                          /* infomask should be okay already */
                          Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
                          pgchanged = true;
--- 1062,1072 ----
                       * Tuple is good.  Consider whether to replace its
                       * xmin value with FrozenTransactionId.
                       */
!                     if (TransactionIdIsNormal(HeapTupleHeaderGetXmin(tuple.t_data)) &&
!                         TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data),
                                                FreezeLimit))
                      {
!                         HeapTupleHeaderSetXmin(tuple.t_data, FrozenTransactionId);
                          /* infomask should be okay already */
                          Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
                          pgchanged = true;
***************
*** 1109,1115 ****
                       * lock on the relation; shouldn't we raise an error?
                       */
                      elog(WARNING, "Rel %s: TID %u/%u: InsertTransactionInProgress %u - can't shrink relation",
!                          relname, blkno, offnum, tuple.t_data->t_xmin);
                      do_shrinking = false;
                      break;
                  case HEAPTUPLE_DELETE_IN_PROGRESS:
--- 1109,1115 ----
                       * lock on the relation; shouldn't we raise an error?
                       */
                      elog(WARNING, "Rel %s: TID %u/%u: InsertTransactionInProgress %u - can't shrink relation",
!                          relname, blkno, offnum, HeapTupleHeaderGetXmin(tuple.t_data));
                      do_shrinking = false;
                      break;
                  case HEAPTUPLE_DELETE_IN_PROGRESS:
***************
*** 1119,1125 ****
                       * lock on the relation; shouldn't we raise an error?
                       */
                      elog(WARNING, "Rel %s: TID %u/%u: DeleteTransactionInProgress %u - can't shrink relation",
!                          relname, blkno, offnum, tuple.t_data->t_xmax);
                      do_shrinking = false;
                      break;
                  default:
--- 1119,1125 ----
                       * lock on the relation; shouldn't we raise an error?
                       */
                      elog(WARNING, "Rel %s: TID %u/%u: DeleteTransactionInProgress %u - can't shrink relation",
!                          relname, blkno, offnum, HeapTupleHeaderGetXmax(tuple.t_data));
                      do_shrinking = false;
                      break;
                  default:
***************
*** 1495,1502 ****

              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
              {
!                 if ((TransactionId) tuple.t_data->t_cmin != myXID)
!                     elog(ERROR, "Invalid XID in t_cmin");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                      elog(ERROR, "HEAP_MOVED_IN was not expected");

--- 1495,1502 ----

              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
              {
!                 if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
!                     elog(ERROR, "Invalid XVAC in tuple header");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                      elog(ERROR, "HEAP_MOVED_IN was not expected");

***************
*** 1540,1546 ****
               * tuples to another places.
               */
              if ((tuple.t_data->t_infomask & HEAP_UPDATED &&
!              !TransactionIdPrecedes(tuple.t_data->t_xmin, OldestXmin)) ||
                  (!(tuple.t_data->t_infomask & HEAP_XMAX_INVALID) &&
                   !(ItemPointerEquals(&(tuple.t_self),
                                       &(tuple.t_data->t_ctid)))))
--- 1540,1547 ----
               * tuples to another places.
               */
              if ((tuple.t_data->t_infomask & HEAP_UPDATED &&
!              !TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data),
!                                     OldestXmin)) ||
                  (!(tuple.t_data->t_infomask & HEAP_XMAX_INVALID) &&
                   !(ItemPointerEquals(&(tuple.t_self),
                                       &(tuple.t_data->t_ctid)))))
***************
*** 1657,1663 ****

                      /* All done ? */
                      if (!(tp.t_data->t_infomask & HEAP_UPDATED) ||
!                     TransactionIdPrecedes(tp.t_data->t_xmin, OldestXmin))
                          break;

                      /* Well, try to find tuple with old row version */
--- 1658,1665 ----

                      /* All done ? */
                      if (!(tp.t_data->t_infomask & HEAP_UPDATED) ||
!                         TransactionIdPrecedes(HeapTupleHeaderGetXmin(tp.t_data),
!                                               OldestXmin))
                          break;

                      /* Well, try to find tuple with old row version */
***************
*** 1705,1712 ****
                           * latter, and we are too close to 6.5 release. -
                           * vadim 06/11/99
                           */
!                         if (!(TransactionIdEquals(Ptp.t_data->t_xmax,
!                                                   tp.t_data->t_xmin)))
                          {
                              if (freeCbuf)
                                  ReleaseBuffer(Cbuf);
--- 1707,1714 ----
                           * latter, and we are too close to 6.5 release. -
                           * vadim 06/11/99
                           */
!                         if (!(TransactionIdEquals(HeapTupleHeaderGetXmax(Ptp.t_data),
!                                                   HeapTupleHeaderGetXmin(tp.t_data))))
                          {
                              if (freeCbuf)
                                  ReleaseBuffer(Cbuf);
***************
*** 1731,1744 ****
                           * removed.
                           */
                          if (Ptp.t_data->t_infomask & HEAP_UPDATED &&
!                             TransactionIdEquals(Ptp.t_data->t_xmin,
!                                                 Ptp.t_data->t_xmax))
                          {
-                             TransactionIdStore(myXID,
-                                 (TransactionId *) &(Ptp.t_data->t_cmin));
                              Ptp.t_data->t_infomask &=
                                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
                              Ptp.t_data->t_infomask |= HEAP_MOVED_OFF;
                              WriteBuffer(Pbuf);
                              continue;
                          }
--- 1733,1745 ----
                           * removed.
                           */
                          if (Ptp.t_data->t_infomask & HEAP_UPDATED &&
!                             TransactionIdEquals(HeapTupleHeaderGetXmin(Ptp.t_data),
!                                                 HeapTupleHeaderGetXmax(Ptp.t_data)))
                          {
                              Ptp.t_data->t_infomask &=
                                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
                              Ptp.t_data->t_infomask |= HEAP_MOVED_OFF;
+                             HeapTupleHeaderSetXvac(Ptp.t_data, myXID);
                              WriteBuffer(Pbuf);
                              continue;
                          }
***************
*** 1802,1811 ****
                      /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
                      START_CRIT_SECTION();

-                     TransactionIdStore(myXID, (TransactionId *) &(tuple.t_data->t_cmin));
                      tuple.t_data->t_infomask &=
                          ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
                      tuple.t_data->t_infomask |= HEAP_MOVED_OFF;

                      /*
                       * If this page was not used before - clean it.
--- 1803,1812 ----
                      /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */
                      START_CRIT_SECTION();

                      tuple.t_data->t_infomask &=
                          ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
                      tuple.t_data->t_infomask |= HEAP_MOVED_OFF;
+                     HeapTupleHeaderSetXvac(tuple.t_data, myXID);

                      /*
                       * If this page was not used before - clean it.
***************
*** 1842,1851 ****
                       * Update the state of the copied tuple, and store it
                       * on the destination page.
                       */
-                     TransactionIdStore(myXID, (TransactionId *) &(newtup.t_data->t_cmin));
                      newtup.t_data->t_infomask &=
                          ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
                      newtup.t_data->t_infomask |= HEAP_MOVED_IN;
                      newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len,
                                           InvalidOffsetNumber, LP_USED);
                      if (newoff == InvalidOffsetNumber)
--- 1843,1852 ----
                       * Update the state of the copied tuple, and store it
                       * on the destination page.
                       */
                      newtup.t_data->t_infomask &=
                          ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
                      newtup.t_data->t_infomask |= HEAP_MOVED_IN;
+                     HeapTupleHeaderSetXvac(newtup.t_data, myXID);
                      newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len,
                                           InvalidOffsetNumber, LP_USED);
                      if (newoff == InvalidOffsetNumber)
***************
*** 1971,1980 ****
               * Mark new tuple as moved_in by vacuum and store vacuum XID
               * in t_cmin !!!
               */
-             TransactionIdStore(myXID, (TransactionId *) &(newtup.t_data->t_cmin));
              newtup.t_data->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
              newtup.t_data->t_infomask |= HEAP_MOVED_IN;

              /* add tuple to the page */
              newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len,
--- 1972,1981 ----
               * Mark new tuple as moved_in by vacuum and store vacuum XID
               * in t_cmin !!!
               */
              newtup.t_data->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
              newtup.t_data->t_infomask |= HEAP_MOVED_IN;
+             HeapTupleHeaderSetXvac(newtup.t_data, myXID);

              /* add tuple to the page */
              newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len,
***************
*** 1997,2006 ****
               * Mark old tuple as moved_off by vacuum and store vacuum XID
               * in t_cmin !!!
               */
-             TransactionIdStore(myXID, (TransactionId *) &(tuple.t_data->t_cmin));
              tuple.t_data->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
              tuple.t_data->t_infomask |= HEAP_MOVED_OFF;

              {
                  XLogRecPtr    recptr =
--- 1998,2007 ----
               * Mark old tuple as moved_off by vacuum and store vacuum XID
               * in t_cmin !!!
               */
              tuple.t_data->t_infomask &=
                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
              tuple.t_data->t_infomask |= HEAP_MOVED_OFF;
+             HeapTupleHeaderSetXvac(tuple.t_data, myXID);

              {
                  XLogRecPtr    recptr =
***************
*** 2048,2055 ****
                  tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
                  if (tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED)
                      continue;
!                 if ((TransactionId) tuple.t_data->t_cmin != myXID)
!                     elog(ERROR, "Invalid XID in t_cmin (4)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                      elog(ERROR, "HEAP_MOVED_IN was not expected (2)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
--- 2049,2056 ----
                  tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
                  if (tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED)
                      continue;
!                 if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
!                     elog(ERROR, "Invalid XVAC in tuple header (4)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                      elog(ERROR, "HEAP_MOVED_IN was not expected (2)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
***************
*** 2186,2193 ****
              tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
              {
!                 if ((TransactionId) tuple.t_data->t_cmin != myXID)
!                     elog(ERROR, "Invalid XID in t_cmin (2)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                  {
                      tuple.t_data->t_infomask |= HEAP_XMIN_COMMITTED;
--- 2187,2194 ----
              tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
              {
!                 if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
!                     elog(ERROR, "Invalid XVAC in tuple header (2)");
                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
                  {
                      tuple.t_data->t_infomask |= HEAP_XMIN_COMMITTED;
***************
*** 2265,2272 ****

                  if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
                  {
!                     if ((TransactionId) tuple.t_data->t_cmin != myXID)
!                         elog(ERROR, "Invalid XID in t_cmin (3)");
                      if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
                      {
                          itemid->lp_flags &= ~LP_USED;
--- 2266,2273 ----

                  if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
                  {
!                     if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
!                         elog(ERROR, "Invalid XVAC in tuple header (3)");
                      if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
                      {
                          itemid->lp_flags &= ~LP_USED;
diff -c -r ../orig/src/backend/commands/vacuumlazy.c src/backend/commands/vacuumlazy.c
*** ../orig/src/backend/commands/vacuumlazy.c    Tue Apr  2 03:03:05 2002
--- src/backend/commands/vacuumlazy.c    Sat May 11 15:50:17 2002
***************
*** 332,342 ****
                       * assumption by momentarily acquiring exclusive lock,
                       * but for the moment I see no need to.
                       */
!                     if (TransactionIdIsNormal(tuple.t_data->t_xmin) &&
!                         TransactionIdPrecedes(tuple.t_data->t_xmin,
                                                FreezeLimit))
                      {
!                         tuple.t_data->t_xmin = FrozenTransactionId;
                          /* infomask should be okay already */
                          Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
                          pgchanged = true;
--- 332,342 ----
                       * assumption by momentarily acquiring exclusive lock,
                       * but for the moment I see no need to.
                       */
!                     if (TransactionIdIsNormal(HeapTupleHeaderGetXmin(tuple.t_data)) &&
!                         TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data),
                                                FreezeLimit))
                      {
!                         HeapTupleHeaderSetXmin(tuple.t_data, FrozenTransactionId);
                          /* infomask should be okay already */
                          Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
                          pgchanged = true;
diff -c -r ../orig/src/backend/utils/time/tqual.c src/backend/utils/time/tqual.c
*** ../orig/src/backend/utils/time/tqual.c    Mon May  6 18:27:02 2002
--- src/backend/utils/time/tqual.c    Sun May 12 00:51:04 2002
***************
*** 70,80 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return false;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 70,80 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 84,94 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return false;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 84,94 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 97,117 ****
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
          {
              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;

              return false;
          }
!         else if (!TransactionIdDidCommit(tuple->t_xmin))
          {
!             if (TransactionIdDidAbort(tuple->t_xmin))
                  tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
              return false;
          }
--- 97,117 ----
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
          {
              if (tuple->t_infomask & HEAP_XMAX_INVALID)    /* xid invalid */
                  return true;

!             Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return true;

              return false;
          }
!         else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
              return false;
          }
***************
*** 131,146 ****
          return false;            /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return true;
          return false;
      }

!     if (!TransactionIdDidCommit(tuple->t_xmax))
      {
!         if (TransactionIdDidAbort(tuple->t_xmax))
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
          return true;
      }
--- 131,146 ----
          return false;            /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return true;
          return false;
      }

!     if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
      {
!         if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
          return true;
      }
***************
*** 209,219 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return false;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 209,219 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 223,233 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return false;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 223,233 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 236,262 ****
                  }
              }
          }
!         else 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 */
          }
!         else if (!TransactionIdDidCommit(tuple->t_xmin))
          {
!             if (TransactionIdDidAbort(tuple->t_xmin))
                  tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
              return false;
          }
--- 236,262 ----
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmin(tuple)))
                  return false;    /* inserted after scan started */

              if (tuple->t_infomask & HEAP_XMAX_INVALID)    /* xid invalid */
                  return true;

!             Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return true;

!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
                  return true;    /* deleted after scan started */
              else
                  return false;    /* deleted before scan started */
          }
!         else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
              return false;
          }
***************
*** 276,294 ****
          return false;
      }

!     if (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 */
      }

!     if (!TransactionIdDidCommit(tuple->t_xmax))
      {
!         if (TransactionIdDidAbort(tuple->t_xmax))
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
          return true;
      }
--- 276,294 ----
          return false;
      }

!     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return true;
!         if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
              return true;        /* deleted after scan started */
          else
              return false;        /* deleted before scan started */
      }

!     if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
      {
!         if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
          return true;
      }
***************
*** 326,336 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return false;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 326,336 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 340,350 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return false;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 340,350 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 380,390 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return HeapTupleInvisible;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return HeapTupleInvisible;
--- 380,390 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HeapTupleInvisible;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return HeapTupleInvisible;
***************
*** 394,404 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return HeapTupleInvisible;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 394,404 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return HeapTupleInvisible;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 407,436 ****
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
          {
!             if (CommandIdGEScanCommandId(tuple->t_cmin))
                  return HeapTupleInvisible;        /* inserted after scan
                                                   * started */

              if (tuple->t_infomask & HEAP_XMAX_INVALID)        /* xid invalid */
                  return HeapTupleMayBeUpdated;

!             Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return HeapTupleMayBeUpdated;

!             if (CommandIdGEScanCommandId(tuple->t_cmax))
                  return HeapTupleSelfUpdated;    /* updated after scan
                                                   * started */
              else
                  return HeapTupleInvisible;        /* updated before scan
                                                   * started */
          }
!         else if (!TransactionIdDidCommit(tuple->t_xmin))
          {
!             if (TransactionIdDidAbort(tuple->t_xmin))
                  tuple->t_infomask |= HEAP_XMIN_INVALID;    /* aborted */
              return HeapTupleInvisible;
          }
--- 407,436 ----
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmin(tuple)))
                  return HeapTupleInvisible;        /* inserted after scan
                                                   * started */

              if (tuple->t_infomask & HEAP_XMAX_INVALID)        /* xid invalid */
                  return HeapTupleMayBeUpdated;

!             Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return HeapTupleMayBeUpdated;

!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
                  return HeapTupleSelfUpdated;    /* updated after scan
                                                   * started */
              else
                  return HeapTupleInvisible;        /* updated before scan
                                                   * started */
          }
!         else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_INVALID;    /* aborted */
              return HeapTupleInvisible;
          }
***************
*** 450,469 ****
          return HeapTupleUpdated;    /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return HeapTupleMayBeUpdated;
!         if (CommandIdGEScanCommandId(tuple->t_cmax))
              return HeapTupleSelfUpdated;        /* updated after scan
                                                   * started */
          else
              return HeapTupleInvisible;    /* updated before scan started */
      }

!     if (!TransactionIdDidCommit(tuple->t_xmax))
      {
!         if (TransactionIdDidAbort(tuple->t_xmax))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
              return HeapTupleMayBeUpdated;
--- 450,469 ----
          return HeapTupleUpdated;    /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return HeapTupleMayBeUpdated;
!         if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
              return HeapTupleSelfUpdated;        /* updated after scan
                                                   * started */
          else
              return HeapTupleInvisible;    /* updated before scan started */
      }

!     if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
      {
!         if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
              return HeapTupleMayBeUpdated;
***************
*** 514,524 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return false;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 514,524 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 528,538 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return false;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 528,538 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 541,566 ****
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
          {
              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;

              return false;
          }
!         else if (!TransactionIdDidCommit(tuple->t_xmin))
          {
!             if (TransactionIdDidAbort(tuple->t_xmin))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return false;
              }
!             SnapshotDirty->xmin = tuple->t_xmin;
              /* XXX shouldn't we fall through to look at xmax? */
              return true;        /* in insertion by other */
          }
--- 541,566 ----
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
          {
              if (tuple->t_infomask & HEAP_XMAX_INVALID)    /* xid invalid */
                  return true;

!             Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return true;

              return false;
          }
!         else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return false;
              }
!             SnapshotDirty->xmin = HeapTupleHeaderGetXmin(tuple);
              /* XXX shouldn't we fall through to look at xmax? */
              return true;        /* in insertion by other */
          }
***************
*** 581,602 ****
          return false;            /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return true;
          return false;
      }

!     if (!TransactionIdDidCommit(tuple->t_xmax))
      {
!         if (TransactionIdDidAbort(tuple->t_xmax))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
              return true;
          }
          /* running xact */
!         SnapshotDirty->xmax = tuple->t_xmax;
          return true;            /* in updation by other */
      }

--- 581,602 ----
          return false;            /* updated by other */
      }

!     if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
      {
          if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
              return true;
          return false;
      }

!     if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
      {
!         if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;        /* aborted */
              return true;
          }
          /* running xact */
!         SnapshotDirty->xmax = HeapTupleHeaderGetXmax(tuple);
          return true;            /* in updation by other */
      }

***************
*** 648,658 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return false;
!             if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 648,658 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 662,672 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
              {
!                 if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                      return false;
!                 if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 662,672 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 675,701 ****
                  }
              }
          }
!         else 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 */
          }
!         else if (!TransactionIdDidCommit(tuple->t_xmin))
          {
!             if (TransactionIdDidAbort(tuple->t_xmin))
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
              return false;
          }
--- 675,701 ----
                  }
              }
          }
!         else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmin(tuple)))
                  return false;    /* inserted after scan started */

              if (tuple->t_infomask & HEAP_XMAX_INVALID)    /* xid invalid */
                  return true;

!             Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));

              if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
                  return true;

!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
                  return true;    /* deleted after scan started */
              else
                  return false;    /* deleted before scan started */
          }
!         else if (!TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
              return false;
          }
***************
*** 707,721 ****
       * By here, the inserting transaction has committed - have to check
       * when...
       */
!     if (TransactionIdFollowsOrEquals(tuple->t_xmin, snapshot->xmin))
      {
          uint32        i;

!         if (TransactionIdFollowsOrEquals(tuple->t_xmin, snapshot->xmax))
              return false;
          for (i = 0; i < snapshot->xcnt; i++)
          {
!             if (TransactionIdEquals(tuple->t_xmin, snapshot->xip[i]))
                  return false;
          }
      }
--- 707,725 ----
       * By here, the inserting transaction has committed - have to check
       * when...
       */
!     if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple),
!                                      snapshot->xmin))
      {
          uint32        i;

!         if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple),
!                                          snapshot->xmax))
              return false;
+
          for (i = 0; i < snapshot->xcnt; i++)
          {
!             if (TransactionIdEquals(HeapTupleHeaderGetXmin(tuple),
!                                     snapshot->xip[i]))
                  return false;
          }
      }
***************
*** 728,744 ****

      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;
          }
--- 732,748 ----

      if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
      {
!         if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
          {
!             if (CommandIdGEScanCommandId(HeapTupleHeaderGetCmax(tuple)))
                  return true;    /* deleted after scan started */
              else
                  return false;    /* deleted before scan started */
          }

!         if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
          {
!             if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
                  tuple->t_infomask |= HEAP_XMAX_INVALID; /* aborted */
              return true;
          }
***************
*** 750,764 ****
      /*
       * OK, the deleting transaction committed too ... but when?
       */
!     if (TransactionIdFollowsOrEquals(tuple->t_xmax, snapshot->xmin))
      {
          uint32        i;

!         if (TransactionIdFollowsOrEquals(tuple->t_xmax, snapshot->xmax))
              return true;
          for (i = 0; i < snapshot->xcnt; i++)
          {
!             if (TransactionIdEquals(tuple->t_xmax, snapshot->xip[i]))
                  return true;
          }
      }
--- 754,769 ----
      /*
       * OK, the deleting transaction committed too ... but when?
       */
!     if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple), snapshot->xmin))
      {
          uint32        i;

!         if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple),
!                                          snapshot->xmax))
              return true;
          for (i = 0; i < snapshot->xcnt; i++)
          {
!             if (TransactionIdEquals(HeapTupleHeaderGetXmax(tuple), snapshot->xip[i]))
                  return true;
          }
      }
***************
*** 801,811 ****
              return HEAPTUPLE_DEAD;
          else if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return HEAPTUPLE_DEAD;
--- 806,816 ----
              return HEAPTUPLE_DEAD;
          else if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return HEAPTUPLE_DEAD;
***************
*** 814,824 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
              else
              {
--- 819,829 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
              else
              {
***************
*** 826,836 ****
                  return HEAPTUPLE_DEAD;
              }
          }
!         else if (TransactionIdIsInProgress(tuple->t_xmin))
              return HEAPTUPLE_INSERT_IN_PROGRESS;
!         else if (TransactionIdDidCommit(tuple->t_xmin))
              tuple->t_infomask |= HEAP_XMIN_COMMITTED;
!         else if (TransactionIdDidAbort(tuple->t_xmin))
          {
              tuple->t_infomask |= HEAP_XMIN_INVALID;
              return HEAPTUPLE_DEAD;
--- 831,841 ----
                  return HEAPTUPLE_DEAD;
              }
          }
!         else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
              return HEAPTUPLE_INSERT_IN_PROGRESS;
!         else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
              tuple->t_infomask |= HEAP_XMIN_COMMITTED;
!         else if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
          {
              tuple->t_infomask |= HEAP_XMIN_INVALID;
              return HEAPTUPLE_DEAD;
***************
*** 865,873 ****
           */
          if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
          {
!             if (TransactionIdIsInProgress(tuple->t_xmax))
                  return HEAPTUPLE_LIVE;
!             if (TransactionIdDidCommit(tuple->t_xmax))
                  tuple->t_infomask |= HEAP_XMAX_COMMITTED;
              else                /* it's either aborted or crashed */
                  tuple->t_infomask |= HEAP_XMAX_INVALID;
--- 870,878 ----
           */
          if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
          {
!             if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
                  return HEAPTUPLE_LIVE;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
                  tuple->t_infomask |= HEAP_XMAX_COMMITTED;
              else                /* it's either aborted or crashed */
                  tuple->t_infomask |= HEAP_XMAX_INVALID;
***************
*** 877,887 ****

      if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
      {
!         if (TransactionIdIsInProgress(tuple->t_xmax))
              return HEAPTUPLE_DELETE_IN_PROGRESS;
!         else if (TransactionIdDidCommit(tuple->t_xmax))
              tuple->t_infomask |= HEAP_XMAX_COMMITTED;
!         else if (TransactionIdDidAbort(tuple->t_xmax))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;
              return HEAPTUPLE_LIVE;
--- 882,892 ----

      if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
      {
!         if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
              return HEAPTUPLE_DELETE_IN_PROGRESS;
!         else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
              tuple->t_infomask |= HEAP_XMAX_COMMITTED;
!         else if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
          {
              tuple->t_infomask |= HEAP_XMAX_INVALID;
              return HEAPTUPLE_LIVE;
***************
*** 903,909 ****
       * Deleter committed, but check special cases.
       */

!     if (TransactionIdEquals(tuple->t_xmin, tuple->t_xmax))
      {
          /*
           * inserter also deleted it, so it was never visible to anyone
--- 908,915 ----
       * Deleter committed, but check special cases.
       */

!     if (TransactionIdEquals(HeapTupleHeaderGetXmin(tuple),
!                             HeapTupleHeaderGetXmax(tuple)))
      {
          /*
           * inserter also deleted it, so it was never visible to anyone
***************
*** 912,918 ****
          return HEAPTUPLE_DEAD;
      }

!     if (!TransactionIdPrecedes(tuple->t_xmax, OldestXmin))
      {
          /* deleting xact is too recent, tuple could still be visible */
          return HEAPTUPLE_RECENTLY_DEAD;
--- 918,924 ----
          return HEAPTUPLE_DEAD;
      }

!     if (!TransactionIdPrecedes(HeapTupleHeaderGetXmax(tuple), OldestXmin))
      {
          /* deleting xact is too recent, tuple could still be visible */
          return HEAPTUPLE_RECENTLY_DEAD;
diff -c -r ../orig/src/include/access/htup.h src/include/access/htup.h
*** ../orig/src/include/access/htup.h    Sat May 11 14:22:41 2002
--- src/include/access/htup.h    Sat May 11 18:25:11 2002
***************
*** 16,21 ****
--- 16,22 ----

  #include "storage/bufpage.h"
  #include "storage/relfilenode.h"
+ #include "access/transam.h"

  #define MinHeapTupleBitmapLen    1    /* in bytes, must be 2**n */

***************
*** 66,71 ****
--- 67,152 ----
  typedef HeapTupleHeaderData *HeapTupleHeader;

  /*
+  * information stored in t_infomask:
+  */
+ #define HEAP_HASNULL            0x0001    /* has null attribute(s) */
+ #define HEAP_HASVARLENA            0x0002    /* has variable length
+                                          * attribute(s) */
+ #define HEAP_HASEXTERNAL        0x0004    /* has external stored
+                                          * attribute(s) */
+ #define HEAP_HASCOMPRESSED        0x0008    /* has compressed stored
+                                          * attribute(s) */
+ #define HEAP_HASEXTENDED        0x000C    /* the two above combined */
+
+ #define HEAP_XMAX_UNLOGGED        0x0080    /* to lock tuple for update */
+                                         /* without logging */
+ #define HEAP_XMIN_COMMITTED        0x0100    /* t_xmin committed */
+ #define HEAP_XMIN_INVALID        0x0200    /* t_xmin invalid/aborted */
+ #define HEAP_XMAX_COMMITTED        0x0400    /* t_xmax committed */
+ #define HEAP_XMAX_INVALID        0x0800    /* t_xmax invalid/aborted */
+ #define HEAP_MARKED_FOR_UPDATE    0x1000    /* marked for UPDATE */
+ #define HEAP_UPDATED            0x2000    /* this is UPDATEd version of row */
+ #define HEAP_MOVED_OFF            0x4000    /* removed or moved to another
+                                          * place by vacuum */
+ #define HEAP_MOVED_IN            0x8000    /* moved from another place by
+                                          * vacuum */
+
+ #define HEAP_XACT_MASK            0xFFF0    /* */
+
+
+ /* HeapTupleHeader accessor macros */
+
+ #define HeapTupleHeaderGetXmin(tup) \
+     ((tup)->t_xmin)
+
+ #define HeapTupleHeaderGetXmax(tup) \
+     ((tup)->t_xmax)
+
+ /* no AssertMacro, because this is read as a system-defined attribute also */
+ #define HeapTupleHeaderGetCmin(tup) \
+ ( \
+     (tup)->t_cmin \
+ )
+
+ #define HeapTupleHeaderGetCmax(tup) \
+     ((tup)->t_cmax)
+
+ #define HeapTupleHeaderGetXvac(tup) \
+ ( \
+     AssertMacro((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF)), \
+     (TransactionId) (tup)->t_cmin \
+ )
+
+
+ #define HeapTupleHeaderSetXmin(tup, xid) \
+     (TransactionIdStore((xid), &(tup)->t_xmin))
+
+ #define HeapTupleHeaderSetXminInvalid(tup) \
+     (StoreInvalidTransactionId(&(tup)->t_xmin))
+
+ #define HeapTupleHeaderSetXmax(tup, xid) \
+     (TransactionIdStore((xid), &(tup)->t_xmax))
+
+ #define HeapTupleHeaderSetXmaxInvalid(tup) \
+     (StoreInvalidTransactionId(&(tup)->t_xmax))
+
+ #define HeapTupleHeaderSetCmin(tup, cid) \
+ ( \
+     AssertMacro(!((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF))), \
+     (tup)->t_cmin = (cid) \
+ )
+
+ #define HeapTupleHeaderSetCmax(tup, cid) \
+     ((tup)->t_cmax = (cid))
+
+ #define HeapTupleHeaderSetXvac(tup, xid) \
+ ( \
+     AssertMacro((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF)), \
+     TransactionIdStore((xid), (TransactionId *) &((tup)->t_cmin)) \
+ )
+
+
+ /*
   * XLOG allows to store some information in high 4 bits of log
   * record xl_info field
   */
***************
*** 234,265 ****
   */
  #define HeapTupleIsValid(tuple) PointerIsValid(tuple)

- /*
-  * information stored in t_infomask:
-  */
- #define HEAP_HASNULL            0x0001    /* has null attribute(s) */
- #define HEAP_HASVARLENA            0x0002    /* has variable length
-                                          * attribute(s) */
- #define HEAP_HASEXTERNAL        0x0004    /* has external stored */
-  /* attribute(s) */
- #define HEAP_HASCOMPRESSED        0x0008    /* has compressed stored */
-  /* attribute(s) */
- #define HEAP_HASEXTENDED        0x000C    /* the two above combined */
-
- #define HEAP_XMAX_UNLOGGED        0x0080    /* to lock tuple for update */
-  /* without logging */
- #define HEAP_XMIN_COMMITTED        0x0100    /* t_xmin committed */
- #define HEAP_XMIN_INVALID        0x0200    /* t_xmin invalid/aborted */
- #define HEAP_XMAX_COMMITTED        0x0400    /* t_xmax committed */
- #define HEAP_XMAX_INVALID        0x0800    /* t_xmax invalid/aborted */
- #define HEAP_MARKED_FOR_UPDATE    0x1000    /* marked for UPDATE */
- #define HEAP_UPDATED            0x2000    /* this is UPDATEd version of row */
- #define HEAP_MOVED_OFF            0x4000    /* removed or moved to another
-                                          * place by vacuum */
- #define HEAP_MOVED_IN            0x8000    /* moved from another place by
-                                          * vacuum */
-
- #define HEAP_XACT_MASK            0xFFF0    /* */

  #define HeapTupleNoNulls(tuple) \
          (!(((HeapTuple) (tuple))->t_data->t_infomask & HEAP_HASNULL))
--- 315,320 ----
diff -c -r ../orig/src/pl/plperl/plperl.c src/pl/plperl/plperl.c
*** ../orig/src/pl/plperl/plperl.c    Sun May  5 02:03:29 2002
--- src/pl/plperl/plperl.c    Sun May 12 00:53:20 2002
***************
*** 552,559 ****
           * This is needed because CREATE OR REPLACE FUNCTION can modify the
           * function's pg_proc entry without changing its OID.
           ************************************************************/
!         uptodate = (prodesc->fn_xmin == procTup->t_data->t_xmin &&
!                     prodesc->fn_cmin == procTup->t_data->t_cmin);

          if (!uptodate)
          {
--- 552,559 ----
           * This is needed because CREATE OR REPLACE FUNCTION can modify the
           * function's pg_proc entry without changing its OID.
           ************************************************************/
!         uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
!                     prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));

          if (!uptodate)
          {
***************
*** 586,593 ****
              elog(ERROR, "plperl: out of memory");
          MemSet(prodesc, 0, sizeof(plperl_proc_desc));
          prodesc->proname = strdup(internal_proname);
!         prodesc->fn_xmin = procTup->t_data->t_xmin;
!         prodesc->fn_cmin = procTup->t_data->t_cmin;

          /************************************************************
           * Lookup the pg_language tuple by Oid
--- 586,593 ----
              elog(ERROR, "plperl: out of memory");
          MemSet(prodesc, 0, sizeof(plperl_proc_desc));
          prodesc->proname = strdup(internal_proname);
!         prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
!         prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);

          /************************************************************
           * Lookup the pg_language tuple by Oid
diff -c -r ../orig/src/pl/plpgsql/src/pl_comp.c src/pl/plpgsql/src/pl_comp.c
*** ../orig/src/pl/plpgsql/src/pl_comp.c    Fri May  3 02:32:18 2002
--- src/pl/plpgsql/src/pl_comp.c    Sun May 12 00:54:11 2002
***************
*** 188,195 ****

      function->fn_name = strdup(NameStr(procStruct->proname));
      function->fn_oid = fn_oid;
!     function->fn_xmin = procTup->t_data->t_xmin;
!     function->fn_cmin = procTup->t_data->t_cmin;
      function->fn_functype = functype;

      switch (functype)
--- 188,195 ----

      function->fn_name = strdup(NameStr(procStruct->proname));
      function->fn_oid = fn_oid;
!     function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
!     function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
      function->fn_functype = functype;

      switch (functype)
diff -c -r ../orig/src/pl/plpgsql/src/pl_handler.c src/pl/plpgsql/src/pl_handler.c
*** ../orig/src/pl/plpgsql/src/pl_handler.c    Thu Oct 25 07:50:20 2001
--- src/pl/plpgsql/src/pl_handler.c    Sat May 11 16:23:10 2002
***************
*** 167,174 ****
          elog(ERROR, "plpgsql: cache lookup for proc %u failed",
               func->fn_oid);

!     result = (func->fn_xmin == procTup->t_data->t_xmin &&
!               func->fn_cmin == procTup->t_data->t_cmin);

      ReleaseSysCache(procTup);

--- 167,174 ----
          elog(ERROR, "plpgsql: cache lookup for proc %u failed",
               func->fn_oid);

!     result = (func->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
!               func->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));

      ReleaseSysCache(procTup);

diff -c -r ../orig/src/pl/plpython/plpython.c src/pl/plpython/plpython.c
*** ../orig/src/pl/plpython/plpython.c    Fri Mar 29 20:06:27 2002
--- src/pl/plpython/plpython.c    Sat May 11 16:25:25 2002
***************
*** 1030,1037 ****
          if (proc->me != plproc)
              elog(FATAL, "plpython: Aiieee, proc->me != plproc");
          /* did we find an up-to-date cache entry? */
!         if (proc->fn_xmin != procTup->t_data->t_xmin ||
!             proc->fn_cmin != procTup->t_data->t_cmin)
          {
              Py_DECREF(plproc);
              proc = NULL;
--- 1030,1037 ----
          if (proc->me != plproc)
              elog(FATAL, "plpython: Aiieee, proc->me != plproc");
          /* did we find an up-to-date cache entry? */
!         if (proc->fn_xmin != HeapTupleHeaderGetXmin(procTup->t_data) ||
!             proc->fn_cmin != HeapTupleHeaderGetCmin(procTup->t_data))
          {
              Py_DECREF(plproc);
              proc = NULL;
***************
*** 1075,1082 ****
      proc = PLy_malloc(sizeof(PLyProcedure));
      proc->proname = PLy_malloc(strlen(procName) + 1);
      strcpy(proc->proname, procName);
!     proc->fn_xmin = procTup->t_data->t_xmin;
!     proc->fn_cmin = procTup->t_data->t_cmin;
      PLy_typeinfo_init(&proc->result);
      for (i = 0; i < FUNC_MAX_ARGS; i++)
          PLy_typeinfo_init(&proc->args[i]);
--- 1075,1082 ----
      proc = PLy_malloc(sizeof(PLyProcedure));
      proc->proname = PLy_malloc(strlen(procName) + 1);
      strcpy(proc->proname, procName);
!     proc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
!     proc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
      PLy_typeinfo_init(&proc->result);
      for (i = 0; i < FUNC_MAX_ARGS; i++)
          PLy_typeinfo_init(&proc->args[i]);
diff -c -r ../orig/src/pl/tcl/pltcl.c src/pl/tcl/pltcl.c
*** ../orig/src/pl/tcl/pltcl.c    Fri Mar 29 20:06:28 2002
--- src/pl/tcl/pltcl.c    Sat May 11 16:28:51 2002
***************
*** 985,992 ****

          prodesc = (pltcl_proc_desc *) Tcl_GetHashValue(hashent);

!         uptodate = (prodesc->fn_xmin == procTup->t_data->t_xmin &&
!                     prodesc->fn_cmin == procTup->t_data->t_cmin);

          if (!uptodate)
          {
--- 985,992 ----

          prodesc = (pltcl_proc_desc *) Tcl_GetHashValue(hashent);

!         uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
!                     prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));

          if (!uptodate)
          {
***************
*** 1023,1030 ****
              elog(ERROR, "pltcl: out of memory");
          MemSet(prodesc, 0, sizeof(pltcl_proc_desc));
          prodesc->proname = strdup(internal_proname);
!         prodesc->fn_xmin = procTup->t_data->t_xmin;
!         prodesc->fn_cmin = procTup->t_data->t_cmin;

          /************************************************************
           * Lookup the pg_language tuple by Oid
--- 1023,1030 ----
              elog(ERROR, "pltcl: out of memory");
          MemSet(prodesc, 0, sizeof(pltcl_proc_desc));
          prodesc->proname = strdup(internal_proname);
!         prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
!         prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);

          /************************************************************
           * Lookup the pg_language tuple by Oid

pgsql-patches by date:

Previous
From: "Rod Taylor"
Date:
Subject: Re: pg_depend patch
Next
From: Rod Taylor
Date:
Subject: Truncate