diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index f017de0cdc8c1c257a2f8d36a7ddd82cb8a689f2..2c6447d7faa14c0c1f79feba3eb84fd7e7fcdc38 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -105,7 +105,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
 	{
 		OffsetNumber mid = low + ((high - low) / 2);
 
-		pitem = (PostingItem *) GinDataPageGetItem(page, mid);
+		pitem = GinDataPageGetPostingItem(page, mid);
 
 		if (mid == maxoff)
 		{
@@ -117,7 +117,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
 		}
 		else
 		{
-			pitem = (PostingItem *) GinDataPageGetItem(page, mid);
+			pitem = GinDataPageGetPostingItem(page, mid);
 			result = ginCompareItemPointers(btree->items + btree->curitem, &(pitem->key));
 		}
 
@@ -135,7 +135,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
 	Assert(high >= FirstOffsetNumber && high <= maxoff);
 
 	stack->off = high;
-	pitem = (PostingItem *) GinDataPageGetItem(page, high);
+	pitem = GinDataPageGetPostingItem(page, high);
 	return PostingItemGetBlockNumber(pitem);
 }
 
@@ -176,7 +176,8 @@ dataLocateLeafItem(GinBtree btree, GinBtreeStack *stack)
 	{
 		OffsetNumber mid = low + ((high - low) / 2);
 
-		result = ginCompareItemPointers(btree->items + btree->curitem, (ItemPointer) GinDataPageGetItem(page, mid));
+		result = ginCompareItemPointers(btree->items + btree->curitem,
+										GinDataPageGetItemPointer(page, mid));
 
 		if (result == 0)
 		{
@@ -210,7 +211,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
 	/* if page isn't changed, we return storedOff */
 	if (storedOff >= FirstOffsetNumber && storedOff <= maxoff)
 	{
-		pitem = (PostingItem *) GinDataPageGetItem(page, storedOff);
+		pitem = GinDataPageGetPostingItem(page, storedOff);
 		if (PostingItemGetBlockNumber(pitem) == blkno)
 			return storedOff;
 
@@ -220,7 +221,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
 		 */
 		for (i = storedOff + 1; i <= maxoff; i++)
 		{
-			pitem = (PostingItem *) GinDataPageGetItem(page, i);
+			pitem = GinDataPageGetPostingItem(page, i);
 			if (PostingItemGetBlockNumber(pitem) == blkno)
 				return i;
 		}
@@ -231,7 +232,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
 	/* last chance */
 	for (i = FirstOffsetNumber; i <= maxoff; i++)
 	{
-		pitem = (PostingItem *) GinDataPageGetItem(page, i);
+		pitem = GinDataPageGetPostingItem(page, i);
 		if (PostingItemGetBlockNumber(pitem) == blkno)
 			return i;
 	}
@@ -251,33 +252,62 @@ dataGetLeftMostPage(GinBtree btree, Page page)
 	Assert(GinPageIsData(page));
 	Assert(GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber);
 
-	pitem = (PostingItem *) GinDataPageGetItem(page, FirstOffsetNumber);
+	pitem = GinDataPageGetPostingItem(page, FirstOffsetNumber);
 	return PostingItemGetBlockNumber(pitem);
 }
 
 /*
- * add ItemPointer or PostingItem to page. data should point to
- * correct value! depending on leaf or non-leaf page
+ * add ItemPointer to a leaf page.
  */
 void
-GinDataPageAddItem(Page page, void *data, OffsetNumber offset)
+GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset)
 {
 	OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;
 	char	   *ptr;
 
+	Assert(GinPageIsLeaf(page));
+
+	if (offset == InvalidOffsetNumber)
+	{
+		ptr = (char *) GinDataPageGetItemPointer(page, maxoff + 1);
+	}
+	else
+	{
+		ptr = (char *) GinDataPageGetItemPointer(page, offset);
+		if (maxoff + 1 - offset != 0)
+			memmove(ptr + sizeof(ItemPointerData),
+					ptr,
+					(maxoff - offset + 1) * sizeof(ItemPointerData));
+	}
+	memcpy(ptr, data, sizeof(ItemPointerData));
+
+	GinPageGetOpaque(page)->maxoff++;
+}
+
+/*
+ * add PostingItem to a non-leaf page.
+ */
+void
+GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset)
+{
+	OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;
+	char	   *ptr;
+
+	Assert(!GinPageIsLeaf(page));
+
 	if (offset == InvalidOffsetNumber)
 	{
-		ptr = GinDataPageGetItem(page, maxoff + 1);
+		ptr = (char *) GinDataPageGetPostingItem(page, maxoff + 1);
 	}
 	else
 	{
-		ptr = GinDataPageGetItem(page, offset);
+		ptr = (char *) GinDataPageGetPostingItem(page, offset);
 		if (maxoff + 1 - offset != 0)
-			memmove(ptr + GinSizeOfDataPageItem(page),
+			memmove(ptr + sizeof(PostingItem),
 					ptr,
-					(maxoff - offset + 1) * GinSizeOfDataPageItem(page));
+					(maxoff - offset + 1) * sizeof(PostingItem));
 	}
-	memcpy(ptr, data, GinSizeOfDataPageItem(page));
+	memcpy(ptr, data, sizeof(PostingItem));
 
 	GinPageGetOpaque(page)->maxoff++;
 }
