head	1.15;
access;
symbols
	release_4_2:1.15
	aix_ok:1.15
	Version_2_1:1.5
	old_buffer_manager:1.3;
locks; strict;
comment	@ * @;


1.15
date	93.07.16.18.43.12;	author avi;	state Exp;
branches;
next	1.14;

1.14
date	93.07.01.22.56.00;	author avi;	state Exp;
branches;
next	1.13;

1.13
date	92.12.29.01.35.49;	author aoki;	state Exp;
branches;
next	1.12;

1.12
date	92.07.13.03.15.48;	author hong;	state Exp;
branches;
next	1.11;

1.11
date	92.05.28.20.20.52;	author mer;	state Exp;
branches;
next	1.10;

1.10
date	92.02.19.01.51.53;	author mer;	state Exp;
branches;
next	1.9;

1.9
date	91.11.08.15.42.23;	author kemnitz;	state Exp;
branches;
next	1.8;

1.8
date	91.08.09.10.21.07;	author mer;	state Exp;
branches;
next	1.7;

1.7
date	91.08.06.12.22.04;	author mer;	state Exp;
branches;
next	1.6;

1.6
date	91.07.22.22.20.47;	author mao;	state Exp;
branches;
next	1.5;

1.5
date	91.02.06.18.17.44;	author cimarron;	state Exp;
branches;
next	1.4;

1.4
date	91.01.18.21.20.24;	author hong;	state Exp;
branches;
next	1.3;

1.3
date	90.09.25.16.18.33;	author kemnitz;	state Exp;
branches;
next	1.2;

1.2
date	90.03.26.20.33.50;	author cimarron;	state Exp;
branches;
next	1.1;

1.1
date	90.03.22.13.02.51;	author cimarron;	state Exp;
branches;
next	;


desc
@new improved transaction access methods support
@


1.15
log
@time cleanup
@
text
@/* ----------------------------------------------------------------
 *   FILE
 *	transsup.c
 *	
 *   DESCRIPTION
 *	postgres transaction access method support code
 *
 *   INTERFACE ROUTINES
 * 	AmiTransactionOverride
 *	CreateTransRelation
 *
 *	TransBlockNumberGetXidStatus
 *	TransBlockNumberSetXidStatus
 *	TransBlockNumberGetCommitTime
 *	TransBlockNumberSetCommitTime
 *	TransGetLastRecordedTransaction
 *
 *   NOTES
 *	This file contains support functions for the high
 *	level access method interface routines found in transam.c
 *
 * ----------------------------------------------------------------
 */

#include "tmp/postgres.h"

 RcsId("$Header: /private/src/postgres/src/backend/access/transam/RCS/transsup.c,v 1.14 1993/07/01 22:56:00 avi Exp avi $");

#include "machine.h"		/* in port/ directory (needed for BLCKSZ) */

#include "storage/buf.h"
#include "storage/bufmgr.h"

#include "utils/rel.h"
#include "utils/log.h"
#include "utils/memutils.h"
#include "utils/nabstime.h"

#include "access/transam.h"

#include "storage/smgr.h"

/* ----------------------------------------------------------------
 *		      general support routines
 * ----------------------------------------------------------------
 */
    
/* --------------------------------
 *	AmiTransactionOverride
 *
 *	This function is used to manipulate the bootstrap flag.
 * --------------------------------
 */
void
AmiTransactionOverride(flag)
    bool flag;
{
    AMI_OVERRIDE = flag;
}

/* --------------------
 *	CreateTransRelation
 *
 *	This function does the work of creating the given specified
 *	relation using a dummy schema.  DummyAttributeTupleForm is
 *	actually a macro in lib/H/catalog/pg_attribute.h.
 * --------------------
 */

AttributeTupleFormData    DummyAtt1 = DummyAttributeTupleForm;
AttributeTupleForm	  DummyTupleDescriptor[ 1 ] = { &DummyAtt1 };

void
CreateTransRelation(name)
    Name name;			/* relation name */
{
    heap_create(name, 'n', 1, DEFAULT_SMGR, DummyTupleDescriptor);
}

/* --------------------------------
 *	TransComputeBlockNumber
 * --------------------------------
 */
void
TransComputeBlockNumber(relation, transactionId, blockNumberOutP)
    Relation	  		relation; 	/* relation to test */
    TransactionId 		transactionId; 	/* transaction id to test */
    BlockNumber			*blockNumberOutP;
{
    long	itemsPerBlock;
    
    /* ----------------
     *  we calculate the block number of our transaction
     *  by dividing the transaction id by the number of
     *  transaction things per block.  
     * ----------------
     */
    if (relation == LogRelation)
	itemsPerBlock = TP_NumXidStatusPerBlock;
    else if (relation == TimeRelation)
	itemsPerBlock = TP_NumTimePerBlock;
    else
	elog(WARN, "TransComputeBlockNumber: unknown relation");
    
    /* ----------------
     *	warning! if the transaction id's get too large
     *  then a BlockNumber may not be large enough to hold the results
     *  of our division.
     *
     *	XXX  this will all vanish soon when we implement an improved
     *       transaction id schema -cim 3/23/90
     *
     *  This has vanished now that xid's are 4 bytes (no longer 5).
     *  -mer 5/24/92
     * ----------------
     */
    (*blockNumberOutP) = transactionId / itemsPerBlock;
}


/* ----------------------------------------------------------------
 *		     trans block support routines
 * ----------------------------------------------------------------
 */
  
/* --------------------------------
 *	TransBlockGetLastTransactionIdStatus
 *
 *	This returns the status and transaction id of the last
 *	transaction information recorded on the given TransBlock.
 * --------------------------------
 */

