diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index c8770cc..b7ddbe5 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -782,10 +782,13 @@ partition_bounds_copy(PartitionBoundInfo src,
 					  PartitionKey key)
 {
 	PartitionBoundInfo dest;
-	int			i;
+	bool		hash_part = (key->strategy == PARTITION_STRATEGY_HASH);
+	Datum *alldatums;
 	int			ndatums;
 	int			partnatts;
+	int			natts;
 	int			num_indexes;
+	int			i;
 
 	dest = (PartitionBoundInfo) palloc(sizeof(PartitionBoundInfoData));
 
@@ -793,65 +796,69 @@ partition_bounds_copy(PartitionBoundInfo src,
 	ndatums = dest->ndatums = src->ndatums;
 	partnatts = key->partnatts;
 
-	num_indexes = get_partition_bound_num_indexes(src);
-
 	/* List partitioned tables have only a single partition key. */
 	Assert(key->strategy != PARTITION_STRATEGY_LIST || partnatts == 1);
 
-	dest->datums = (Datum **) palloc(sizeof(Datum *) * ndatums);
-
 	if (src->kind != NULL)
 	{
+		PartitionRangeDatumKind *allkinds;
+
 		dest->kind = (PartitionRangeDatumKind **) palloc(ndatums *
 														 sizeof(PartitionRangeDatumKind *));
+		allkinds = (PartitionRangeDatumKind *) palloc(ndatums * partnatts *
+													  sizeof(PartitionRangeDatumKind));
+
 		for (i = 0; i < ndatums; i++)
 		{
-			dest->kind[i] = (PartitionRangeDatumKind *) palloc(partnatts *
-															   sizeof(PartitionRangeDatumKind));
+			dest->kind[i] = allkinds;
+			allkinds += partnatts;
 
 			memcpy(dest->kind[i], src->kind[i],
-				   sizeof(PartitionRangeDatumKind) * key->partnatts);
+				   sizeof(PartitionRangeDatumKind) * partnatts);
 		}
 	}
 	else
 		dest->kind = NULL;
 
+	dest->datums = (Datum **) palloc(sizeof(Datum *) * ndatums);
+
+	/*
+	 * For hash partitioning, datums arrays will have two elements - modulus
+	 * and remainder.
+	 */
+	natts = hash_part ? 2 : partnatts;
+
+	alldatums = (Datum *) palloc(sizeof(Datum) * natts * ndatums);
+
 	for (i = 0; i < ndatums; i++)
 	{
-		int			j;
+		dest->datums[i] = alldatums;
+		alldatums += natts;
 
 		/*
-		 * For a corresponding to hash partition, datums array will have two
-		 * elements - modulus and remainder.
+		 * For hash partitioning, we know that both datums are present and
+		 * pass-by-value (since they're int4s), so just memcpy the datum
+		 * array.  Otherwise we have to apply datumCopy.
 		 */
-		bool		hash_part = (key->strategy == PARTITION_STRATEGY_HASH);
-		int			natts = hash_part ? 2 : partnatts;
-
-		dest->datums[i] = (Datum *) palloc(sizeof(Datum) * natts);
-
-		for (j = 0; j < natts; j++)
+		if (hash_part)
 		{
-			bool		byval;
-			int			typlen;
-
-			if (hash_part)
-			{
-				typlen = sizeof(int32); /* Always int4 */
-				byval = true;	/* int4 is pass-by-value */
-			}
-			else
+			memcpy(dest->datums[i], src->datums[i], 2 * sizeof(Datum));
+		}
+		else
+		{
+			for (int j = 0; j < natts; j++)
 			{
-				byval = key->parttypbyval[j];
-				typlen = key->parttyplen[j];
+				if (dest->kind == NULL ||
+					dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE)
+					dest->datums[i][j] = datumCopy(src->datums[i][j],
+												   key->parttypbyval[j],
+												   key->parttyplen[j]);
 			}
-
-			if (dest->kind == NULL ||
-				dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE)
-				dest->datums[i][j] = datumCopy(src->datums[i][j],
-											   byval, typlen);
 		}
 	}
 
+	num_indexes = get_partition_bound_num_indexes(src);
+
 	dest->indexes = (int *) palloc(sizeof(int) * num_indexes);
 	memcpy(dest->indexes, src->indexes, sizeof(int) * num_indexes);
 