@@ -294,7 +324,8 @@ GinPageDeletePostingItem(Page page, OffsetNumber offset)
 	Assert(offset >= FirstOffsetNumber && offset <= maxoff);
 
 	if (offset != maxoff)
-		memmove(GinDataPageGetItem(page, offset), GinDataPageGetItem(page, offset + 1),
+		memmove(GinDataPageGetPostingItem(page, offset),
+				GinDataPageGetPostingItem(page, offset + 1),
 				sizeof(PostingItem) * (maxoff - offset));
 
 	GinPageGetOpaque(page)->maxoff--;
@@ -342,7 +373,7 @@ dataPrepareData(GinBtree btree, Page page, OffsetNumber off)
 
 	if (!GinPageIsLeaf(page) && btree->rightblkno != InvalidBlockNumber)
 	{
-		PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, off);
+		PostingItem *pitem = GinDataPageGetPostingItem(page, off);
 
 		PostingItemSetBlockNumber(pitem, btree->rightblkno);
 		ret = btree->rightblkno;
@@ -418,7 +449,7 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prda
 
 			while (btree->curitem < btree->nitem)
 			{
-				GinDataPageAddItem(page, btree->items + btree->curitem, off);
+				GinDataPageAddItemPointer(page, btree->items + btree->curitem, off);
 				off++;
 				btree->curitem++;
 			}
@@ -427,12 +458,12 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prda
 		}
 		else
 		{
-			GinDataPageAddItem(page, btree->items + btree->curitem, off);
+			GinDataPageAddItemPointer(page, btree->items + btree->curitem, off);
 			btree->curitem++;
 		}
 	}
 	else
