From: | Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> |
---|---|
To: | Manfred Koizar <mkoi-pg(at)aon(dot)at> |
Cc: | pgsql-patches(at)postgresql(dot)org |
Subject: | Re: HeapTupleHeader accessor macros |
Date: | 2002-06-14 05:07:01 |
Message-ID: | 200206140507.g5E571l04275@candle.pha.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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(at)postgresql(dot)org)
--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
From | Date | Subject | |
---|---|---|---|
Next Message | Bruce Momjian | 2002-06-14 05:07:49 | Re: Fix disabled triggers with deferred constraints |
Previous Message | Bruce Momjian | 2002-06-14 05:02:38 | Re: boolean options and postmaster documentation |