diff -cpr pgsql-orig/src/backend/commands/vacuum.c pgsql/src/backend/commands/vacuum.c
*** pgsql-orig/src/backend/commands/vacuum.c	2005-08-31 19:31:59.000000000 +0900
--- pgsql/src/backend/commands/vacuum.c	2005-09-01 09:19:50.868589816 +0900
*************** scan_heap(VRelStats *vacrelstats, Relati
*** 1357,1363 ****
  						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;
--- 1357,1363 ----
  						TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data),
  											  FreezeLimit))
  					{
! 						tuple.t_data->t_infomask |= HEAP_FROZEN;
  						/* infomask should be okay already */
  						Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
  						pgchanged = true;
diff -cpr pgsql-orig/src/backend/commands/vacuumlazy.c pgsql/src/backend/commands/vacuumlazy.c
*** pgsql-orig/src/backend/commands/vacuumlazy.c	2005-08-31 19:31:59.000000000 +0900
--- pgsql/src/backend/commands/vacuumlazy.c	2005-09-01 09:19:50.786602280 +0900
*************** lazy_scan_heap(Relation onerel, LVRelSta
*** 381,387 ****
  						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;
--- 381,387 ----
  						TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data),
  											  FreezeLimit))
  					{
! 						tuple.t_data->t_infomask |= HEAP_FROZEN;
  						/* infomask should be okay already */
  						Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED);
  						pgchanged = true;
diff -cpr pgsql-orig/src/backend/storage/page/bufpage.c pgsql/src/backend/storage/page/bufpage.c
*** pgsql-orig/src/backend/storage/page/bufpage.c	2005-08-31 19:31:59.000000000 +0900
--- pgsql/src/backend/storage/page/bufpage.c	2005-09-01 09:28:36.192728408 +0900
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "storage/bufpage.h"
+ #include "access/htup.h"
  
  
  /* ----------------------------------------------------------------
*************** typedef struct itemIdSortData
*** 281,287 ****
  	int			offsetindex;	/* linp array index */
  	int			itemoff;		/* page offset of item data */
  	Size		alignedlen;		/* MAXALIGN(item data len) */
! 	ItemIdData	olditemid;		/* used only in PageIndexMultiDelete */
  } itemIdSortData;
  typedef itemIdSortData *itemIdSort;
  
--- 282,292 ----
  	int			offsetindex;	/* linp array index */
  	int			itemoff;		/* page offset of item data */
  	Size		alignedlen;		/* MAXALIGN(item data len) */
! 	union
! 	{
! 		int			cutlen;		/* used only in PageRepairFragmentation */
! 		ItemIdData	olditemid;		/* used only in PageIndexMultiDelete */
! 	} extra;
  } itemIdSortData;
  typedef itemIdSortData *itemIdSort;
  
*************** PageRepairFragmentation(Page page, Offse
*** 372,385 ****
  			{
  				itemidptr->offsetindex = i;
  				itemidptr->itemoff = lp->lp_off;
! 				if (itemidptr->itemoff < (int) pd_upper ||
  					itemidptr->itemoff >= (int) pd_special)
  					ereport(ERROR,
  							(errcode(ERRCODE_DATA_CORRUPTED),
  							 errmsg("corrupted item pointer: %u",
  									itemidptr->itemoff)));
  				itemidptr->alignedlen = MAXALIGN(lp->lp_len);
! 				totallen += itemidptr->alignedlen;
  				itemidptr++;
  			}
  			else
--- 377,400 ----
  			{
  				itemidptr->offsetindex = i;
  				itemidptr->itemoff = lp->lp_off;
! 				if (MAXIMUM_ALIGNOF <= offsetof(HeapTupleFields, t_xmax) &&
! 					((HeapTupleHeader) PageGetItem(page, lp))->t_infomask & HEAP_FROZEN)
! 				{
! 					/* assume offsetof(xmax) == sizeof(xmin) + sizeof(cmin) */
! 					itemidptr->extra.cutlen = offsetof(HeapTupleFields, t_xmax);
! 				}
! 				else
! 				{
! 					itemidptr->extra.cutlen = 0;
! 				}
! 				if (itemidptr->itemoff + itemidptr->extra.cutlen < (int) pd_upper ||
  					itemidptr->itemoff >= (int) pd_special)
  					ereport(ERROR,
  							(errcode(ERRCODE_DATA_CORRUPTED),
  							 errmsg("corrupted item pointer: %u",
  									itemidptr->itemoff)));
  				itemidptr->alignedlen = MAXALIGN(lp->lp_len);
! 				totallen += itemidptr->alignedlen - itemidptr->extra.cutlen;
  				itemidptr++;
  			}
  			else
*************** PageRepairFragmentation(Page page, Offse
*** 404,414 ****
  		for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++)
  		{
  			lp = PageGetItemId(page, itemidptr->offsetindex + 1);
! 			upper -= itemidptr->alignedlen;
  			memmove((char *) page + upper,
! 					(char *) page + itemidptr->itemoff,
! 					itemidptr->alignedlen);
! 			lp->lp_off = upper;
  		}
  
  		((PageHeader) page)->pd_upper = upper;
--- 419,429 ----
  		for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++)
  		{
  			lp = PageGetItemId(page, itemidptr->offsetindex + 1);
! 			lp->lp_off = upper - itemidptr->alignedlen;
! 			upper = lp->lp_off + itemidptr->extra.cutlen;
  			memmove((char *) page + upper,
! 					(char *) page + itemidptr->itemoff + itemidptr->extra.cutlen,
! 					itemidptr->alignedlen - itemidptr->extra.cutlen);
  		}
  
  		((PageHeader) page)->pd_upper = upper;