-		GinDataPageAddItem(page, &(btree->pitem), off);
+		GinDataPageAddPostingItem(page, &(btree->pitem), off);
 }
 
 /*
@@ -448,6 +479,7 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
 	OffsetNumber separator;
 	ItemPointer bound;
 	Page		lpage = PageGetTempPageCopy(BufferGetPage(lbuf));
+	bool		isleaf = GinPageIsLeaf(lpage);
 	ItemPointerData oldbound = *GinDataPageGetRightBound(lpage);
 	int			sizeofitem = GinSizeOfDataPageItem(lpage);
 	OffsetNumber maxoff = GinPageGetOpaque(lpage)->maxoff;
@@ -469,10 +501,20 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
 		InvalidOffsetNumber : PostingItemGetBlockNumber(&(btree->pitem));
 	data.updateBlkno = dataPrepareData(btree, lpage, off);
 
-	memcpy(vector, GinDataPageGetItem(lpage, FirstOffsetNumber),
-		   maxoff * sizeofitem);
+	if (isleaf)
+	{
+		memcpy(vector,
+			   GinDataPageGetItemPointer(lpage, FirstOffsetNumber),
+			   maxoff * sizeof(ItemPointerData));
+	}
+	else
+	{
+		memcpy(vector,
+			   GinDataPageGetPostingItem(lpage, FirstOffsetNumber),
+			   maxoff * sizeof(PostingItem));
+	}
 
-	if (GinPageIsLeaf(lpage) && GinPageRightMost(lpage) && off > GinPageGetOpaque(lpage)->maxoff)
+	if (isleaf && GinPageRightMost(lpage) && off > GinPageGetOpaque(lpage)->maxoff)
 	{
 		nCopied = 0;
 		while (btree->curitem < btree->nitem &&
@@ -491,7 +533,7 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
 		ptr = vector + (off - 1) * sizeofitem;
 		if (maxoff + 1 - off != 0)
 			memmove(ptr + sizeofitem, ptr, (maxoff - off + 1) * sizeofitem);
-		if (GinPageIsLeaf(lpage))
+		if (isleaf)
 		{
 			memcpy(ptr, btree->items + btree->curitem, sizeofitem);
 			btree->curitem++;
@@ -514,19 +556,32 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
 	GinInitPage(rpage, GinPageGetOpaque(lpage)->flags, pageSize);
 	GinInitPage(lpage, GinPageGetOpaque(rpage)->flags, pageSize);
 
-	memcpy(GinDataPageGetItem(lpage, FirstOffsetNumber), vector, separator * sizeofitem);
+	if (isleaf)
+		memcpy(GinDataPageGetItemPointer(lpage, FirstOffsetNumber),
+			   vector, separator * sizeof(ItemPointerData));
+	else
+		memcpy(GinDataPageGetPostingItem(lpage, FirstOffsetNumber),
+			   vector, separator * sizeof(PostingItem));
+
 	GinPageGetOpaque(lpage)->maxoff = separator;
-	memcpy(GinDataPageGetItem(rpage, FirstOffsetNumber),
-		 vector + separator * sizeofitem, (maxoff - separator) * sizeofitem);
+	if (isleaf)
+		memcpy(GinDataPageGetItemPointer(rpage, FirstOffsetNumber),
+			   vector + separator * sizeof(ItemPointerData),
+			   (maxoff - separator) * sizeof(ItemPointerData));
+	else
+		memcpy(GinDataPageGetPostingItem(rpage, FirstOffsetNumber),
+			   vector + separator * sizeof(PostingItem),
+			   (maxoff - separator) * sizeof(PostingItem));
+
 	GinPageGetOpaque(rpage)->maxoff = maxoff - separator;
 
 	PostingItemSetBlockNumber(&(btree->pitem), BufferGetBlockNumber(lbuf));
 	if (GinPageIsLeaf(lpage))
-		btree->pitem.key = *(ItemPointerData *) GinDataPageGetItem(lpage,
+		btree->pitem.key = *GinDataPageGetItemPointer(lpage,
 											GinPageGetOpaque(lpage)->maxoff);
 	else
-		btree->pitem.key = ((PostingItem *) GinDataPageGetItem(lpage,
-									  GinPageGetOpaque(lpage)->maxoff))->key;
+		btree->pitem.key = GinDataPageGetPostingItem(lpage,
+									  GinPageGetOpaque(lpage)->maxoff)->key;
 	btree->rightblkno = BufferGetBlockNumber(rbuf);
 
 	/* set up right bound for left page */
@@ -576,11 +631,11 @@ ginDataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf)
 
 	li.key = *GinDataPageGetRightBound(lpage);
 	PostingItemSetBlockNumber(&li, BufferGetBlockNumber(lbuf));
-	GinDataPageAddItem(page, &li, InvalidOffsetNumber);
+	GinDataPageAddPostingItem(page, &li, InvalidOffsetNumber);
 
 	ri.key = *GinDataPageGetRightBound(rpage);
 	PostingItemSetBlockNumber(&ri, BufferGetBlockNumber(rbuf));
