diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index ed8e3ac324d768a4a91e2a67d1d73b9b943c78da..57c57997e3c7ecb8adc85fefa8a84a9c6e86dc53 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.51 1999/11/22 17:55:54 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.52 1999/12/26 03:48:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -267,6 +267,18 @@ _bt_insertonpg(Relation rel,
 										 * this but we need to be
 										 * consistent */
 
+	/*
+	 * Check whether the item can fit on a btree page at all.
+	 * (Eventually, we ought to try to apply TOAST methods if not.)
+	 * We actually need to be able to fit three items on every page,
+	 * so restrict any one item to 1/3 the per-page available space.
+	 * Note that at this point, itemsz doesn't include the ItemId.
+	 */
+	if (itemsz > (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData))
+		elog(ERROR, "btree: index item size %d exceeds maximum %d",
+			 itemsz,
+			 (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData));
+
 	/*
 	 * If we have to insert item on the leftmost page which is the first
 	 * page in the chain of duplicates then: 1. if scankey == hikey (i.e.
@@ -342,36 +354,42 @@ _bt_insertonpg(Relation rel,
 	{
 		OffsetNumber offnum = (P_RIGHTMOST(lpageop)) ? P_HIKEY : P_FIRSTKEY;
 		OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
-		ItemId		itid;
-		BTItem		previtem,
-					chkitem;
-		Size		maxsize;
-		Size		currsize;
-
-		itid = PageGetItemId(page, offnum);
-		previtem = (BTItem) PageGetItem(page, itid);
-		maxsize = currsize = (ItemIdGetLength(itid) + sizeof(ItemIdData));
-		for (offnum = OffsetNumberNext(offnum);
-			 offnum <= maxoff; offnum = OffsetNumberNext(offnum))
+
+		if (offnum < maxoff)	/* can't split unless at least 2 items... */
 		{
+			ItemId		itid;
+			BTItem		previtem,
+						chkitem;
+			Size		maxsize;
+			Size		currsize;
+
+			/* find largest group of identically-keyed items on page */
 			itid = PageGetItemId(page, offnum);
-			chkitem = (BTItem) PageGetItem(page, itid);
-			if (!_bt_itemcmp(rel, keysz, previtem, chkitem,
-							 BTEqualStrategyNumber))
+			previtem = (BTItem) PageGetItem(page, itid);
+			maxsize = currsize = (ItemIdGetLength(itid) + sizeof(ItemIdData));
+			for (offnum = OffsetNumberNext(offnum);
+				 offnum <= maxoff; offnum = OffsetNumberNext(offnum))
 			{
-				if (currsize > maxsize)
-					maxsize = currsize;
-				currsize = 0;
-				previtem = chkitem;
+				itid = PageGetItemId(page, offnum);
+				chkitem = (BTItem) PageGetItem(page, itid);
+				if (!_bt_itemcmp(rel, keysz, previtem, chkitem,
+								 BTEqualStrategyNumber))
+				{
+					if (currsize > maxsize)
+						maxsize = currsize;
+					currsize = 0;
+					previtem = chkitem;
+				}
+				currsize += (ItemIdGetLength(itid) + sizeof(ItemIdData));
 			}
-			currsize += (ItemIdGetLength(itid) + sizeof(ItemIdData));
+			if (currsize > maxsize)
+				maxsize = currsize;
+			/* Decide to split if largest group is > 1/2 page size */
+			maxsize += sizeof(PageHeaderData) +
+				MAXALIGN(sizeof(BTPageOpaqueData));
+			if (maxsize >= PageGetPageSize(page) / 2)
+				do_split = true;
 		}
-		if (currsize > maxsize)
-			maxsize = currsize;
-		maxsize += sizeof(PageHeaderData) +
-			MAXALIGN(sizeof(BTPageOpaqueData));
-		if (maxsize >= PageGetPageSize(page) / 2)
-			do_split = true;
 	}
 
 	if (do_split)