diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c
new file mode 100644
index b38208e..ab5aaff
*** a/src/backend/access/hash/hash_xlog.c
--- b/src/backend/access/hash/hash_xlog.c
*************** hash_xlog_move_page_contents(XLogReaderS
*** 558,564 ****
  				Size		itemsz;
  				OffsetNumber l;
  
! 				itemsz = IndexTupleDSize(*itup);
  				itemsz = MAXALIGN(itemsz);
  
  				data += itemsz;
--- 558,564 ----
  				Size		itemsz;
  				OffsetNumber l;
  
! 				itemsz = IndexTupleSize(itup);
  				itemsz = MAXALIGN(itemsz);
  
  				data += itemsz;
*************** hash_xlog_squeeze_page(XLogReaderState *
*** 686,692 ****
  				Size		itemsz;
  				OffsetNumber l;
  
! 				itemsz = IndexTupleDSize(*itup);
  				itemsz = MAXALIGN(itemsz);
  
  				data += itemsz;
--- 686,692 ----
  				Size		itemsz;
  				OffsetNumber l;
  
! 				itemsz = IndexTupleSize(itup);
  				itemsz = MAXALIGN(itemsz);
  
  				data += itemsz;
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
new file mode 100644
index f668dcf..f121286
*** a/src/backend/access/hash/hashinsert.c
--- b/src/backend/access/hash/hashinsert.c
*************** _hash_doinsert(Relation rel, IndexTuple
*** 55,61 ****
  	hashkey = _hash_get_indextuple_hashkey(itup);
  
  	/* compute item size too */
! 	itemsz = IndexTupleDSize(*itup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
--- 55,61 ----
  	hashkey = _hash_get_indextuple_hashkey(itup);
  
  	/* compute item size too */
! 	itemsz = IndexTupleSize(itup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
*************** restart_insert:
*** 222,228 ****
  		XLogRegisterBuffer(1, metabuf, REGBUF_STANDARD);
  
  		XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
! 		XLogRegisterBufData(0, (char *) itup, IndexTupleDSize(*itup));
  
  		recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_INSERT);
  
--- 222,228 ----
  		XLogRegisterBuffer(1, metabuf, REGBUF_STANDARD);
  
  		XLogRegisterBuffer(0, buf, REGBUF_STANDARD);
! 		XLogRegisterBufData(0, (char *) itup, IndexTupleSize(itup));
  
  		recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_INSERT);
  
*************** _hash_pgaddmultitup(Relation rel, Buffer
*** 309,315 ****
  	{
  		Size		itemsize;
  
! 		itemsize = IndexTupleDSize(*itups[i]);
  		itemsize = MAXALIGN(itemsize);
  
  		/* Find where to insert the tuple (preserving page's hashkey ordering) */
--- 309,315 ----
  	{
  		Size		itemsize;
  
! 		itemsize = IndexTupleSize(itups[i]);
  		itemsize = MAXALIGN(itemsize);
  
  		/* Find where to insert the tuple (preserving page's hashkey ordering) */
diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c
new file mode 100644
index c9de128..d92ecd7
*** a/src/backend/access/hash/hashovfl.c
--- b/src/backend/access/hash/hashovfl.c
*************** readpage:
*** 890,896 ****
  
  			itup = (IndexTuple) PageGetItem(rpage,
  											PageGetItemId(rpage, roffnum));
! 			itemsz = IndexTupleDSize(*itup);
  			itemsz = MAXALIGN(itemsz);
  
  			/*
--- 890,896 ----
  
  			itup = (IndexTuple) PageGetItem(rpage,
  											PageGetItemId(rpage, roffnum));
! 			itemsz = IndexTupleSize(itup);
  			itemsz = MAXALIGN(itemsz);
  
  			/*
diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c
new file mode 100644
index e3c8721..3859e3b
*** a/src/backend/access/hash/hashpage.c
--- b/src/backend/access/hash/hashpage.c
*************** _hash_splitbucket(Relation rel,
*** 1173,1179 ****
  				 * the current page in the new bucket, we must allocate a new
  				 * overflow page and place the tuple on that page instead.
  				 */
! 				itemsz = IndexTupleDSize(*new_itup);
  				itemsz = MAXALIGN(itemsz);
  
  				if (PageGetFreeSpaceForMultipleTuples(npage, nitups + 1) < (all_tups_size + itemsz))
--- 1173,1179 ----
  				 * the current page in the new bucket, we must allocate a new
  				 * overflow page and place the tuple on that page instead.
  				 */
! 				itemsz = IndexTupleSize(new_itup);
  				itemsz = MAXALIGN(itemsz);
  
  				if (PageGetFreeSpaceForMultipleTuples(npage, nitups + 1) < (all_tups_size + itemsz))
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
new file mode 100644
index 51059c0..2fe9867
*** a/src/backend/access/nbtree/nbtinsert.c
--- b/src/backend/access/nbtree/nbtinsert.c
*************** _bt_findinsertloc(Relation rel,
*** 558,564 ****
  
  	lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
  
! 	itemsz = IndexTupleDSize(*newtup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
--- 558,564 ----
  
  	lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
  
! 	itemsz = IndexTupleSize(newtup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
*************** _bt_insertonpg(Relation rel,
*** 755,761 ****
  		elog(ERROR, "cannot insert to incompletely split page %u",
  			 BufferGetBlockNumber(buf));
  
! 	itemsz = IndexTupleDSize(*itup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
--- 755,761 ----
  		elog(ERROR, "cannot insert to incompletely split page %u",
  			 BufferGetBlockNumber(buf));
  
! 	itemsz = IndexTupleSize(itup);
  	itemsz = MAXALIGN(itemsz);	/* be safe, PageAddItem will do this but we
  								 * need to be consistent */
  
*************** _bt_insertonpg(Relation rel,
*** 914,920 ****
  									sizeof(IndexTupleData));
  			}
  			else
! 				XLogRegisterBufData(0, (char *) itup, IndexTupleDSize(*itup));
  
  			recptr = XLogInsert(RM_BTREE_ID, xlinfo);
  
--- 914,920 ----
  									sizeof(IndexTupleData));
  			}
  			else
! 				XLogRegisterBufData(0, (char *) itup, IndexTupleSize(itup));
  
  			recptr = XLogInsert(RM_BTREE_ID, xlinfo);
  
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
new file mode 100644
index f6159db..4a909ea
*** a/src/backend/access/nbtree/nbtsort.c
--- b/src/backend/access/nbtree/nbtsort.c
*************** _bt_buildadd(BTWriteState *wstate, BTPag
*** 468,474 ****
  	last_off = state->btps_lastoff;
  
  	pgspc = PageGetFreeSpace(npage);
! 	itupsz = IndexTupleDSize(*itup);
  	itupsz = MAXALIGN(itupsz);
  
  	/*
--- 468,474 ----
  	last_off = state->btps_lastoff;
  
  	pgspc = PageGetFreeSpace(npage);
! 	itupsz = IndexTupleSize(itup);
  	itupsz = MAXALIGN(itupsz);
  
  	/*
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
new file mode 100644
index bed1dd2..153d079
*** a/src/backend/access/nbtree/nbtxlog.c
--- b/src/backend/access/nbtree/nbtxlog.c
*************** _bt_restore_page(Page page, char *from,
*** 38,44 ****
  	IndexTupleData itupdata;
  	Size		itemsz;
  	char	   *end = from + len;
! 	Item		items[MaxIndexTuplesPerPage];
  	uint16		itemsizes[MaxIndexTuplesPerPage];
  	int			i;
  	int			nitems;
--- 38,44 ----
  	IndexTupleData itupdata;
  	Size		itemsz;
  	char	   *end = from + len;
! 	IndexTuple	items[MaxIndexTuplesPerPage];
  	uint16		itemsizes[MaxIndexTuplesPerPage];
  	int			i;
  	int			nitems;
*************** _bt_restore_page(Page page, char *from,
*** 53,62 ****
  	{
  		/* Need to copy tuple header due to alignment considerations */
  		memcpy(&itupdata, from, sizeof(IndexTupleData));
! 		itemsz = IndexTupleDSize(itupdata);
  		itemsz = MAXALIGN(itemsz);
  
! 		items[i] = (Item) from;
  		itemsizes[i] = itemsz;
  		i++;
  
--- 53,62 ----
  	{
  		/* Need to copy tuple header due to alignment considerations */
  		memcpy(&itupdata, from, sizeof(IndexTupleData));
! 		itemsz = IndexTupleSize(&itupdata);
  		itemsz = MAXALIGN(itemsz);
  
! 		items[i] = (IndexTuple) from;
  		itemsizes[i] = itemsz;
  		i++;
  
*************** _bt_restore_page(Page page, char *from,
*** 66,72 ****
  
  	for (i = nitems - 1; i >= 0; i--)
  	{
! 		if (PageAddItem(page, items[i], itemsizes[i], nitems - i,
  						false, false) == InvalidOffsetNumber)
  			elog(PANIC, "_bt_restore_page: cannot add item to page");
  		from += itemsz;
--- 66,72 ----
  
  	for (i = nitems - 1; i >= 0; i--)
  	{
! 		if (PageAddItem(page, (Item) items[i], itemsizes[i], nitems - i,
  						false, false) == InvalidOffsetNumber)
  			elog(PANIC, "_bt_restore_page: cannot add item to page");
  		from += itemsz;
*************** btree_xlog_split(bool onleft, XLogReader
*** 205,211 ****
  	BTPageOpaque ropaque;
  	char	   *datapos;
  	Size		datalen;
! 	Item		left_hikey = NULL;
  	Size		left_hikeysz = 0;
  	BlockNumber leftsib;
  	BlockNumber rightsib;
--- 205,211 ----
  	BTPageOpaque ropaque;
  	char	   *datapos;
  	Size		datalen;
! 	IndexTuple	left_hikey = NULL;
  	Size		left_hikeysz = 0;
  	BlockNumber leftsib;
  	BlockNumber rightsib;
*************** btree_xlog_split(bool onleft, XLogReader
*** 248,254 ****
  	{
  		ItemId		hiItemId = PageGetItemId(rpage, P_FIRSTDATAKEY(ropaque));
  
! 		left_hikey = PageGetItem(rpage, hiItemId);
  		left_hikeysz = ItemIdGetLength(hiItemId);
  	}
  
--- 248,254 ----
  	{
  		ItemId		hiItemId = PageGetItemId(rpage, P_FIRSTDATAKEY(ropaque));
  
! 		left_hikey = (IndexTuple) PageGetItem(rpage, hiItemId);
  		left_hikeysz = ItemIdGetLength(hiItemId);
  	}
  
*************** btree_xlog_split(bool onleft, XLogReader
*** 272,278 ****
  		Page		lpage = (Page) BufferGetPage(lbuf);
  		BTPageOpaque lopaque = (BTPageOpaque) PageGetSpecialPointer(lpage);
  		OffsetNumber off;
! 		Item		newitem = NULL;
  		Size		newitemsz = 0;
  		Page		newlpage;
  		OffsetNumber leftoff;
--- 272,278 ----
  		Page		lpage = (Page) BufferGetPage(lbuf);
  		BTPageOpaque lopaque = (BTPageOpaque) PageGetSpecialPointer(lpage);
  		OffsetNumber off;
! 		IndexTuple	newitem = NULL;
  		Size		newitemsz = 0;
  		Page		newlpage;
  		OffsetNumber leftoff;
*************** btree_xlog_split(bool onleft, XLogReader
*** 281,287 ****
  
  		if (onleft)
  		{
! 			newitem = (Item) datapos;
  			newitemsz = MAXALIGN(IndexTupleSize(newitem));
  			datapos += newitemsz;
  			datalen -= newitemsz;
--- 281,287 ----
  
  		if (onleft)
  		{
! 			newitem = (IndexTuple) datapos;
  			newitemsz = MAXALIGN(IndexTupleSize(newitem));
  			datapos += newitemsz;
  			datalen -= newitemsz;
*************** btree_xlog_split(bool onleft, XLogReader
*** 290,296 ****
  		/* Extract left hikey and its size (assuming 16-bit alignment) */
  		if (!isleaf)
  		{
! 			left_hikey = (Item) datapos;
  			left_hikeysz = MAXALIGN(IndexTupleSize(left_hikey));
  			datapos += left_hikeysz;
  			datalen -= left_hikeysz;
--- 290,296 ----
  		/* Extract left hikey and its size (assuming 16-bit alignment) */
  		if (!isleaf)
  		{
! 			left_hikey = (IndexTuple) datapos;
  			left_hikeysz = MAXALIGN(IndexTupleSize(left_hikey));
  			datapos += left_hikeysz;
  			datalen -= left_hikeysz;
*************** btree_xlog_split(bool onleft, XLogReader
*** 301,307 ****
  
  		/* Set high key */
  		leftoff = P_HIKEY;
! 		if (PageAddItem(newlpage, left_hikey, left_hikeysz,
  						P_HIKEY, false, false) == InvalidOffsetNumber)
  			elog(PANIC, "failed to add high key to left page after split");
  		leftoff = OffsetNumberNext(leftoff);
--- 301,307 ----
  
  		/* Set high key */
  		leftoff = P_HIKEY;
! 		if (PageAddItem(newlpage, (Item) left_hikey, left_hikeysz,
  						P_HIKEY, false, false) == InvalidOffsetNumber)
  			elog(PANIC, "failed to add high key to left page after split");
  		leftoff = OffsetNumberNext(leftoff);
*************** btree_xlog_split(bool onleft, XLogReader
*** 310,321 ****
  		{
  			ItemId		itemid;
  			Size		itemsz;
! 			Item		item;
  
  			/* add the new item if it was inserted on left page */
  			if (onleft && off == xlrec->newitemoff)
  			{
! 				if (PageAddItem(newlpage, newitem, newitemsz, leftoff,
  								false, false) == InvalidOffsetNumber)
  					elog(ERROR, "failed to add new item to left page after split");
  				leftoff = OffsetNumberNext(leftoff);
--- 310,321 ----
  		{
  			ItemId		itemid;
  			Size		itemsz;
! 			IndexTuple	item;
  
  			/* add the new item if it was inserted on left page */
  			if (onleft && off == xlrec->newitemoff)
  			{
! 				if (PageAddItem(newlpage, (Item) newitem, newitemsz, leftoff,
  								false, false) == InvalidOffsetNumber)
  					elog(ERROR, "failed to add new item to left page after split");
  				leftoff = OffsetNumberNext(leftoff);
*************** btree_xlog_split(bool onleft, XLogReader
*** 323,330 ****
  
  			itemid = PageGetItemId(lpage, off);
  			itemsz = ItemIdGetLength(itemid);
! 			item = PageGetItem(lpage, itemid);
! 			if (PageAddItem(newlpage, item, itemsz, leftoff,
  							false, false) == InvalidOffsetNumber)
  				elog(ERROR, "failed to add old item to left page after split");
  			leftoff = OffsetNumberNext(leftoff);
--- 323,330 ----
  
  			itemid = PageGetItemId(lpage, off);
  			itemsz = ItemIdGetLength(itemid);
! 			item = (IndexTuple) PageGetItem(lpage, itemid);
! 			if (PageAddItem(newlpage, (Item) item, itemsz, leftoff,
  							false, false) == InvalidOffsetNumber)
  				elog(ERROR, "failed to add old item to left page after split");
  			leftoff = OffsetNumberNext(leftoff);
*************** btree_xlog_split(bool onleft, XLogReader
*** 333,339 ****
  		/* cope with possibility that newitem goes at the end */
  		if (onleft && off == xlrec->newitemoff)
  		{
! 			if (PageAddItem(newlpage, newitem, newitemsz, leftoff,
  							false, false) == InvalidOffsetNumber)
  				elog(ERROR, "failed to add new item to left page after split");
  			leftoff = OffsetNumberNext(leftoff);
--- 333,339 ----
  		/* cope with possibility that newitem goes at the end */
  		if (onleft && off == xlrec->newitemoff)
  		{
! 			if (PageAddItem(newlpage, (Item) newitem, newitemsz, leftoff,
  							false, false) == InvalidOffsetNumber)
  				elog(ERROR, "failed to add new item to left page after split");
  			leftoff = OffsetNumberNext(leftoff);
diff --git a/src/include/access/itup.h b/src/include/access/itup.h
new file mode 100644
index 0ffa91d..9be3442
*** a/src/include/access/itup.h
--- b/src/include/access/itup.h
*************** typedef IndexAttributeBitMapData * Index
*** 67,74 ****
  #define INDEX_VAR_MASK	0x4000
  #define INDEX_NULL_MASK 0x8000
  
! #define IndexTupleSize(itup)		((Size) (((IndexTuple) (itup))->t_info & INDEX_SIZE_MASK))
! #define IndexTupleDSize(itup)		((Size) ((itup).t_info & INDEX_SIZE_MASK))
  #define IndexTupleHasNulls(itup)	((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK))
  #define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK))
  
--- 67,73 ----
  #define INDEX_VAR_MASK	0x4000
  #define INDEX_NULL_MASK 0x8000
  
! #define IndexTupleSize(itup)		((Size) ((itup)->t_info & INDEX_SIZE_MASK))
  #define IndexTupleHasNulls(itup)	((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK))
  #define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK))
  