-	GinDataPageAddItem(page, &ri, InvalidOffsetNumber);
+	GinDataPageAddPostingItem(page, &ri, InvalidOffsetNumber);
 }
 
 void
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index cb17d383bc845a5c922dc2cfdfdc83df2ab9eb41..cb779aa7f74e7beb4f066368413918c5eff11a9a 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -83,7 +83,7 @@ findItemInPostingPage(Page page, ItemPointer item, OffsetNumber *off)
 	 */
 	for (*off = FirstOffsetNumber; *off <= maxoff; (*off)++)
 	{
-		res = ginCompareItemPointers(item, (ItemPointer) GinDataPageGetItem(page, *off));
+		res = ginCompareItemPointers(item, GinDataPageGetItemPointer(page, *off));
 
 		if (res <= 0)
 			return true;
@@ -154,7 +154,7 @@ scanPostingTree(Relation index, GinScanEntry scanEntry,
 			GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber)
 		{
 			tbm_add_tuples(scanEntry->matchBitmap,
-				   (ItemPointer) GinDataPageGetItem(page, FirstOffsetNumber),
+						   GinDataPageGetItemPointer(page, FirstOffsetNumber),
 						   GinPageGetOpaque(page)->maxoff, false);
 			scanEntry->predictNumberResult += GinPageGetOpaque(page)->maxoff;
 		}
@@ -467,7 +467,8 @@ restartScanEntry:
 			 */
 			entry->list = (ItemPointerData *) palloc(BLCKSZ);
 			entry->nlist = GinPageGetOpaque(page)->maxoff;
-			memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
+			memcpy(entry->list,
+				   GinDataPageGetItemPointer(page, FirstOffsetNumber),
 				   GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
 
 			LockBuffer(entry->buffer, GIN_UNLOCK);
@@ -587,8 +588,9 @@ entryGetNextItem(GinState *ginstate, GinScanEntry entry)
 				 * Found position equal to or greater than stored
 				 */
 				entry->nlist = GinPageGetOpaque(page)->maxoff;
-				memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
-				   GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
+				memcpy(entry->list,
+					   GinDataPageGetItemPointer(page, FirstOffsetNumber),
+					   GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
 
 				LockBuffer(entry->buffer, GIN_UNLOCK);
 
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index b84d3a30de39b135897355b98ba6f5c4f86d8ffb..bda9c60279ac5e30998be9af766229432516f083 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -210,7 +210,7 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno, bool isRoot,
 
 		for (i = FirstOffsetNumber; i <= GinPageGetOpaque(page)->maxoff; i++)
 		{
-			PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, i);
+			PostingItem *pitem = GinDataPageGetPostingItem(page, i);
 
 			if (ginVacuumPostingTreeLeaves(gvs, PostingItemGetBlockNumber(pitem), FALSE, NULL))
 				isChildHasVoid = TRUE;
@@ -283,7 +283,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
 #ifdef USE_ASSERT_CHECKING
 	do
 	{
-		PostingItem *tod = (PostingItem *) GinDataPageGetItem(parentPage, myoff);
+		PostingItem *tod = GinDataPageGetPostingItem(parentPage, myoff);
 
 		Assert(PostingItemGetBlockNumber(tod) == deleteBlkno);
 	} while (0);
@@ -422,7 +422,7 @@ ginScanToDelete(GinVacuumState *gvs, BlockNumber blkno, bool isRoot, DataPageDel
 		me->blkno = blkno;
 		for (i = FirstOffsetNumber; i <= GinPageGetOpaque(page)->maxoff; i++)
 		{
-			PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, i);
+			PostingItem *pitem = GinDataPageGetPostingItem(page, i);
 
 			if (ginScanToDelete(gvs, PostingItemGetBlockNumber(pitem), FALSE, me, i))
 				i--;
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index 5daabb0eef9885dda57adc9c0dd0fcdc9d2292d0..4d0ccb876f21f5971c2940e772ce9ffb9645f5f1 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -189,7 +189,7 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
 				Assert(data->updateBlkno == InvalidBlockNumber);
 
 				for (i = 0; i < data->nitem; i++)
-					GinDataPageAddItem(page, items + i, data->offset + i);
+					GinDataPageAddItemPointer(page, &items[i], data->offset + i);
 			}
 			else
 			{
@@ -200,13 +200,13 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
 				if (data->updateBlkno != InvalidBlockNumber)
 				{
 					/* update link to right page after split */
-					pitem = (PostingItem *) GinDataPageGetItem(page, data->offset);
+					pitem = GinDataPageGetPostingItem(page, data->offset);
 					PostingItemSetBlockNumber(pitem, data->updateBlkno);
 				}
 
 				pitem = (PostingItem *) (XLogRecGetData(record) + sizeof(ginxlogInsert));
 
-				GinDataPageAddItem(page, pitem, data->offset);
+				GinDataPageAddPostingItem(page, pitem, data->offset);
 			}
 		}
 		else
@@ -286,22 +286,28 @@ ginRedoSplit(XLogRecPtr lsn, XLogRecord *record)
 
 		for (i = 0; i < data->separator; i++)
 		{
-			GinDataPageAddItem(lpage, ptr, InvalidOffsetNumber);
+			if (data->isLeaf)
+				GinDataPageAddItemPointer(lpage, (ItemPointer) ptr, InvalidOffsetNumber);
+			else
+				GinDataPageAddPostingItem(lpage, (PostingItem *) ptr, InvalidOffsetNumber);
 			ptr += sizeofitem;
 		}
 
 		for (i = data->separator; i < data->nitem; i++)
 		{
-			GinDataPageAddItem(rpage, ptr, InvalidOffsetNumber);
+			if (data->isLeaf)
+				GinDataPageAddItemPointer(rpage, (ItemPointer) ptr, InvalidOffsetNumber);
+			else
+				GinDataPageAddPostingItem(rpage, (PostingItem *) ptr, InvalidOffsetNumber);
 			ptr += sizeofitem;
 		}
 
 		/* set up right key */
 		bound = GinDataPageGetRightBound(lpage);
 		if (data->isLeaf)
-			*bound = *(ItemPointerData *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff);
+			*bound = *GinDataPageGetItemPointer(lpage, GinPageGetOpaque(lpage)->maxoff);
 		else
-			*bound = ((PostingItem *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff))->key;
+			*bound = GinDataPageGetPostingItem(lpage, GinPageGetOpaque(lpage)->maxoff)->key;
 
 		bound = GinDataPageGetRightBound(rpage);
 		*bound = data->rightbound;
@@ -803,11 +809,11 @@ ginContinueSplit(ginIncompleteSplit *split)
 
 		PostingItemSetBlockNumber(&(btree.pitem), split->leftBlkno);
 		if (GinPageIsLeaf(page))
-			btree.pitem.key = *(ItemPointerData *) GinDataPageGetItem(page,
-											 GinPageGetOpaque(page)->maxoff);
+			btree.pitem.key = *GinDataPageGetItemPointer(page,
+														 GinPageGetOpaque(page)->maxoff);
 		else
-			btree.pitem.key = ((PostingItem *) GinDataPageGetItem(page,
-									   GinPageGetOpaque(page)->maxoff))->key;
+			btree.pitem.key = GinDataPageGetPostingItem(page,
+														GinPageGetOpaque(page)->maxoff)->key;
 	}
 
 	btree.rightblkno = split->rightBlkno;
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index c603521c9574fda6331889c5034ac956f86b2cff..7af3a870c7511bd4be9bc1288fa9bbeeb48587d0 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -232,10 +232,14 @@ typedef signed char GinNullCategory;
 #define GinDataPageGetRightBound(page)	((ItemPointer) PageGetContents(page))
 #define GinDataPageGetData(page)	\
 	(PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))
+/* non-leaf pages contain PostingItems */
+#define GinDataPageGetPostingItem(page, i)	\
+	((PostingItem *) (GinDataPageGetData(page) + ((i)-1) * sizeof(PostingItem)))
+/* leaf pages contain ItemPointers */
+#define GinDataPageGetItemPointer(page, i)	\
+	((ItemPointer) (GinDataPageGetData(page) + ((i)-1) * sizeof(ItemPointerData)))
 #define GinSizeOfDataPageItem(page) \
 	(GinPageIsLeaf(page) ? sizeof(ItemPointerData) : sizeof(PostingItem))
-#define GinDataPageGetItem(page,i)	\
-	(GinDataPageGetData(page) + ((i)-1) * GinSizeOfDataPageItem(page))
 
 #define GinDataPageGetFreeSpace(page)	\
 	(BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \
@@ -534,7 +538,8 @@ extern uint32 ginMergeItemPointers(ItemPointerData *dst,
 					 ItemPointerData *a, uint32 na,
 					 ItemPointerData *b, uint32 nb);
 
-extern void GinDataPageAddItem(Page page, void *data, OffsetNumber offset);
+extern void GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset);
+extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
 extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
 
 typedef struct