Re: HeapTupleHeader accessor macros - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: HeapTupleHeader accessor macros
Date
Msg-id 200206140507.g5E571l04275@candle.pha.pa.us
Whole thread Raw
In response to HeapTupleHeader accessor macros  (Manfred Koizar <mkoi-pg@aon.at>)
List pgsql-patches
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

---------------------------------------------------------------------------


Manfred Koizar wrote:
> 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

>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: boolean options and postmaster documentation
Next
From: Bruce Momjian
Date:
Subject: Re: Fix disabled triggers with deferred constraints