diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 64ad2d749b066ad9c57ccf43be143798106f8444..9c6625bba3a43a155ab2b60ff94abdd19c128315 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -148,16 +148,22 @@ gistinsert(PG_FUNCTION_ARGS)
  * pages are released; note that new tuple(s) are *not* on the root page
  * but in one of the new child pages.
  *
+ * If 'newblkno' is not NULL, returns the block number of page the first
+ * new/updated tuple was inserted to. Usually it's the given page, but could
+ * be its right sibling if the page was split.
+ *
  * Returns 'true' if the page was split, 'false' otherwise.
  */
 bool
 gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
 				Buffer buffer,
 				IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
+				BlockNumber *newblkno,
 				Buffer leftchildbuf,
 				List **splitinfo,
 				bool markfollowright)
 {
+	BlockNumber blkno = BufferGetBlockNumber(buffer);
 	Page		page = BufferGetPage(buffer);
 	bool		is_leaf = (GistPageIsLeaf(page)) ? true : false;
 	XLogRecPtr	recptr;
@@ -199,7 +205,6 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
 		BlockNumber oldrlink = InvalidBlockNumber;
 		GistNSN		oldnsn = 0;
 		SplitedPageLayout rootpg;
-		BlockNumber blkno = BufferGetBlockNumber(buffer);
 		bool		is_rootsplit;
 
 		is_rootsplit = (blkno == GIST_ROOT_BLKNO);
@@ -319,9 +324,19 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
 
 			for (i = 0; i < ptr->block.num; i++)
 			{
-				if (PageAddItem(ptr->page, (Item) data, IndexTupleSize((IndexTuple) data), i + FirstOffsetNumber, false, false) == InvalidOffsetNumber)
+				IndexTuple	thistup = (IndexTuple) data;
+
+				if (PageAddItem(ptr->page, (Item) data, IndexTupleSize(thistup), i + FirstOffsetNumber, false, false) == InvalidOffsetNumber)
 					elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(rel));
-				data += IndexTupleSize((IndexTuple) data);
+
+				/*
+				 * If this is the first inserted/updated tuple, let the caller
+				 * know which page it landed on.
+				 */
+				if (newblkno && ItemPointerEquals(&thistup->t_tid, &(*itup)->t_tid))
+					*newblkno = ptr->block.blkno;
+
+				data += IndexTupleSize(thistup);
 			}
 
 			/* Set up rightlinks */
@@ -436,6 +451,9 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
 			recptr = GetXLogRecPtrForTemp();
 			PageSetLSN(page, recptr);
 		}
+
+		if (newblkno)
+			*newblkno = blkno;
 	}
 
 	/*
@@ -1074,9 +1092,9 @@ gistinserttuple(GISTInsertState *state, GISTInsertStack *stack,
  *	  is kept pinned.
  *	- Lock and pin on 'rightchild' are always released.
  *
- * Returns 'true' if the page had to be split. Note that if the page had
- * be split, the inserted/updated might've been inserted to a right sibling
- * of stack->buffer instead of stack->buffer itself.
+ * Returns 'true' if the page had to be split. Note that if the page was
+ * split, the inserted/updated tuples might've been inserted to a right
+ * sibling of stack->buffer instead of stack->buffer itself.
  */
 static bool
 gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
@@ -1091,7 +1109,8 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
 	/* Insert the tuple(s) to the page, splitting the page if necessary */
 	is_split = gistplacetopage(state->r, state->freespace, giststate,
 							   stack->buffer,
-							   tuples, ntup, oldoffnum,
+							   tuples, ntup,
+							   oldoffnum, NULL,
 							   leftchild,
 							   &splitinfo,
 							   true);
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index 8caf4856763b68828c6f23d9c1df6c9a60f8e7b5..bcd95a8a4d85852f7adfd8e27fb7359c3c550b36 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -85,7 +85,7 @@ static void gistBufferingBuildInsert(GISTBuildState *buildstate,
 						 IndexTuple itup);
 static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup,
 				BlockNumber startblkno, int startlevel);
-static void gistbufferinginserttuples(GISTBuildState *buildstate,
+static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate,
 						  Buffer buffer, int level,
 						  IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
 						  BlockNumber parentblk, OffsetNumber downlinkoffnum);
@@ -621,9 +621,9 @@ gistProcessItup(GISTBuildState *buildstate, IndexTuple itup,
 		newtup = gistgetadjusted(indexrel, idxtuple, itup, giststate);
 		if (newtup)
 		{
-			gistbufferinginserttuples(buildstate, buffer, level,
-									  &newtup, 1, childoffnum,
-									InvalidBlockNumber, InvalidOffsetNumber);
+			blkno  = gistbufferinginserttuples(buildstate, buffer, level,
+											   &newtup, 1, childoffnum,
+									  InvalidBlockNumber, InvalidOffsetNumber);
 			/* gistbufferinginserttuples() released the buffer */
 		}
 		else
@@ -676,10 +676,14 @@ gistProcessItup(GISTBuildState *buildstate, IndexTuple itup,
  *
  * This is analogous with gistinserttuples() in the regular insertion code.
  *
+ * Returns the block number of the page where the (first) new or updated tuple
+ * was inserted. Usually that's the original page, but might be a sibling page
+ * if the original page was split.
+ *
  * Caller should hold a lock on 'buffer' on entry. This function will unlock
  * and unpin it.
  */
-static void
+static BlockNumber
 gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
 						  IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
 						  BlockNumber parentblk, OffsetNumber downlinkoffnum)
@@ -687,12 +691,13 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
 	GISTBuildBuffers *gfbb = buildstate->gfbb;
 	List	   *splitinfo;
 	bool		is_split;
+	BlockNumber	placed_to_blk = InvalidBlockNumber;
 
 	is_split = gistplacetopage(buildstate->indexrel,
 							   buildstate->freespace,
 							   buildstate->giststate,
 							   buffer,
-							   itup, ntup, oldoffnum,
+							   itup, ntup, oldoffnum, &placed_to_blk,
 							   InvalidBuffer,
 							   &splitinfo,
 							   false);
@@ -823,6 +828,8 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
 	}
 	else
 		UnlockReleaseBuffer(buffer);
+
+	return placed_to_blk;
 }
 
 /*
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 9af9a0cf8c14ca160ffadbeb98c9f582b4530383..52877ae293fdc28a12f0d0d8a03dc481eb62c49e 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -430,7 +430,8 @@ typedef struct
 
 extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
 				Buffer buffer,
-				IndexTuple *itup, int ntup, OffsetNumber oldoffnum,
+				IndexTuple *itup, int ntup,
+				OffsetNumber oldoffnum, BlockNumber *newblkno,
 				Buffer leftchildbuf,
 				List **splitinfo,
 				bool markleftchild);