XidStatus
TransBlockGetLastTransactionIdStatus(tblock, baseXid, returnXidP)
    Pointer		tblock;
    TransactionId	baseXid;
    TransactionId	*returnXidP;  /* RETURN */
{
    Index         index;
    Index         maxIndex;
    bits8         bit1;
    bits8	  bit2;
    BitIndex      offset;
    TransactionId TTupXid;
    XidStatus     xstatus;

    /* ----------------
     *	sanity check
     * ----------------
     */
    Assert((tblock != NULL));

    /* ----------------
     *	search downward from the top of the block data, looking
     *  for the first Non-in progress transaction status.  Since we
     *  are scanning backward, this will be last recorded transaction
     *  status on the block.
     * ----------------
     */
    maxIndex = TP_NumXidStatusPerBlock;
    for (index = maxIndex-1; index>=0; index--) {
	offset =  BitIndexOf(index);
	bit1 =    ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
	bit2 =    (bits8)  BitArrayBitIsSet((BitArray) tblock, offset);
	
	xstatus =  (bit1 | bit2) ;

	/* ----------------
	 *  here we have the status of some transaction, so test
	 *  if the status is recorded as "in progress".  If so, then
	 *  we save the transaction id in the place specified by the caller.
	 * ----------------
	 */
	if (xstatus != XID_INPROGRESS) {
	    if (returnXidP != NULL) {
		TransactionIdStore(baseXid, returnXidP);
		TransactionIdAdd(returnXidP, index);
	    }
	    break;
	}
    }

    /* ----------------
     *	if we get here and index is 0 it means we couldn't find
     *  a non-inprogress transaction on the block.  For now we just
     *  return this info to the user.  They can check if the return
     *  status is "in progress" to know this condition has arisen.
     * ----------------
     */
    if (index == 0) {
	if (returnXidP != NULL)
	    TransactionIdStore(baseXid, returnXidP);
    }

    /* ----------------
     *	return the status to the user
     * ----------------
     */
    return xstatus;
}

/* --------------------------------
 *	TransBlockGetXidStatus
 *
 *	This returns the status of the desired transaction
 * --------------------------------
 */