*************** PageIndexMultiDelete(Page page, OffsetNu
*** 636,642 ****
  		{
  			itemidptr->offsetindex = nused; /* where it will go */
  			itemidptr->itemoff = offset;
! 			itemidptr->olditemid = *lp;
  			itemidptr->alignedlen = MAXALIGN(size);
  			totallen += itemidptr->alignedlen;
  			itemidptr++;
--- 651,657 ----
  		{
  			itemidptr->offsetindex = nused; /* where it will go */
  			itemidptr->itemoff = offset;
! 			itemidptr->extra.olditemid = *lp;
  			itemidptr->alignedlen = MAXALIGN(size);
  			totallen += itemidptr->alignedlen;
  			itemidptr++;
*************** PageIndexMultiDelete(Page page, OffsetNu
*** 668,674 ****
  		memmove((char *) page + upper,
  				(char *) page + itemidptr->itemoff,
  				itemidptr->alignedlen);
! 		*lp = itemidptr->olditemid;
  		lp->lp_off = upper;
  	}
  
--- 683,689 ----
  		memmove((char *) page + upper,
  				(char *) page + itemidptr->itemoff,
  				itemidptr->alignedlen);
! 		*lp = itemidptr->extra.olditemid;
  		lp->lp_off = upper;
  	}
  
diff -cpr pgsql-orig/src/include/access/htup.h pgsql/src/include/access/htup.h
*** pgsql-orig/src/include/access/htup.h	2005-08-31 19:31:59.000000000 +0900
--- pgsql/src/include/access/htup.h	2005-08-31 19:33:18.000000000 +0900
*************** typedef HeapTupleHeaderData *HeapTupleHe
*** 167,173 ****
  										 * attribute(s) */
  #define HEAP_HASEXTENDED		0x000C	/* the two above combined */
  #define HEAP_HASOID				0x0010	/* has an object-id field */
! /* 0x0020 is presently unused */
  #define HEAP_XMAX_EXCL_LOCK		0x0040  /* xmax is exclusive locker */
  #define HEAP_XMAX_SHARED_LOCK	0x0080  /* xmax is shared locker */
  /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */
--- 167,173 ----
  										 * attribute(s) */
  #define HEAP_HASEXTENDED		0x000C	/* the two above combined */
  #define HEAP_HASOID				0x0010	/* has an object-id field */
! #define HEAP_FROZEN				0x0020	/* no xmin and cmin */
  #define HEAP_XMAX_EXCL_LOCK		0x0040  /* xmax is exclusive locker */
  #define HEAP_XMAX_SHARED_LOCK	0x0080  /* xmax is shared locker */
  /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */
*************** typedef HeapTupleHeaderData *HeapTupleHe
*** 184,190 ****
  										 * VACUUM FULL */
  #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
  
! #define HEAP_XACT_MASK			0xFFC0	/* visibility-related bits */
  
  
  /*
--- 184,190 ----
  										 * VACUUM FULL */
  #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)
  
! #define HEAP_XACT_MASK			0xFFE0	/* visibility-related bits */
  
  
  /*
*************** typedef HeapTupleHeaderData *HeapTupleHe
*** 196,202 ****
  
  #define HeapTupleHeaderGetXmin(tup) \
  ( \
! 	(tup)->t_choice.t_heap.t_xmin \
  )
  
  #define HeapTupleHeaderSetXmin(tup, xid) \
--- 196,205 ----
  
  #define HeapTupleHeaderGetXmin(tup) \
  ( \
! 	((tup)->t_infomask & HEAP_FROZEN) ? \
! 		FrozenTransactionId \
! 	: \
! 		(tup)->t_choice.t_heap.t_xmin \
  )
  
  #define HeapTupleHeaderSetXmin(tup, xid) \