diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 1be96517df946f24a7b191800a35d7719862549c..d5391e8b983a0df4827b03b105272a665345bb89 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -2500,6 +2500,7 @@ array_set_slice(ArrayType *array,
 	{
 		/*
 		 * here we must allow for possibility of slice larger than orig array
+		 * and/or not adjacent to orig array subscripts
 		 */
 		int			oldlb = ARR_LBOUND(array)[0];
 		int			oldub = oldlb + ARR_DIMS(array)[0] - 1;
@@ -2508,10 +2509,12 @@ array_set_slice(ArrayType *array,
 		char	   *oldarraydata = ARR_DATA_PTR(array);
 		bits8	   *oldarraybitmap = ARR_NULLBITMAP(array);
 
+		/* count/size of old array entries that will go before the slice */
 		itemsbefore = Min(slicelb, oldub + 1) - oldlb;
 		lenbefore = array_nelems_size(oldarraydata, 0, oldarraybitmap,
 									  itemsbefore,
 									  elmlen, elmbyval, elmalign);
+		/* count/size of old array entries that will be replaced by slice */
 		if (slicelb > sliceub)
 		{
 			nolditems = 0;
@@ -2525,7 +2528,8 @@ array_set_slice(ArrayType *array,
 											nolditems,
 											elmlen, elmbyval, elmalign);
 		}
-		itemsafter = oldub - sliceub;
+		/* count/size of old array entries that will go after the slice */
+		itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
 		lenafter = olddatasize - lenbefore - olditemsize;
 	}