XidStatus
TransBlockGetXidStatus(tblock, transactionId)
    Pointer		tblock;
    TransactionId	transactionId;
{
    TransactionIdValueData	xidv;
    TransactionIdValueData 	itemsPerBlock;
    TransactionIdValueData 	result;
    Index       		index;
    bits8       		bit1;
    bits8			bit2;
    BitIndex    		offset;

    /* ----------------
     *	sanity check
     * ----------------
     */
    if (tblock == NULL) {
	return XID_INVALID;
    }

    /* ----------------
     *	calculate the index into the transaction data where
     *  our transaction status is located
     *
     *  XXX this will be replaced soon when we move to the
     *      new transaction id scheme -cim 3/23/90
     *
     *  The old system has now been replaced. -mer 5/24/92
     * ----------------
     */
    index = transactionId % TP_NumXidStatusPerBlock;
   
    /* ----------------
     *	get the data at the specified index
     * ----------------
     */
    offset =    BitIndexOf(index);
    bit1 =      ((bits8)   BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
    bit2 =      (bits8)    BitArrayBitIsSet((BitArray) tblock, offset);
    
    /* ----------------
     *	return the transaction status to the caller
     * ----------------
     */
    return (XidStatus)
	(bit1 | bit2);
}

/* --------------------------------
 *	TransBlockSetXidStatus
 *
 *	This sets the status of the desired transaction
 * --------------------------------
 */

void
TransBlockSetXidStatus(tblock, transactionId, xstatus)
    Pointer		tblock;
    TransactionId	transactionId;
    XidStatus 		xstatus;
{
    TransactionIdValueData	xidv;
    Index       		index;
    BitIndex    		offset;
    TransactionIdValueData 	itemsPerBlock;
    TransactionIdValueData 	result;
    
    /* ----------------
     *	sanity check
     * ----------------
     */
    if (tblock == NULL)
	return;
    
    /* ----------------
     *	calculate the index into the transaction data where
     *  we sould store our transaction status.
     *
     *  XXX this will be replaced soon when we move to the
     *      new transaction id scheme -cim 3/23/90
     *
     *  The new scheme is here -mer 5/24/92
     * ----------------
     */
    index = transactionId % TP_NumXidStatusPerBlock;
    
    offset =    BitIndexOf(index);
    
    /* ----------------
     *	store the transaction value at the specified offset
     * ----------------
     */
    switch(xstatus) {
    case XID_COMMIT:             /* set 10 */
	BitArraySetBit((BitArray) tblock, offset);
	BitArrayClearBit((BitArray) tblock, offset + 1);
	break;
    case XID_ABORT:             /* set 01 */
	BitArrayClearBit((BitArray) tblock, offset);
	BitArraySetBit((BitArray) tblock, offset + 1);
	break;
    case XID_INPROGRESS:        /* set 00 */
	BitArrayClearBit((BitArray) tblock, offset);
	BitArrayClearBit((BitArray) tblock, offset + 1);
	break;
    default:
	elog(NOTICE,
	     "TransBlockSetXidStatus: invalid status: %d (ignored)",
	     xstatus);
	break;
    }
}

/* --------------------------------
 *	TransBlockGetCommitTime
 *
 *	This returns the transaction commit time for the
 *	specified transaction id in the trans block.
 * --------------------------------
 */

AbsoluteTime
TransBlockGetCommitTime(tblock, transactionId)
    Pointer		tblock;
    TransactionId	transactionId;
{
    Index			index;
    AbsoluteTime		*timeArray;
    
    /* ----------------
     *	sanity check
     * ----------------
     */
    if (tblock == NULL)
	return INVALID_ABSTIME;
    
    /* ----------------
     *	calculate the index into the transaction data where
     *  our transaction commit time is located
     *
     *  XXX this will be replaced soon when we move to the
     *      new transaction id scheme -cim 3/23/90
     *
     *  The new scheme is here. -mer 5/24/92
     * ----------------
     */
    index = transactionId % TP_NumTimePerBlock;
    
    /* ----------------
     *	return the commit time to the caller
     * ----------------
     */
    timeArray =  (AbsoluteTime *) tblock;
    return (AbsoluteTime)
	timeArray[ index ];
}

/* --------------------------------
 *	TransBlockSetCommitTime
 *
 *	This sets the commit time of the specified transaction
 * --------------------------------
 */

void
TransBlockSetCommitTime(tblock, transactionId, commitTime)
    Pointer		tblock;
    TransactionId	transactionId;
    AbsoluteTime	commitTime;
{
    Index		index;
    AbsoluteTime	*timeArray;
    
    /* ----------------
     *	sanity check
     * ----------------
     */
    if (tblock == NULL)
	return;

    
    /* ----------------
     *	calculate the index into the transaction data where
     *  we sould store our transaction status.  
     *
     *  XXX this will be replaced soon when we move to the
     *      new transaction id scheme -cim 3/23/90
     *
     *  The new scheme is here.  -mer 5/24/92
     * ----------------
     */
    index = transactionId % TP_NumTimePerBlock;

    /* ----------------
     *	store the transaction commit time at the specified index
     * ----------------
     */
    timeArray =  (AbsoluteTime *) tblock;
    timeArray[ index ] = commitTime;
}

/* ----------------------------------------------------------------
 *	           transam i/o support routines
 * ----------------------------------------------------------------
 */

/* --------------------------------
 *	TransBlockNumberGetXidStatus
 * --------------------------------
 */
XidStatus
TransBlockNumberGetXidStatus(relation, blockNumber, xid, failP)
    Relation		relation;
    BlockNumber	   	blockNumber;
    TransactionId	xid;
    bool		*failP;
{
    Buffer	   	buffer;		/* buffer associated with block */
    Block		block;		/* block containing xstatus */
    XidStatus		xstatus;	/* recorded status of xid */
    bool		localfail;      /* bool used if failP = NULL */

    /* ----------------
     *	SOMEDAY place a read lock on the log relation
     *  That someday is today 5 Aug 1991 -mer
     * ----------------
     */
    RelationSetLockForRead(relation);

    /* ----------------
     *	get the page containing the transaction information
     * ----------------
     */
    buffer = 	   ReadBuffer(relation, blockNumber);
    block =   	   BufferGetBlock(buffer);

    /* ----------------
     *	get the status from the block.  note, for now we always
     *  return false in failP.
     * ----------------
     */
    if (failP == NULL)
	failP = &localfail;
    (*failP) = false;

    xstatus = TransBlockGetXidStatus(block, xid);

    /* ----------------
     *	release the buffer and return the status
     * ----------------
     */
    ReleaseBuffer(buffer);

    /* ----------------
     *	SOMEDAY release our lock on the log relation
     * ----------------
     */
    RelationUnsetLockForRead(relation);

    return
	xstatus;
}

/* --------------------------------
 *	TransBlockNumberSetXidStatus
 * --------------------------------
 */
void
TransBlockNumberSetXidStatus(relation, blockNumber, xid, xstatus, failP)
    Relation		relation;
    BlockNumber	  	blockNumber;
    TransactionId	xid;
    XidStatus		xstatus;
    bool		*failP;
{
    Buffer	   	buffer;		/* buffer associated with block */
    Block		block;		/* block containing xstatus */
    bool		localfail;      /* bool used if failP = NULL */
    
    /* ----------------
     *	SOMEDAY gain exclusive access to the log relation
     *
     *  That someday is today 5 Aug 1991 -mer
     * ----------------
     */
    RelationSetLockForWrite(relation);

    /* ----------------
     *	get the block containing the transaction status
     * ----------------
     */
    buffer = 	ReadBuffer(relation, blockNumber);
    block =   	BufferGetBlock(buffer);
    
    /* ----------------
     *	attempt to update the status of the transaction on the block.
     *  if we are successful, write the block. otherwise release the buffer.
     *  note, for now we always return false in failP.
     * ----------------
     */
    if (failP == NULL)
	failP = &localfail;
    (*failP) = false;
    
    TransBlockSetXidStatus(block, xid, xstatus);

    if ((*failP) == false)
	WriteBuffer(buffer);
    else
	ReleaseBuffer(buffer);

    /* ----------------
     *	SOMEDAY release our lock on the log relation
     * ----------------
     */    
    RelationUnsetLockForWrite(relation);
}

/* --------------------------------
 *	TransBlockNumberGetCommitTime
 * --------------------------------
 */
AbsoluteTime
TransBlockNumberGetCommitTime(relation, blockNumber, xid, failP)
    Relation		relation;
    BlockNumber	   	blockNumber;
    TransactionId	xid;
    bool		*failP;
{
    Buffer	   	buffer;		/* buffer associated with block */
    Block		block;		/* block containing commit time */
    bool		localfail;      /* bool used if failP = NULL */
    AbsoluteTime	xtime;		/* commit time */
    
    /* ----------------
     *	SOMEDAY place a read lock on the time relation
     *
     *  That someday is today 5 Aug. 1991 -mer
     * ----------------
     */
    RelationSetLockForRead(relation);
    
    /* ----------------
     *	get the block containing the transaction information
     * ----------------
     */
    buffer = 		ReadBuffer(relation, blockNumber);
    block =   		BufferGetBlock(buffer);

    /* ----------------
     *	get the commit time from the block
     *  note, for now we always return false in failP.
     * ----------------
     */
    if (failP == NULL)
	failP = &localfail;
    (*failP) == false;
    
    xtime = TransBlockGetCommitTime(block, xid);

    /* ----------------
     *	release the buffer and return the commit time
     * ----------------
     */
    ReleaseBuffer(buffer);
    
    /* ----------------
     *	SOMEDAY release our lock on the time relation
     * ----------------
     */
    RelationUnsetLockForRead(relation);

    if ((*failP) == false)
	return xtime;
    else
	return INVALID_ABSTIME;

}

/* --------------------------------
 *	TransBlockNumberSetCommitTime
 * --------------------------------
 */
void
TransBlockNumberSetCommitTime(relation, blockNumber, xid, xtime, failP)
    Relation		relation;
    BlockNumber	  	blockNumber;
    TransactionId	xid;
    AbsoluteTime	xtime;
    bool		*failP;
{
    Buffer	   	buffer;		/* buffer associated with block */
    Block		block;		/* block containing commit time */
    bool		localfail;      /* bool used if failP = NULL */

    /* ----------------
     *	SOMEDAY gain exclusive access to the time relation
     *
     *  That someday is today 5 Aug. 1991 -mer
     * ----------------
     */
    RelationSetLockForWrite(relation);
    
    /* ----------------
     *	get the block containing our commit time
     * ----------------
     */
    buffer = 	   ReadBuffer(relation, blockNumber);
    block =   	   BufferGetBlock(buffer);

    /* ----------------
     *	attempt to update the commit time of the transaction on the block.
     *  if we are successful, write the block. otherwise release the buffer.
     *  note, for now we always return false in failP.
     * ----------------
     */
    if (failP == NULL)
	failP = &localfail;
    (*failP) = false;
    
    TransBlockSetCommitTime(block, xid, xtime);

    if ((*failP) == false)
	WriteBuffer(buffer);
    else
	ReleaseBuffer(buffer);
    
    /* ----------------
     *	SOMEDAY release our lock on the time relation
     * ----------------
     */
    RelationUnsetLockForWrite(relation);

}

/* --------------------------------
 *	TransGetLastRecordedTransaction
 * --------------------------------
 */
void
TransGetLastRecordedTransaction(relation, xid, failP)
    Relation		relation;
    TransactionId	xid;		/* return: transaction id */
    bool		*failP;
{
    BlockNumber	  	blockNumber;	/* block number */
    Buffer	   	buffer;		/* buffer associated with block */
    Block		block;		/* block containing xid status */
    BlockNumber		n;		/* number of blocks in the relation */
    TransactionId	baseXid;
    
    (*failP) = false;

    /* ----------------
     *	SOMEDAY gain exclusive access to the log relation
     *
     *  That someday is today 5 Aug. 1991 -mer
     *  It looks to me like we only need to set a read lock here, despite
     *  the above comment about exclusive access.  The block is never 
     *  actually written into, we only check status bits.
     * ----------------
     */
    RelationSetLockForRead(relation);
    
    /* ----------------
     *	we assume the last block of the log contains the last
     *  recorded transaction.  If the relation is empty we return
     *  failure to the user.
     * ----------------
     */
    n = RelationGetNumberOfBlocks(relation);
    if (n == 0) {
	(*failP) = true;
	return;
    }

    /* ----------------
     *	get the block containing the transaction information
     * ----------------
     */
    blockNumber =  n-1;
    buffer = 	ReadBuffer(relation, blockNumber);
    block =   	BufferGetBlock(buffer);

    /* ----------------
     *	get the last xid on the block
     * ----------------
     */
    baseXid = blockNumber * TP_NumXidStatusPerBlock;
    
    (void) TransBlockGetLastTransactionIdStatus(block, baseXid, &xid);
    
    ReleaseBuffer(buffer);

    /* ----------------
     *	SOMEDAY release our lock on the log relation
     * ----------------
     */
    RelationUnsetLockForRead(relation);
}
@


1.14
log
@got rid of InvalidTime
@
text
@d27 1
a27 1
 RcsId("$Header: /private/src/postgres/src/backend/access/transam/RCS/transsup.c,v 1.13 1992/12/29 01:35:49 aoki Exp avi $");
d332 1
a332 1
Time
d338 1
a338 1
    Time			*timeArray;
d363 2
a364 2
    timeArray =  (Time *) tblock;
    return (Time)
d379 1
a379 1
    Time 		commitTime;
d381 2
a382 2
    Index			index;
    Time			*timeArray;
d408 1
a408 1
    timeArray =  (Time *) tblock;
d533 1
a533 1
Time
d543 1
a543 1
    Time		xtime;		/* commit time */
d599 1
a599 1
    Time		xtime;
@


1.13
log
@removed reference to ancient .h
@
text
@d27 1
a27 1
 RcsId("$Header: /usr/local/dev/postgres/mastertree/newconf/RCS/transsup.c,v 1.12 1992/07/13 03:15:48 hong Exp $");
d345 1
a345 1
	return InvalidTime;
d586 1
a586 1
	return InvalidTime;
@


1.12
log
@prototyping
@
text
@d27 1
a27 1
 RcsId("$Header: RCS/transsup.c,v 1.11 92/05/28 20:20:52 mer Exp Locker: hong $");
d36 1
a37 1
#include "tmp/bit.h"
@


1.11
log
@Transaction ids are now longs and command ids are now shorts
@
text
@d27 1
a27 1
 RcsId("$Header: /private/mer/pg.latest/src/access/transam/RCS/transsup.c,v 1.10 1992/02/19 01:51:53 mer Exp mer $");
d193 1
a193 1
	    TransactionIdStore(baseXid, (Pointer) returnXidP);
@


1.10
log
@changes for the new abstime implementation
@
text
@a24 2
#include <math.h>

d27 1
a27 1
 RcsId("$Header: /users/mer/pg/src/access/transam/RCS/transsup.c,v 1.9 1991/11/08 15:42:23 kemnitz Exp mer $");
d90 1
a90 2
    TransactionIdValueData	xidv;
    TransactionIdValueData	itemsPerBlock;
d112 3
d117 1
a117 2
    TransactionIdSetTransactionIdValue(transactionId, &xidv);
    (*blockNumberOutP) = xidv / itemsPerBlock;
d135 1
a135 1
TransBlockGetLastTransactionIdStatus(tblock, baseXid, returnXid)
d138 1
a138 1
    TransactionId	returnXid;  /* RETURN */
d176 3
a178 3
	    if (returnXid != NULL) {
		TransactionIdStore(baseXid, (Pointer) returnXid);
		TransactionIdAdd(returnXid, index);
d192 2
a193 2
	if (returnXid != NULL)
	    TransactionIdStore(baseXid, (Pointer) returnXid);
d237 2
d241 1
a241 4
    TransactionIdSetTransactionIdValue(transactionId, &xidv);
    itemsPerBlock = TP_NumXidStatusPerBlock;
    result = xidv - floor(xidv / itemsPerBlock) * itemsPerBlock;
    index = result;
a242 4
    if (index >= TP_NumXidStatusPerBlock) {
	return XID_INVALID;
    }
    
d291 2
d295 1
a295 4
    TransactionIdSetTransactionIdValue(transactionId, &xidv);
    itemsPerBlock = TP_NumXidStatusPerBlock;
    result = xidv - floor(xidv / itemsPerBlock) * itemsPerBlock;
    index = result;
a296 3
    if (index >= TP_NumXidStatusPerBlock) 
	return;
       
a336 1
    TransactionIdValueData	xidv;
a338 2
    TransactionIdValueData 	itemsPerBlock;
    TransactionIdValueData 	result;
d353 2
d357 1
a357 7
    TransactionIdSetTransactionIdValue(transactionId, &xidv);
    itemsPerBlock = TP_NumTimePerBlock;
    result = xidv - floor(xidv / itemsPerBlock) * itemsPerBlock;
    index = result;
    
    if (index >= TP_NumTimePerBlock)
	return InvalidTime;
a380 1
    TransactionIdValueData	xidv;
a382 2
    TransactionIdValueData 	itemsPerBlock;
    TransactionIdValueData 	result;
d398 2
d402 1
a402 7
    TransactionIdSetTransactionIdValue(transactionId, &xidv);
    itemsPerBlock = TP_NumTimePerBlock;
    result = xidv - floor(xidv / itemsPerBlock) * itemsPerBlock;
    index = result;

    if (index >= TP_NumTimePerBlock)
	return;
d660 1
a660 2
    TransactionIdValueData xidv;	/* arithmetic representation of xid */
    TransactionIdData	baseXid;
d699 1
a699 2
    xidv = blockNumber * TP_NumXidStatusPerBlock;
    TransactionIdValueSetTransactionId(&xidv, &baseXid);
d701 1
a701 1
    (void) TransBlockGetLastTransactionIdStatus(block, &baseXid, xid);
a710 1

@


1.9
log
@fixed prototypes.
@
text
@d29 1
a29 1
 RcsId("$Header: RCS/transsup.c,v 1.8 91/08/09 10:21:07 mer Exp Locker: kemnitz $");
d38 1
@


1.8
log
@bug fix for assignment done with double equals.
@
text
@d29 1
a29 1
 RcsId("$Header: RCS/transsup.c,v 1.7 91/08/06 12:22:04 mer Exp $");
d164 2
a165 2
	bit1 =    ((bits8) BitArrayBitIsSet(tblock, offset++)) << 1;
	bit2 =    (bits8)  BitArrayBitIsSet(tblock, offset);
d177 1
a177 1
		TransactionIdStore(baseXid, returnXid);
d193 1
a193 1
	    TransactionIdStore(baseXid, returnXid);
d253 2
a254 2
    bit1 =      ((bits8)   BitArrayBitIsSet(tblock, offset++)) << 1;
    bit2 =      (bits8)    BitArrayBitIsSet(tblock, offset);
d314 2
a315 2
	BitArraySetBit(tblock, offset);
	BitArrayClearBit(tblock, offset + 1);
d318 2
a319 2
	BitArrayClearBit(tblock, offset);
	BitArraySetBit(tblock, offset + 1);
d322 2
a323 2
	BitArrayClearBit(tblock, offset);
	BitArrayClearBit(tblock, offset + 1);
@


1.7
log
@add synchronization in dealing with system catalogs
@
text
@a21 2
 *   IDENTIFICATION
 *	$Header: RCS/transsup.c,v 1.6 91/07/22 22:20:47 mao Exp Locker: mer $
d29 1
a29 1
 RcsId("$Header: RCS/transsup.c,v 1.6 91/07/22 22:20:47 mao Exp Locker: mer $");
d536 1
a536 1
    (*failP) == false;
@


1.6
log
@jukebox storage manager installation
@
text
@d23 1
a23 1
 *	$Header: /users/mao/postgres/src/access/transam/RCS/transsup.c,v 1.5 1991/02/06 18:17:44 cimarron Exp mao $
d31 1
a31 1
 RcsId("$Header: /users/mao/postgres/src/access/transam/RCS/transsup.c,v 1.5 1991/02/06 18:17:44 cimarron Exp mao $");
d460 1
d463 1
d493 2
d517 2
d521 1
d551 1
d572 2
d576 1
d606 2
d633 2
d637 1
d667 2
d692 5
d699 2
d736 1
@


1.5
log
@preliminary checkin for access method and system cache changes
@
text
@d23 1
a23 1
 *	$Header: RCS/transsup.c,v 1.4 91/01/18 21:20:24 hong Exp Locker: cimarron $
d31 1
a31 1
 RcsId("$Header: RCS/transsup.c,v 1.4 91/01/18 21:20:24 hong Exp Locker: cimarron $");
d44 2
d80 1
a80 1
    heap_create(name, 'n', 1, DummyTupleDescriptor);
@


1.4
log
@for new buffer manager, changed ReadBuffer() interface.
@
text
@d23 1
a23 1
 *	$Header: RCS/transsup.c,v 1.3 90/09/25 16:18:33 kemnitz Exp Locker: hong $
d31 1
a31 1
 RcsId("$Header: RCS/transsup.c,v 1.3 90/09/25 16:18:33 kemnitz Exp Locker: hong $");
d78 1
a78 4
    RelationNameCreateHeapRelation(name,
				   'n',
				   1,
				   DummyTupleDescriptor);
@


1.3
log
@Updating from revision 1.2 to revision 1.4
@
text
@d23 1
a23 1
 *	$Header: RCS/transsup.c,v 1.4 90/09/12 17:54:30 cimarron Exp Locker: cimarron $
d31 1
a31 1
 RcsId("$Header: RCS/transsup.c,v 1.4 90/09/12 17:54:30 cimarron Exp Locker: cimarron $");
d468 1
a468 1
    buffer = 	   ReadBuffer(relation, blockNumber, 0);
d521 1
a521 1
    buffer = 	ReadBuffer(relation, blockNumber, 0);
d572 1
a572 1
    buffer = 		ReadBuffer(relation, blockNumber, 0);
d628 1
a628 1
    buffer = 	   ReadBuffer(relation, blockNumber, 0);
d694 1
a694 1
    buffer = 	ReadBuffer(relation, blockNumber, 0);
@


1.2
log
@*** empty log message ***
@
text
@d23 1
a23 1
 *	$Header: RCS/transsup.c,v 1.1 90/03/22 13:02:51 cimarron Exp $
d27 1
a27 2
#include "transam.h"
 RcsId("$Header: RCS/transsup.c,v 1.1 90/03/22 13:02:51 cimarron Exp $");
d29 15
d66 2
a67 1
 *	relation using a dummy schema.  
d71 2
a72 4
AttributeTupleFormData
    DummyAtt1 = { 0l, "dummy", 28, 0l, 0l, 0l, 5, 1, 0, '\000', '\001' };
AttributeTupleForm
    DummyTupleDescriptor[ 1 ] = { &DummyAtt1 };
@


1.1
log
@Initial revision
@
text
@a10 2
 *	CreateNewTransTuple
 *	TransComputeItemPointer
d12 4
a15 4
 *	TransItemPointerGetXidStatus
 *	TransItemPointerSetXidStatus
 *	TransItemPointerGetCommitTime
 *	TransItemPointerSetCommitTime
d23 1
a23 1
 *	$Header$
d28 1
a28 1
 RcsId("$Header$");
d52 1
a52 1
 *	relation using the TransTuple schema.
d57 1
a57 3
    TransAtt1 = { 0l, "xid", 28, 0l, 0l, 0l,  5, 1, 0, '\000', '\001' };
AttributeTupleFormData
    TransAtt2 = { 0l, "data",   17, 0l, 0l, 0l, -1, 2, 0, '\000', '\001' };
d59 1
a59 1
    TransTupleDescriptor[ TT_NumAttributes ] = { &TransAtt1, &TransAtt2 };
d67 2
a68 2
				   TT_NumAttributes,
				   TransTupleDescriptor);
a70 95
/* --------------------
 *	CreateNewTransTuple
 *
 *	This function is used when we need a new trans tuple on a
 *	new page in the trans relation because no existing page
 *	in the trans relation contains the trans tuple we want --
 *	there is no tuple containing information associated with
 *	the given transaction id in the relation.
 *
 *	This function adds a page to the relation and initializes
 *	the page to contain the needed trans tuple.  An item pointer
 *	to the new trans tuple is returned.
 *
 *   	Notes to minimize confusion:
 *
 *   	VARSIZE is a macro which returns the size field of a varlena object
 *   	VARDATA is a macro which returns the data field of a varlena object
 *
 *	&ttupData[ sizeof(*tuple) ] is the address of the first byte
 *      beyond the tuple header. (tuples are variable length structures)
 * --------------------
 */

ItemPointer	/* location of new trans tuple */
CreateNewTransTuple(relation, id)
    Relation		relation; /* relation */
    TransactionId	id;	  /* base transaction id */
{
    HeapTuple		tuple;
    TransTuple		ttup;
    struct varlena 	*byteArrayP;
    char		ttupData[ TT_HeapTupleSize ];

    /* ----------------
     *	initialize our pointer to the heap tuple header
     * ----------------
     */
    tuple = (HeapTuple) &ttupData[0];

    /* ----------------
     *	initialize our pointer to the first byte in the tuple
     *  past the heap tuple header where the attributes are stored.
     * ----------------
     */
    ttup = (TransTuple) &ttupData[ sizeof(*tuple) ];

    /* ----------------
     *  Now, ttup->xid is the first attribute and ttup->data is
     *  the second.  ttup->data is a variable length attribute.
     *
     *  initialize fields of the heap tuple header.  this is
     *  stolen from the heap code.
     * ----------------
     */
    tuple->t_len = 	   TT_HeapTupleSize;
    tuple->t_lock.l_lock = InvalidRuleLock;
    tuple->t_natts = 	   TT_NumAttributes;
    tuple->t_hoff = 	   sizeof(HeapTupleData);
    tuple->t_bits[0] =     0x3;		/* XXX unportable byte order? */
    tuple->t_bits[1] =     0x0;
    tuple->t_bits[2] =     0x0;
    tuple->t_bits[3] =     0x0;

    /* ----------------
     *    initialize the first (xid) attribute
     * ----------------
     */
    TransactionIdStore(id, &(ttup->xid));

    /* ----------------
     *    initialize the second (data) attribute
     *
     *	  XXX assuming the size of a variable length attribute
     *        being an int32 will change soon when we implement
     *	      arrays and "large attributes".  -cim 3/20/90
     * ----------------
     */
    VARSIZE(&ttup->data) =
	TT_TupleDataSize + sizeof(int32);
	
    bzero(VARDATA(&ttup->data), TT_TupleDataSize);

    /* ----------------
     *    insert tuple in relation and return item pointer.
     *
     *    XXX we have to guarantee that this is appended to
     *	      the relation. -cim 3/20/90
     * ----------------
     */
    (void) RelationInsertHeapTuple(relation, tuple, (double*) NULL);

    return
	(ItemPointer) &(tuple->t_ctid);
}

d72 1
a72 6
 *	TransCacheLookup
 *
 *	This checks the (xid, item pointer) cache to see
 *	if we can avoid going to the buffer manager to get the
 *	heap item pointer associated with the TransTuple containing
 *	the status of xid, thus avoiding a disk I/O.
a74 13

ItemPointer
TransCacheLookup(transactionId, relation)
    TransactionId	transactionId;
    Relation		relation;
{
    return ((ItemPointer) NULL);
}

/* --------------------------------
 *	TransComputeItemPointer
 * --------------------------------
 */
d76 4
a79 4
TransComputeItemPointer(relation, transactionId, iptr)
    Relation	  	relation; 	/* relation to test */
    TransactionId 	transactionId; 	/* transaction id to test */
    ItemPointer		iptr;		/* item pointer to TransTuple */
a80 2
    BlockNumber			block;
    double			result;
d82 1
d91 1
a91 1
	itemsPerPage = TT_NumXidStatusPerTuple;
d93 1
a93 1
	itemsPerPage = TT_NumTimePerTuple;
d95 1
a95 1
	elog(WARN, "TransComputeItemPointer: unknown relation");
d100 4
a103 1
     *  of our division. 
d107 1
a107 8
    result = xidv / itemsPerPage;
    block = result;
    
    /* ----------------
     *	place the computed block number into the given item pointer.
     * ----------------
     */
    ItemPointerSimpleSet(iptr, block, 1);
d112 1
a112 1
 *		     trans tuple support routines
d117 1
a117 1
 *	TransTupleGetLastTransactionIdStatus
d120 1
a120 1
 *	transaction information recorded on the given TransTuple.
d125 4
a128 3
TransTupleGetLastTransactionIdStatus(ttup, transactionId)
    TransTuple		ttup;
    TransactionId	transactionId;  /* RETURN */
a131 1
    BitArray      bitArray;
d136 1
a136 1
    XidStatus     status;
d142 1
a142 1
    Assert((ttup != NULL));
d145 1
a145 9
     *	get the starting transaction id from the trans tuple
     *  and calculate the maximum index into the tuple
     * ----------------
     */
    TTupXid = (TransactionId) &(ttup->xid);
    maxIndex = VARSIZE(&(ttup->data)) * 4;

    /* ----------------
     *	search downward from the top of the tuple data, looking
d148 1
a148 1
     *  status on the tuple.
d151 1
d153 3
a155 5
	offset =    BitIndexOf(index);
	bitArray =  (BitArray) VARDATA(&(ttup->data));

	bit1 =    ((bits8) BitArrayBitIsSet(bitArray, offset++)) << 1;
	bit2 =    (bits8)  BitArrayBitIsSet(bitArray, offset);
d157 1
a157 1
	status =  (bit1 | bit2) ;
d165 4
a168 4
	if (status != XID_INPROGRESS) {
	    if (transactionId != NULL) {
		TransactionIdStore(TTupXid, transactionId);
		TransactionIdAdd(transactionId, index);
d172 1
d174 10
a183 5
	if (index == 0) {
	    if (transactionId != NULL)
		TransactionIdStore(TTupXid, transactionId);
	    break;
	}
d190 1
a190 1
    return status;
d194 1
a194 1
 *	TransTupleGetXidStatus
d201 2
a202 2
TransTupleGetXidStatus(ttup, transactionId, failP)
    TransTuple		ttup;
a203 1
    bool		*failP;
d205 7
a211 6
    Index       index;
    Index       maxIndex;
    BitArray    bitArray;
    bits8       bit1;
    bits8	bit2;
    BitIndex    offset;
a212 2
    (*failP) = false;
    
d217 2
a218 3
    if (ttup == NULL) {
	(*failP) = true;
	return;
d224 3
d229 4
a232 2
    index = IntegerTransactionIdMinus(transactionId, ttup->xid);
    maxIndex = VARSIZE(&(ttup->data)) * 4;
d234 2
a235 3
    if (index >= maxIndex) {
	(*failP) = true;
	return;
d237 1
a237 1
      
d243 3
a245 5
    bitArray =  (BitArray) VARDATA(&(ttup->data));

    bit1 =      ((bits8)   BitArrayBitIsSet(bitArray, offset++)) << 1;
    bit2 =      (bits8)    BitArrayBitIsSet(bitArray, offset);

d255 1
a255 1
 *	TransTupleSetXidStatus
d262 2
a263 2
TransTupleSetXidStatus(ttup, transactionId, status, failP)
    TransTuple		ttup;
d265 1
a265 2
    LogValue 		status;
    bool		*failP;
d267 5
a271 6
    Index       index;
    Index       maxIndex;
    BitArray    bitArray;
    BitIndex    offset;

    (*failP) = false;
d277 1
a277 2
    if (ttup == NULL) {
	(*failP) = true;
d279 1
a279 2
    }

d282 4
a285 1
     *  we sould store our transaction status
d288 6
a293 5
    index = IntegerTransactionIdMinus(transactionId, ttup->xid);
    maxIndex = VARSIZE(&(ttup->data)) * 4;

    if (index >= maxIndex) {
	(*failP) = true;
a294 1
    }
d297 1
a297 2
    bitArray =  (BitArray) VARDATA(&(ttup->data));

d302 1
a302 1
    switch(status) {
d304 2
a305 2
	BitArraySetBit(bitArray, offset);
	BitArrayClearBit(bitArray, offset + 1);
d308 2
a309 2
	BitArrayClearBit(bitArray, offset);
	BitArraySetBit(bitArray, offset + 1);
d312 2
a313 2
	BitArrayClearBit(bitArray, offset);
	BitArrayClearBit(bitArray, offset + 1);
d317 2
a318 3
	     "TransTupleSetXidIdStatus: invalid status: %d (ignored)",
	     status);
	(*failP) = true;
d324 1
a324 1
 *	TransTupleGetTransactionCommitTime
d327 1
a327 1
 *	specified transaction id in the trans tuple.
d332 2
a333 2
TransTupleGetTransactionCommitTime(ttup, transactionId, failP)
    TransTuple		ttup;
a334 1
    bool		*failP;
d336 5
a340 5
    Time	*timeArray;
    Index	index;
    Index       maxIndex;

    (*failP) = false;
d346 3
a348 5
    if (ttup == NULL) {
	(*failP) = true;
	return InvalidCommitTime;
    }

d352 3
d357 8
a364 8
    index = IntegerTransactionIdMinus(transactionId, ttup->xid);
    maxIndex = VARSIZE(&(ttup->data)) / sizeof(Time);
   
    if (index >= maxIndex) {
	(*failP) = true;
	return InvalidCommitTime;
    }

d369 1
a369 1
    timeArray =  (Time *) VARDATA(&(ttup->data));
d375 1
a375 1
 *	TransTupleSetTransactionCommitTime
d382 2
a383 2
TransTupleSetTransactionCommitTime(ttup, transactionId, commitTime, failP)
    TransTuple		ttup;
a385 1
    bool		*failP;
d387 5
a391 5
    Time	*timeArray;
    Index	index;
    Index       maxIndex;

    (*failP) = false;
d397 1
a397 2
    if (ttup == NULL) {
	(*failP) = true;
a398 1
    }
d400 1
d403 4
a406 1
     *  we sould store our transaction status
d409 4
a412 2
    index = IntegerTransactionIdMinus(transactionId, ttup->xid);
    maxIndex = VARSIZE(&(ttup->data)) / sizeof(Time);
d414 1
a414 2
    if (index >= maxIndex) {
	(*failP) = true;
a415 1
    }
d421 1
a421 1
    timeArray =  (Time *) VARDATA(&(ttup->data));
d431 1
a431 1
 *	TransItemPointerGetXidStatus
d435 1
a435 1
TransItemPointerGetXidStatus(relation, iptr, xid, failP)
d437 1
a437 1
    ItemPointer		iptr;
a440 4
    PagePartition   	partition;	/* number partitions on page */
    BlockNumber	   	blockNumber;	/* TransTuple block number */
    PageNumber	  	pageNumber;	/* TransTuple page number */
    OffsetNumber	offsetNumber;	/* item number on page of TransTuple */
d442 2
a443 4
    Page		page;		/* page containing TransTuple */
    ItemId	   	itemId;		/* item id referencing TransTuple */
    Item		ttitem;		/* TransTuple containing xid status */
    XidStatus		xidstatus;	/* recorded status of xid */
d447 1
a447 1
     *	get the block number and stuff from the item pointer
a449 4
    partition =    SinglePagePartition;
    blockNumber =  ItemPointerGetBlockNumber(iptr);
    pageNumber =   ItemPointerGetPageNumber(iptr, partition);
    offsetNumber = ItemPointerGetOffsetNumber(iptr, partition);
d452 1
a452 1
     *	get the page containing the tuple
d455 2
a456 2
    buffer = 	ReadBuffer(relation, blockNumber, 0);
    page =   	BufferGetPageDebug(buffer, pageNumber);
d459 2
a460 1
     *	get the item on the page we want
a462 7
    itemId =    PageGetItemId(page, offsetNumber - 1);
    ttitem =   	PageGetItem(page, itemId);

    /* ----------------
     *	get the status from the tuple
     * ----------------
     */
d465 1
d467 1
a467 1
    xidstatus = TransTupleGetXidIdStatus(ttitem, xid, failP);
d474 5
a478 1
    
d480 1
a480 1
	xidstatus;
d484 1
a484 1
 *	TransItemPointerSetXidStatus
d488 1
a488 1
TransItemPointerSetXidStatus(relation, iptr, xid, status, failP)
d490 1
a490 1
    ItemPointer		iptr;
d492 1
a492 1
    XidStatus		xidstatus;
a494 4
    PagePartition   	partition;	/* number partitions on page */
    BlockNumber	   	blockNumber;	/* TransTuple block number */
    PageNumber	  	pageNumber;	/* TransTuple page number */
    OffsetNumber	offsetNumber;	/* item number on page of TransTuple */
d496 1
a496 3
    Page		page;		/* page containing TransTuple */
    ItemId	   	itemId;		/* item id referencing TransTuple */
    Item		ttitem;		/* TransTuple containing xid status */
d500 1
a500 1
     *	get the block number and stuff from the item pointer
d503 1
a503 5
    partition =    SinglePagePartition;
    blockNumber =  ItemPointerGetBlockNumber(iptr);
    pageNumber =   ItemPointerGetPageNumber(iptr, partition);
    offsetNumber = ItemPointerGetOffsetNumber(iptr, partition);
    
d505 1
a505 1
     *	get the page containing the tuple
d508 2
a509 2
    buffer = ReadBuffer(relation, blockNumber, 0);
    page =   BufferGetPageDebug(buffer, pageNumber);
d512 3
a514 1
     *	get the item on the page
a516 8
    itemId =   	PageGetItemId(page, offsetNumber - 1);
    ttitem =   	PageGetItem(page, itemId);

    /* ----------------
     *	attempt to update the status of the transaction on the page.
     *  if we are successful, write the page. otherwise release the buffer.
     * ----------------
     */
d519 1
d521 1
a521 1
    TransTupleSetXidStatus(ttitem, xid, status, failP);
d527 5
d535 1
a535 1
 *	TransItemPointerGetCommitTime
d539 1
a539 1
TransItemPointerGetCommitTime(relation, iptr, xid, failP)
d541 1
a541 1
    ItemPointer		iptr;
a544 4
    PagePartition   	partition;	/* number partitions on btree page */
    BlockNumber	   	blockNumber;	/* TransTuple block number */
    PageNumber	  	pageNumber;	/* TransTuple page number */
    OffsetNumber	offsetNumber;	/* item number on page of TransTuple */
d546 1
a546 4
    Page		page;		/* page containing TransTuple */
    ItemId	   	itemId;		/* item id referencing TransTuple */
    Item		ttitem;		/* TransTuple containing xid status */
    Time		xtime;		/* recorded commit time of xid */
d548 2
a549 1

d551 1
a551 1
     *	get the block number and stuff from the item pointer
d554 1
a554 5
    partition =    SinglePagePartition;
    blockNumber =  ItemPointerGetBlockNumber(iptr);
    pageNumber =   ItemPointerGetPageNumber(iptr, partition);
    offsetNumber = ItemPointerGetOffsetNumber(iptr, partition);

d556 1
a556 1
     *	get the page containing the tuple
d559 2
a560 2
    buffer = 	ReadBuffer(relation, blockNumber, 0);
    page =   	BufferGetPageDebug(buffer, pageNumber);
d563 2
a564 1
     *	get the item on the page we want
a566 7
    itemId =    PageGetItemId(page, offsetNumber - 1);
    ttitem =   	PageGetItem(page, itemId);

    /* ----------------
     *	get the commit time from the tuple
     * ----------------
     */
d569 3
a572 2
    xtime = TransTupleGetTransactionCommitTime(ttitem, xid, failP);

d579 4
d586 2
a587 1
	return InvalidCommitTime;
d591 1
a591 1
 *	TransItemPointerSetCommitTime
d595 1
a595 1
TransItemPointerSetCommitTime(relation, iptr, xid, xtime, failP)
d597 1
a597 1
    ItemPointer		iptr;
a601 4
    PagePartition   	partition;	/* number partitions on btree page */
    BlockNumber	   	blockNumber;	/* TransTuple block number */
    PageNumber	  	pageNumber;	/* TransTuple page number */
    OffsetNumber	offsetNumber;	/* item number on page of TransTuple */
d603 1
a603 3
    Page		page;		/* page containing TransTuple */
    ItemId	   	itemId;		/* item id referencing TransTuple */
    Item		ttitem;		/* TransTuple containing xid status */
d607 1
a607 1
     *	get the block number and stuff from the item pointer
d610 1
a610 5
    partition =    SinglePagePartition;
    blockNumber =  ItemPointerGetBlockNumber(iptr);
    pageNumber =   ItemPointerGetPageNumber(iptr, partition);
    offsetNumber = ItemPointerGetOffsetNumber(iptr, partition);

d612 1
a612 1
     *	get the page containing the tuple
d615 2
a616 2
    buffer = 	ReadBuffer(relation, blockNumber, 0);
    page =   	BufferGetPageDebug(buffer, pageNumber);
d619 3
a621 1
     *	get the item on the page we want
a623 8
    itemId =    PageGetItemId(page, offsetNumber - 1);
    ttitem =   	PageGetItem(page, itemId);

    /* ----------------
     *	attempt to update the commit time of the transaction on the page.
     *  if we are successful, write the page. otherwise release the buffer.
     * ----------------
     */
d626 1
d628 1
a628 1
    TransTupleSetTransactionCommitTime(ttitem, xid, status, xtime, failP);
d634 5
d651 1
a651 4
    PagePartition   	partition;	/* number partitions on page */
    BlockNumber	   	blockNumber;	/* TransTuple block number */
    PageNumber	  	pageNumber;	/* TransTuple page number */
    OffsetNumber	offsetNumber;	/* item number on page of TransTuple */
d653 6
a658 4
    Page		page;		/* page containing TransTuple */
    ItemId	   	itemId;		/* item id referencing TransTuple */
    Item		ttitem;		/* TransTuple containing xid status */
    BlockNumber		n;		/* number of pages in the relation */
a659 2
    (*failP) = false;
    
d661 5
a665 1
     *	we assume the last page of the log contains the last
d677 1
a677 1
     *	get the page containing the tuple
a679 1
    partition =    SinglePagePartition;
a680 3
    pageNumber =   0;
    offsetNumber = 0;

d682 1
a682 1
    page =   	BufferGetPageDebug(buffer, pageNumber);
d685 1
a685 1
     *	get the item on the page we want
d688 2
a689 4
    itemId =    PageGetItemId(page, offsetNumber - 1);
    ttitem =   	PageGetItem(page, itemId);

    (void) TransTupleGetLastTransactionIdStatus(ttitem, xid);
d691 2
d694 5
@
