From 388174a5f8039e5666d6e14c3e2467e622926d46 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Thu, 25 Dec 2025 11:00:26 +0800
Subject: [PATCH v3] Use array allocation helpers in more places

Author: Chao Li <lic@highgo.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/CAEoWx2m1Vo97Jg9=K7JAZ0xdkg5D=GkgOxZR1=EW7mUfy008fw@mail.gmail.com
---
 src/backend/access/common/tupdesc.c           |  6 ++--
 src/backend/access/gin/gindatapage.c          |  2 +-
 src/backend/access/gin/ginget.c               |  8 ++---
 src/backend/access/gin/ginpostinglist.c       |  6 ++--
 src/backend/access/gin/ginscan.c              |  8 ++---
 src/backend/access/gist/gistget.c             |  4 +--
 src/backend/access/gist/gistproc.c            | 10 +++----
 src/backend/access/gist/gistsplit.c           |  4 +--
 src/backend/access/nbtree/nbtinsert.c         | 10 +++----
 src/backend/access/nbtree/nbtpreprocesskeys.c | 12 ++++----
 src/backend/access/nbtree/nbtree.c            |  2 +-
 src/backend/access/transam/xact.c             |  4 +--
 src/backend/access/transam/xloginsert.c       |  6 ++--
 src/backend/catalog/dependency.c              | 23 +++++++--------
 src/backend/catalog/heap.c                    |  2 +-
 src/backend/catalog/namespace.c               |  2 +-
 src/backend/catalog/pg_constraint.c           |  6 ++--
 src/backend/commands/analyze.c                | 29 +++++++++----------
 src/backend/commands/async.c                  |  2 +-
 src/backend/commands/collationcmds.c          |  5 ++--
 src/backend/commands/explain.c                |  2 +-
 src/backend/commands/explain_state.c          |  4 +--
 src/backend/commands/functioncmds.c           | 10 +++----
 src/backend/storage/file/buffile.c            | 10 +++----
 24 files changed, 82 insertions(+), 95 deletions(-)

diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index d771a265b34..727212e3916 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -363,7 +363,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
 
 		if ((cpy->num_defval = constr->num_defval) > 0)
 		{
-			cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
+			cpy->defval = palloc_array(AttrDefault, cpy->num_defval);
 			memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
 			for (i = cpy->num_defval - 1; i >= 0; i--)
 				cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
@@ -371,7 +371,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
 
 		if (constr->missing)
 		{
-			cpy->missing = (AttrMissing *) palloc(tupdesc->natts * sizeof(AttrMissing));
+			cpy->missing = palloc_array(AttrMissing, tupdesc->natts);
 			memcpy(cpy->missing, constr->missing, tupdesc->natts * sizeof(AttrMissing));
 			for (i = tupdesc->natts - 1; i >= 0; i--)
 			{
@@ -388,7 +388,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
 
 		if ((cpy->num_check = constr->num_check) > 0)
 		{
-			cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
+			cpy->check = palloc_array(ConstrCheck, cpy->num_check);
 			memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
 			for (i = cpy->num_check - 1; i >= 0; i--)
 			{
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index c5d7db28077..6c25e8c320a 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -168,7 +168,7 @@ GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
 	{
 		ItemPointer tmp = dataLeafPageGetUncompressed(page, nitems);
 
-		result = palloc((*nitems) * sizeof(ItemPointerData));
+		result = palloc_array(ItemPointerData, *nitems);
 		memcpy(result, tmp, (*nitems) * sizeof(ItemPointerData));
 	}
 
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 6b148e69a8e..3027a50f64a 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -544,7 +544,7 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
 
 		key->nrequired = 0;
 		key->nadditional = key->nentries;
-		key->additionalEntries = palloc(key->nadditional * sizeof(GinScanEntry));
+		key->additionalEntries = palloc_array(GinScanEntry, key->nadditional);
 		for (i = 0; i < key->nadditional; i++)
 			key->additionalEntries[i] = key->scanEntry[i];
 	}
@@ -577,8 +577,8 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
 
 		key->nrequired = i + 1;
 		key->nadditional = key->nentries - key->nrequired;
-		key->requiredEntries = palloc(key->nrequired * sizeof(GinScanEntry));
-		key->additionalEntries = palloc(key->nadditional * sizeof(GinScanEntry));
+		key->requiredEntries = palloc_array(GinScanEntry, key->nrequired);
+		key->additionalEntries = palloc_array(GinScanEntry, key->nadditional);
 
 		j = 0;
 		for (i = 0; i < key->nrequired; i++)
@@ -595,7 +595,7 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
 
 		key->nrequired = 1;
 		key->nadditional = 0;
-		key->requiredEntries = palloc(1 * sizeof(GinScanEntry));
+		key->requiredEntries = palloc_array(GinScanEntry, key->nrequired);
 		key->requiredEntries[0] = key->scanEntry[0];
 	}
 	MemoryContextSwitchTo(oldCtx);
diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c
index d8dfcee4bde..74da185db06 100644
--- a/src/backend/access/gin/ginpostinglist.c
+++ b/src/backend/access/gin/ginpostinglist.c
@@ -308,7 +308,7 @@ ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_
 	 * Guess an initial size of the array.
 	 */
 	nallocated = segment->nbytes * 2 + 1;
-	result = palloc(nallocated * sizeof(ItemPointerData));
+	result = palloc_array(ItemPointerData, nallocated);
 
 	ndecoded = 0;
 	while ((char *) segment < endseg)
@@ -317,7 +317,7 @@ ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_
 		if (ndecoded >= nallocated)
 		{
 			nallocated *= 2;
-			result = repalloc(result, nallocated * sizeof(ItemPointerData));
+			result = repalloc_array(result, ItemPointerData, nallocated);
 		}
 
 		/* copy the first item */
@@ -335,7 +335,7 @@ ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_
 			if (ndecoded >= nallocated)
 			{
 				nallocated *= 2;
-				result = repalloc(result, nallocated * sizeof(ItemPointerData));
+				result = repalloc_array(result, ItemPointerData, nallocated);
 			}
 
 			val += decode_varbyte(&ptr);
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index fb929761ab7..178ea593fe2 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -282,15 +282,13 @@ ginNewScanKey(IndexScanDesc scan)
 	oldCtx = MemoryContextSwitchTo(so->keyCtx);
 
 	/* if no scan keys provided, allocate extra EVERYTHING GinScanKey */
-	so->keys = (GinScanKey)
-		palloc(Max(scan->numberOfKeys, 1) * sizeof(GinScanKeyData));
+	so->keys = palloc_array(GinScanKeyData, Max(scan->numberOfKeys, 1));
 	so->nkeys = 0;
 
 	/* initialize expansible array of GinScanEntry pointers */
 	so->totalentries = 0;
 	so->allocentries = 32;
-	so->entries = (GinScanEntry *)
-		palloc(so->allocentries * sizeof(GinScanEntry));
+	so->entries = palloc_array(GinScanEntry, so->allocentries);
 
 	so->isVoidRes = false;
 
@@ -423,7 +421,7 @@ ginNewScanKey(IndexScanDesc scan)
 		/* We'd better have made at least one normal key */
 		Assert(numExcludeOnly < so->nkeys);
 		/* Make a temporary array to hold the re-ordered scan keys */
-		tmpkeys = (GinScanKey) palloc(so->nkeys * sizeof(GinScanKeyData));
+		tmpkeys = palloc_array(GinScanKeyData, so->nkeys);
 		/* Re-order the keys ... */
 		iNormalKey = 0;
 		iExcludeOnly = so->nkeys - numExcludeOnly;
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 4d7c100d737..c946e818d8f 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -668,9 +668,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
 						MemoryContext oldCxt =
 							MemoryContextSwitchTo(so->giststate->scanCxt);
 
-						so->killedItems =
-							(OffsetNumber *) palloc(MaxIndexTuplesPerPage
-													* sizeof(OffsetNumber));
+						so->killedItems = palloc_array(OffsetNumber, MaxIndexTuplesPerPage);
 
 						MemoryContextSwitchTo(oldCxt);
 					}
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index bb84030b23d..7dd8920f34e 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -516,8 +516,8 @@ gist_box_picksplit(PG_FUNCTION_ARGS)
 	nentries = context.entriesCount = maxoff - FirstOffsetNumber + 1;
 
 	/* Allocate arrays for intervals along axes */
-	intervalsLower = (SplitInterval *) palloc(nentries * sizeof(SplitInterval));
-	intervalsUpper = (SplitInterval *) palloc(nentries * sizeof(SplitInterval));
+	intervalsLower = palloc_array(SplitInterval, nentries);
+	intervalsUpper = palloc_array(SplitInterval, nentries);
 
 	/*
 	 * Calculate the overall minimum bounding box over all the entries.
@@ -693,8 +693,8 @@ gist_box_picksplit(PG_FUNCTION_ARGS)
 	 */
 
 	/* Allocate vectors for results */
-	v->spl_left = (OffsetNumber *) palloc(nentries * sizeof(OffsetNumber));
-	v->spl_right = (OffsetNumber *) palloc(nentries * sizeof(OffsetNumber));
+	v->spl_left = palloc_array(OffsetNumber, nentries);
+	v->spl_right = palloc_array(OffsetNumber, nentries);
 	v->spl_nleft = 0;
 	v->spl_nright = 0;
 
@@ -707,7 +707,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS)
 	 * either group without affecting overlap along selected axis.
 	 */
 	commonEntriesCount = 0;
-	commonEntries = (CommonEntry *) palloc(nentries * sizeof(CommonEntry));
+	commonEntries = (CommonEntry *) palloc_array(CommonEntry, nentries);
 
 	/* Helper macros to place an entry in the left or right group */
 #define PLACE_LEFT(box, off)					\
diff --git a/src/backend/access/gist/gistsplit.c b/src/backend/access/gist/gistsplit.c
index dc899565320..dbea49e445f 100644
--- a/src/backend/access/gist/gistsplit.c
+++ b/src/backend/access/gist/gistsplit.c
@@ -587,8 +587,8 @@ gistSplitHalf(GIST_SPLITVEC *v, int len)
 	int			i;
 
 	v->spl_nright = v->spl_nleft = 0;
-	v->spl_left = (OffsetNumber *) palloc(len * sizeof(OffsetNumber));
-	v->spl_right = (OffsetNumber *) palloc(len * sizeof(OffsetNumber));
+	v->spl_left = palloc_array(OffsetNumber, len);
+	v->spl_right = palloc_array(OffsetNumber, len);
 	for (i = 1; i <= len; i++)
 		if (i < len / 2)
 			v->spl_right[v->spl_nright++] = i;
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index c8af97dd23d..3b945342d83 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -2876,8 +2876,8 @@ _bt_simpledel_pass(Relation rel, Buffer buffer, Relation heapRel,
 	delstate.bottomup = false;
 	delstate.bottomupfreespace = 0;
 	delstate.ndeltids = 0;
-	delstate.deltids = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexDelete));
-	delstate.status = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexStatus));
+	delstate.deltids = palloc_array(TM_IndexDelete, MaxTIDsPerBTreePage);
+	delstate.status = palloc_array(TM_IndexStatus, MaxTIDsPerBTreePage);
 
 	for (offnum = minoff;
 		 offnum <= maxoff;
@@ -3019,8 +3019,7 @@ _bt_deadblocks(Page page, OffsetNumber *deletable, int ndeletable,
 			if (ntids + 1 > spacentids)
 			{
 				spacentids *= 2;
-				tidblocks = (BlockNumber *)
-					repalloc(tidblocks, sizeof(BlockNumber) * spacentids);
+				tidblocks = repalloc_array(tidblocks, BlockNumber, spacentids);
 			}
 
 			tidblocks[ntids++] = ItemPointerGetBlockNumber(&itup->t_tid);
@@ -3032,8 +3031,7 @@ _bt_deadblocks(Page page, OffsetNumber *deletable, int ndeletable,
 			if (ntids + nposting > spacentids)
 			{
 				spacentids = Max(spacentids * 2, ntids + nposting);
-				tidblocks = (BlockNumber *)
-					repalloc(tidblocks, sizeof(BlockNumber) * spacentids);
+				tidblocks = repalloc_array(tidblocks, BlockNumber, spacentids);
 			}
 
 			for (int j = 0; j < nposting; j++)
diff --git a/src/backend/access/nbtree/nbtpreprocesskeys.c b/src/backend/access/nbtree/nbtpreprocesskeys.c
index 39c0a5d610f..31bdf359327 100644
--- a/src/backend/access/nbtree/nbtpreprocesskeys.c
+++ b/src/backend/access/nbtree/nbtpreprocesskeys.c
@@ -258,8 +258,8 @@ _bt_preprocess_keys(IndexScanDesc scan)
 		 * a skip array's scan key
 		 */
 		if (numberOfKeys > scan->numberOfKeys)
-			so->keyData = repalloc(so->keyData,
-								   numberOfKeys * sizeof(ScanKeyData));
+			so->keyData = repalloc_array(so->keyData,
+										 ScanKeyData, numberOfKeys);
 	}
 	else
 		inkeys = scan->keyData;
@@ -1653,14 +1653,14 @@ _bt_unmark_keys(IndexScanDesc scan, int *keyDataMap)
 	 * Next, allocate temp arrays: one for required keys that'll remain
 	 * required, the other for all remaining keys
 	 */
-	unmarkKeys = palloc(nunmark * sizeof(ScanKeyData));
-	keepKeys = palloc((so->numberOfKeys - nunmark) * sizeof(ScanKeyData));
+	unmarkKeys = palloc_array(ScanKeyData, nunmark);
+	keepKeys = palloc_array(ScanKeyData, so->numberOfKeys - nunmark);
 	nunmarked = 0;
 	nkept = 0;
 	if (so->numArrayKeys)
 	{
-		unmarkOrderProcs = palloc(nunmark * sizeof(FmgrInfo));
-		keepOrderProcs = palloc((so->numberOfKeys - nunmark) * sizeof(FmgrInfo));
+		unmarkOrderProcs = palloc_array(FmgrInfo, nunmark);
+		keepOrderProcs = palloc_array(FmgrInfo, so->numberOfKeys - nunmark);
 	}
 
 	/*
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index aed74590cf4..e182266e74e 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -351,7 +351,7 @@ btbeginscan(Relation rel, int nkeys, int norderbys)
 	BTScanPosInvalidate(so->currPos);
 	BTScanPosInvalidate(so->markPos);
 	if (scan->numberOfKeys > 0)
-		so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
+		so->keyData = palloc_array(ScanKeyData, scan->numberOfKeys);
 	else
 		so->keyData = NULL;
 
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index aafc53e0164..500b276c0d9 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1719,8 +1719,8 @@ AtSubCommit_childXids(void)
 				MemoryContextAlloc(TopTransactionContext,
 								   new_maxChildXids * sizeof(TransactionId));
 		else
-			new_childXids = repalloc(s->parent->childXids,
-									 new_maxChildXids * sizeof(TransactionId));
+			new_childXids = repalloc_array(s->parent->childXids,
+										   TransactionId, new_maxChildXids);
 
 		s->parent->childXids = new_childXids;
 		s->parent->maxChildXids = new_maxChildXids;
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index e4a819efeeb..57b59ab5c0e 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -200,8 +200,8 @@ XLogEnsureRecordSpace(int max_block_id, int ndatas)
 
 	if (nbuffers > max_registered_buffers)
 	{
-		registered_buffers = (registered_buffer *)
-			repalloc(registered_buffers, sizeof(registered_buffer) * nbuffers);
+		registered_buffers =
+			repalloc_array(registered_buffers, registered_buffer, nbuffers);
 
 		/*
 		 * At least the padding bytes in the structs must be zeroed, because
@@ -214,7 +214,7 @@ XLogEnsureRecordSpace(int max_block_id, int ndatas)
 
 	if (ndatas > max_rdatas)
 	{
-		rdatas = (XLogRecData *) repalloc(rdatas, sizeof(XLogRecData) * ndatas);
+		rdatas = repalloc_array(rdatas, XLogRecData, ndatas);
 		max_rdatas = ndatas;
 	}
 }
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index fdb8e67e1f5..c3f778dca6d 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -966,9 +966,8 @@ findDependentObjects(const ObjectAddress *object,
 		{
 			/* enlarge array if needed */
 			maxDependentObjects *= 2;
-			dependentObjects = (ObjectAddressAndFlags *)
-				repalloc(dependentObjects,
-						 maxDependentObjects * sizeof(ObjectAddressAndFlags));
+			dependentObjects = repalloc_array(dependentObjects,
+											  ObjectAddressAndFlags, maxDependentObjects);
 		}
 
 		dependentObjects[numDependentObjects].obj = otherObject;
@@ -2710,8 +2709,7 @@ add_object_address(Oid classId, Oid objectId, int32 subId,
 	if (addrs->numrefs >= addrs->maxrefs)
 	{
 		addrs->maxrefs *= 2;
-		addrs->refs = (ObjectAddress *)
-			repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
+		addrs->refs = repalloc_array(addrs->refs, ObjectAddress, addrs->maxrefs);
 		Assert(!addrs->extras);
 	}
 	/* record this item */
@@ -2737,8 +2735,8 @@ add_exact_object_address(const ObjectAddress *object,
 	if (addrs->numrefs >= addrs->maxrefs)
 	{
 		addrs->maxrefs *= 2;
-		addrs->refs = (ObjectAddress *)
-			repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
+		addrs->refs = repalloc_array(addrs->refs,
+									 ObjectAddress, addrs->maxrefs);
 		Assert(!addrs->extras);
 	}
 	/* record this item */
@@ -2762,17 +2760,16 @@ add_exact_object_address_extra(const ObjectAddress *object,
 
 	/* allocate extra space if first time */
 	if (!addrs->extras)
-		addrs->extras = (ObjectAddressExtra *)
-			palloc(addrs->maxrefs * sizeof(ObjectAddressExtra));
+		addrs->extras = palloc_array(ObjectAddressExtra, addrs->maxrefs);
 
 	/* enlarge array if needed */
 	if (addrs->numrefs >= addrs->maxrefs)
 	{
 		addrs->maxrefs *= 2;
-		addrs->refs = (ObjectAddress *)
-			repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
-		addrs->extras = (ObjectAddressExtra *)
-			repalloc(addrs->extras, addrs->maxrefs * sizeof(ObjectAddressExtra));
+		addrs->refs = repalloc_array(addrs->refs,
+									 ObjectAddress, addrs->maxrefs);
+		addrs->extras = repalloc_array(addrs->extras,
+									   ObjectAddressExtra, addrs->maxrefs);
 	}
 	/* record this item */
 	item = addrs->refs + addrs->numrefs;
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 5748aa9a1a9..e454fa8755e 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -2174,7 +2174,7 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr,
 		ListCell   *vl;
 		int			i = 0;
 
-		attNos = (int16 *) palloc(keycount * sizeof(int16));
+		attNos = palloc_array(int16, keycount);
 		foreach(vl, varList)
 		{
 			Var		   *var = (Var *) lfirst(vl);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 56b87d878e8..f21dce6a23b 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -1650,7 +1650,7 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
 	Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
 
 	/* initialize state for matching */
-	*argnumbers = (int *) palloc(pronargs * sizeof(int));
+	*argnumbers = palloc_array(int, pronargs);
 	memset(arggiven, false, pronargs * sizeof(bool));
 
 	/* there are numposargs positional args before the named args */
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index b12765ae691..a21d673a65a 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -118,7 +118,7 @@ CreateConstraintEntry(const char *constraintName,
 	{
 		Datum	   *conkey;
 
-		conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
+		conkey = palloc_array(Datum, constraintNKeys);
 		for (i = 0; i < constraintNKeys; i++)
 			conkey[i] = Int16GetDatum(constraintKey[i]);
 		conkeyArray = construct_array_builtin(conkey, constraintNKeys, INT2OID);
@@ -131,7 +131,7 @@ CreateConstraintEntry(const char *constraintName,
 		Datum	   *fkdatums;
 		int			nkeys = Max(foreignNKeys, numFkDeleteSetCols);
 
-		fkdatums = (Datum *) palloc(nkeys * sizeof(Datum));
+		fkdatums = palloc_array(Datum, nkeys);
 		for (i = 0; i < foreignNKeys; i++)
 			fkdatums[i] = Int16GetDatum(foreignKey[i]);
 		confkeyArray = construct_array_builtin(fkdatums, foreignNKeys, INT2OID);
@@ -167,7 +167,7 @@ CreateConstraintEntry(const char *constraintName,
 	{
 		Datum	   *opdatums;
 
-		opdatums = (Datum *) palloc(constraintNKeys * sizeof(Datum));
+		opdatums = palloc_array(Datum, constraintNKeys);
 		for (i = 0; i < constraintNKeys; i++)
 			opdatums[i] = ObjectIdGetDatum(exclOp[i]);
 		conexclopArray = construct_array_builtin(opdatums, constraintNKeys, OIDOID);
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index eeed91be266..dd2ac5518c0 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -529,7 +529,7 @@ do_analyze_rel(Relation onerel, const VacuumParams params,
 	/*
 	 * Acquire the sample rows
 	 */
-	rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
+	rows = palloc_array(HeapTuple, targrows);
 	pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE,
 								 inh ? PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS_INH :
 								 PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS);
@@ -924,8 +924,8 @@ compute_index_stats(Relation onerel, double totalrows,
 		predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
 
 		/* Compute and save index expression values */
-		exprvals = (Datum *) palloc(numrows * attr_cnt * sizeof(Datum));
-		exprnulls = (bool *) palloc(numrows * attr_cnt * sizeof(bool));
+		exprvals = palloc_array(Datum, numrows * attr_cnt);
+		exprnulls = palloc_array(bool, numrows * attr_cnt);
 		numindexrows = 0;
 		tcnt = 0;
 		for (rowno = 0; rowno < numrows; rowno++)
@@ -1440,10 +1440,9 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
 	 * Identify acquirefuncs to use, and count blocks in all the relations.
 	 * The result could overflow BlockNumber, so we use double arithmetic.
 	 */
-	rels = (Relation *) palloc(list_length(tableOIDs) * sizeof(Relation));
-	acquirefuncs = (AcquireSampleRowsFunc *)
-		palloc(list_length(tableOIDs) * sizeof(AcquireSampleRowsFunc));
-	relblocks = (double *) palloc(list_length(tableOIDs) * sizeof(double));
+	rels = palloc_array(Relation, list_length(tableOIDs));
+	acquirefuncs = palloc_array(AcquireSampleRowsFunc, list_length(tableOIDs));
+	relblocks = palloc_array(double, list_length(tableOIDs));
 	totalblocks = 0;
 	nrels = 0;
 	has_child = false;
@@ -1718,7 +1717,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
 			if (stats->stanumbers[k] != NULL)
 			{
 				int			nnum = stats->numnumbers[k];
-				Datum	   *numdatums = (Datum *) palloc(nnum * sizeof(Datum));
+				Datum	   *numdatums = palloc_array(Datum, nnum);
 				ArrayType  *arry;
 
 				for (n = 0; n < nnum; n++)
@@ -2090,7 +2089,7 @@ compute_distinct_stats(VacAttrStatsP stats,
 	track_max = 2 * num_mcv;
 	if (track_max < 10)
 		track_max = 10;
-	track = (TrackItem *) palloc(track_max * sizeof(TrackItem));
+	track = palloc_array(TrackItem, track_max);
 	track_cnt = 0;
 
 	fmgr_info(mystats->eqfunc, &f_cmpeq);
@@ -2327,7 +2326,7 @@ compute_distinct_stats(VacAttrStatsP stats,
 
 			if (num_mcv > 0)
 			{
-				mcv_counts = (int *) palloc(num_mcv * sizeof(int));
+				mcv_counts = palloc_array(int, num_mcv);
 				for (i = 0; i < num_mcv; i++)
 					mcv_counts[i] = track[i].count;
 
@@ -2347,8 +2346,8 @@ compute_distinct_stats(VacAttrStatsP stats,
 
 			/* Must copy the target values into anl_context */
 			old_context = MemoryContextSwitchTo(stats->anl_context);
-			mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
-			mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
+			mcv_values = palloc_array(Datum, num_mcv);
+			mcv_freqs = palloc_array(float4, num_mcv);
 			for (i = 0; i < num_mcv; i++)
 			{
 				mcv_values[i] = datumCopy(track[i].value,
@@ -2426,9 +2425,9 @@ compute_scalar_stats(VacAttrStatsP stats,
 	int			num_bins = stats->attstattarget;
 	StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
 
-	values = (ScalarItem *) palloc(samplerows * sizeof(ScalarItem));
-	tupnoLink = (int *) palloc(samplerows * sizeof(int));
-	track = (ScalarMCVItem *) palloc(num_mcv * sizeof(ScalarMCVItem));
+	values = palloc_array(ScalarItem, samplerows);
+	tupnoLink = palloc_array(int, samplerows);
+	track = palloc_array(ScalarMCVItem, num_mcv);
 
 	memset(&ssup, 0, sizeof(ssup));
 	ssup.ssup_cxt = CurrentMemoryContext;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 5c9a56c3d40..3c83c8e91b9 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -1112,7 +1112,7 @@ pg_listening_channels(PG_FUNCTION_ARGS)
 			MemoryContext oldcontext;
 
 			oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
-			status = (HASH_SEQ_STATUS *) palloc(sizeof(HASH_SEQ_STATUS));
+			status = palloc_object(HASH_SEQ_STATUS);
 			hash_seq_init(status, localChannelTable);
 			funcctx->user_fctx = status;
 			MemoryContextSwitchTo(oldcontext);
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 0bc31ec2b6f..cfa0e4610d9 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -867,7 +867,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
 
 		/* expansible array of aliases */
 		maxaliases = 100;
-		aliases = (CollAliasData *) palloc(maxaliases * sizeof(CollAliasData));
+		aliases = palloc_array(CollAliasData, maxaliases);
 		naliases = 0;
 
 		locale_a_handle = OpenPipeStream("locale -a", "r");
@@ -911,8 +911,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
 				if (naliases >= maxaliases)
 				{
 					maxaliases *= 2;
-					aliases = (CollAliasData *)
-						repalloc(aliases, maxaliases * sizeof(CollAliasData));
+					aliases = repalloc_array(aliases, CollAliasData, maxaliases);
 				}
 				aliases[naliases].localename = pstrdup(localebuf);
 				aliases[naliases].alias = pstrdup(alias);
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 296ea8a1ed2..1d36fcb35af 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -5015,7 +5015,7 @@ ExplainCreateWorkersState(int num_workers)
 	wstate->worker_inited = (bool *) palloc0(num_workers * sizeof(bool));
 	wstate->worker_str = (StringInfoData *)
 		palloc0(num_workers * sizeof(StringInfoData));
-	wstate->worker_state_save = (int *) palloc(num_workers * sizeof(int));
+	wstate->worker_state_save = palloc_array(int, num_workers);
 	return wstate;
 }
 
diff --git a/src/backend/commands/explain_state.c b/src/backend/commands/explain_state.c
index 77f59b8e500..e1cf7db92cf 100644
--- a/src/backend/commands/explain_state.c
+++ b/src/backend/commands/explain_state.c
@@ -343,8 +343,8 @@ RegisterExtensionExplainOption(const char *option_name,
 	{
 		int			i = pg_nextpower2_32(ExplainExtensionOptionsAssigned + 1);
 
-		ExplainExtensionOptionArray = (ExplainExtensionOption *)
-			repalloc(ExplainExtensionOptionArray, i * sizeof(ExplainExtensionOption));
+		ExplainExtensionOptionArray = repalloc_array(ExplainExtensionOptionArray,
+													 ExplainExtensionOption, i);
 		ExplainExtensionOptionsAllocated = i;
 	}
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3afd762e9dc..9133606d949 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -213,10 +213,10 @@ interpret_function_parameter_list(ParseState *pstate,
 	*variadicArgType = InvalidOid;	/* default result */
 	*requiredResultType = InvalidOid;	/* default result */
 
-	inTypes = (Oid *) palloc(parameterCount * sizeof(Oid));
-	allTypes = (Datum *) palloc(parameterCount * sizeof(Datum));
-	paramModes = (Datum *) palloc(parameterCount * sizeof(Datum));
-	paramNames = (Datum *) palloc0(parameterCount * sizeof(Datum));
+	inTypes = palloc_array(Oid, parameterCount);
+	allTypes = palloc_array(Datum, parameterCount);
+	paramModes = palloc_array(Datum, parameterCount);
+	paramNames = palloc0_array(Datum, parameterCount);
 	*parameterDefaults = NIL;
 
 	/* Scan the list and extract data into work arrays */
@@ -918,7 +918,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
 
 		pinfo->fname = funcname;
 		pinfo->nargs = list_length(parameterTypes);
-		pinfo->argtypes = (Oid *) palloc(pinfo->nargs * sizeof(Oid));
+		pinfo->argtypes = palloc_array(Oid, pinfo->nargs);
 		pinfo->argnames = (char **) palloc(pinfo->nargs * sizeof(char *));
 		for (int i = 0; i < list_length(parameterTypes); i++)
 		{
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index c4afe4d368a..e2e3a7c4854 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -141,7 +141,7 @@ makeBufFile(File firstfile)
 {
 	BufFile    *file = makeBufFileCommon(1);
 
-	file->files = palloc_object(File);
+	file->files = palloc_array(File, 1);
 	file->files[0] = firstfile;
 	file->readOnly = false;
 	file->fileset = NULL;
@@ -172,8 +172,7 @@ extendBufFile(BufFile *file)
 
 	CurrentResourceOwner = oldowner;
 
-	file->files = (File *) repalloc(file->files,
-									(file->numFiles + 1) * sizeof(File));
+	file->files = repalloc_array(file->files, File, file->numFiles + 1);
 	file->files[file->numFiles] = pfile;
 	file->numFiles++;
 }
@@ -272,7 +271,7 @@ BufFileCreateFileSet(FileSet *fileset, const char *name)
 	file = makeBufFileCommon(1);
 	file->fileset = fileset;
 	file->name = pstrdup(name);
-	file->files = palloc_object(File);
+	file->files = palloc_array(File, 1);
 	file->files[0] = MakeNewFileSetSegment(file, 0);
 	file->readOnly = false;
 
@@ -911,8 +910,7 @@ BufFileAppend(BufFile *target, BufFile *source)
 	if (target->resowner != source->resowner)
 		elog(ERROR, "could not append BufFile with non-matching resource owner");
 
-	target->files = (File *)
-		repalloc(target->files, sizeof(File) * newNumFiles);
+	target->files = repalloc_array(target->files, File, newNumFiles);
 	for (i = target->numFiles; i < newNumFiles; i++)
 		target->files[i] = source->files[i - target->numFiles];
 	target->numFiles = newNumFiles;
-- 
2.50.1 (Apple Git-155)

