From f7eb3ee22ae86df2b1fec2e06727e77db5b4d12b Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sun, 16 May 2021 11:21:14 -0500
Subject: [PATCH 4/5] Allocate datum arrays in bulk, to avoid palloc overhead

---
 src/backend/partitioning/partbounds.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 490fe89eb8..961447ba5d 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -362,6 +362,7 @@ create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	int			i;
 	int			ndatums = 0;
 	int			greatest_modulus;
+	Datum		*datumptr;
 
 	boundinfo = (PartitionBoundInfoData *)
 		palloc0(sizeof(PartitionBoundInfoData));
@@ -406,12 +407,14 @@ create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	 * pairs) as there are partitions.  Indexes are simply values ranging from
 	 * 0 to (nparts - 1).
 	 */
+	datumptr = (Datum *) palloc0(ndatums * 2 * sizeof(Datum));
 	for (i = 0; i < nparts; i++)
 	{
 		int			modulus = hbounds[i].modulus;
 		int			remainder = hbounds[i].remainder;
 
-		boundinfo->datums[i] = (Datum *) palloc(2 * sizeof(Datum));
+		boundinfo->datums[i] = datumptr;
+		datumptr += 2;
 		boundinfo->datums[i][0] = Int32GetDatum(modulus);
 		boundinfo->datums[i][1] = Int32GetDatum(remainder);
 
@@ -472,6 +475,7 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	int			next_index = 0;
 	int			default_index = -1;
 	int			null_index = -1;
+	Datum		*datumptr;
 
 	boundinfo = (PartitionBoundInfoData *)
 		palloc0(sizeof(PartitionBoundInfoData));
@@ -541,11 +545,12 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	 * receive the same value. The value for a given partition is the index of
 	 * that partition's smallest datum in the all_values[] array.
 	 */
+	datumptr = (Datum *) palloc0(ndatums * sizeof(Datum));
 	for (i = 0; i < ndatums; i++)
 	{
 		int			orig_index = all_values[i].index;
 
-		boundinfo->datums[i] = (Datum *) palloc(sizeof(Datum));
+		boundinfo->datums[i] = datumptr++;
 		boundinfo->datums[i][0] = datumCopy(all_values[i].value,
 											key->parttypbyval[0],
 											key->parttyplen[0]);
@@ -609,6 +614,7 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	int			ndatums = 0;
 	int			default_index = -1;
 	int			next_index = 0;
+	Datum		*datumptr;
 
 	boundinfo = (PartitionBoundInfoData *)
 		palloc0(sizeof(PartitionBoundInfoData));
@@ -733,12 +739,13 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	boundinfo->nindexes = ndatums + 1;
 	boundinfo->indexes = (int *) palloc((ndatums + 1) * sizeof(int));
 
+	datumptr = (Datum *) palloc0(ndatums * key->partnatts * sizeof(Datum));
 	for (i = 0; i < ndatums; i++)
 	{
 		int			j;
 
-		boundinfo->datums[i] = (Datum *) palloc(key->partnatts *
-												sizeof(Datum));
+		boundinfo->datums[i] = datumptr;
+		datumptr += key->partnatts;
 		boundinfo->kind[i] = (PartitionRangeDatumKind *)
 			palloc(key->partnatts *
 				   sizeof(PartitionRangeDatumKind));
-- 
2.17.0

