Skip to content

Commit b4b7ce8

Browse files
committed
Add repalloc0 and repalloc0_array
These zero out the space added by repalloc. This is a common pattern that is quite hairy to code by hand. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/b66dfc89-9365-cb57-4e1f-b7d31813eeec@enterprisedb.com
1 parent 30d98e1 commit b4b7ce8

File tree

10 files changed

+48
-71
lines changed

10 files changed

+48
-71
lines changed

src/backend/executor/nodeHash.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -940,12 +940,8 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable)
940940
else
941941
{
942942
/* enlarge arrays and zero out added entries */
943-
hashtable->innerBatchFile = repalloc_array(hashtable->innerBatchFile, BufFile *, nbatch);
944-
hashtable->outerBatchFile = repalloc_array(hashtable->outerBatchFile, BufFile *, nbatch);
945-
MemSet(hashtable->innerBatchFile + oldnbatch, 0,
946-
(nbatch - oldnbatch) * sizeof(BufFile *));
947-
MemSet(hashtable->outerBatchFile + oldnbatch, 0,
948-
(nbatch - oldnbatch) * sizeof(BufFile *));
943+
hashtable->innerBatchFile = repalloc0_array(hashtable->innerBatchFile, BufFile *, oldnbatch, nbatch);
944+
hashtable->outerBatchFile = repalloc0_array(hashtable->outerBatchFile, BufFile *, oldnbatch, nbatch);
949945
}
950946

951947
MemoryContextSwitchTo(oldcxt);

src/backend/libpq/be-fsstubs.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -696,19 +696,16 @@ newLOfd(void)
696696
newsize = 64;
697697
cookies = (LargeObjectDesc **)
698698
MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *));
699-
cookies_size = newsize;
700699
}
701700
else
702701
{
703702
/* Double size of array */
704703
i = cookies_size;
705704
newsize = cookies_size * 2;
706-
cookies = (LargeObjectDesc **)
707-
repalloc(cookies, newsize * sizeof(LargeObjectDesc *));
708-
MemSet(cookies + cookies_size, 0,
709-
(newsize - cookies_size) * sizeof(LargeObjectDesc *));
710-
cookies_size = newsize;
705+
cookies =
706+
repalloc0_array(cookies, LargeObjectDesc *, cookies_size, newsize);
711707
}
708+
cookies_size = newsize;
712709

713710
return i;
714711
}

src/backend/optimizer/util/placeholder.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,11 @@ find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
133133
while (phinfo->phid >= new_size)
134134
new_size *= 2;
135135
if (root->placeholder_array)
136-
{
137-
root->placeholder_array = (PlaceHolderInfo **)
138-
repalloc(root->placeholder_array,
139-
sizeof(PlaceHolderInfo *) * new_size);
140-
MemSet(root->placeholder_array + root->placeholder_array_size, 0,
141-
sizeof(PlaceHolderInfo *) * (new_size - root->placeholder_array_size));
142-
}
136+
root->placeholder_array =
137+
repalloc0_array(root->placeholder_array, PlaceHolderInfo *, root->placeholder_array_size, new_size);
143138
else
144-
root->placeholder_array = (PlaceHolderInfo **)
145-
palloc0(new_size * sizeof(PlaceHolderInfo *));
139+
root->placeholder_array =
140+
palloc0_array(PlaceHolderInfo *, new_size);
146141
root->placeholder_array_size = new_size;
147142
}
148143
root->placeholder_array[phinfo->phid] = phinfo;

src/backend/optimizer/util/relnode.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -157,31 +157,18 @@ expand_planner_arrays(PlannerInfo *root, int add_size)
157157

158158
new_size = root->simple_rel_array_size + add_size;
159159

160-
root->simple_rel_array = (RelOptInfo **)
161-
repalloc(root->simple_rel_array,
162-
sizeof(RelOptInfo *) * new_size);
163-
MemSet(root->simple_rel_array + root->simple_rel_array_size,
164-
0, sizeof(RelOptInfo *) * add_size);
160+
root->simple_rel_array =
161+
repalloc0_array(root->simple_rel_array, RelOptInfo *, root->simple_rel_array_size, new_size);
165162

166-
root->simple_rte_array = (RangeTblEntry **)
167-
repalloc(root->simple_rte_array,
168-
sizeof(RangeTblEntry *) * new_size);
169-
MemSet(root->simple_rte_array + root->simple_rel_array_size,
170-
0, sizeof(RangeTblEntry *) * add_size);
163+
root->simple_rte_array =
164+
repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size);
171165

172166
if (root->append_rel_array)
173-
{
174-
root->append_rel_array = (AppendRelInfo **)
175-
repalloc(root->append_rel_array,
176-
sizeof(AppendRelInfo *) * new_size);
177-
MemSet(root->append_rel_array + root->simple_rel_array_size,
178-
0, sizeof(AppendRelInfo *) * add_size);
179-
}
167+
root->append_rel_array =
168+
repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size);
180169
else
181-
{
182-
root->append_rel_array = (AppendRelInfo **)
183-
palloc0(sizeof(AppendRelInfo *) * new_size);
184-
}
170+
root->append_rel_array =
171+
palloc0_array(AppendRelInfo *, new_size);
185172

186173
root->simple_rel_array_size = new_size;
187174
}

src/backend/parser/parse_param.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,10 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref)
145145
{
146146
/* Need to enlarge param array */
147147
if (*parstate->paramTypes)
148-
*parstate->paramTypes = (Oid *) repalloc(*parstate->paramTypes,
149-
paramno * sizeof(Oid));
148+
*parstate->paramTypes = repalloc0_array(*parstate->paramTypes, Oid,
149+
*parstate->numParams, paramno);
150150
else
151-
*parstate->paramTypes = (Oid *) palloc(paramno * sizeof(Oid));
152-
/* Zero out the previously-unreferenced slots */
153-
MemSet(*parstate->paramTypes + *parstate->numParams,
154-
0,
155-
(paramno - *parstate->numParams) * sizeof(Oid));
151+
*parstate->paramTypes = palloc0_array(Oid, paramno);
156152
*parstate->numParams = paramno;
157153
}
158154

src/backend/storage/lmgr/lwlock.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -668,13 +668,8 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name)
668668
MemoryContextAllocZero(TopMemoryContext,
669669
newalloc * sizeof(char *));
670670
else
671-
{
672-
LWLockTrancheNames = (const char **)
673-
repalloc(LWLockTrancheNames, newalloc * sizeof(char *));
674-
memset(LWLockTrancheNames + LWLockTrancheNamesAllocated,
675-
0,
676-
(newalloc - LWLockTrancheNamesAllocated) * sizeof(char *));
677-
}
671+
LWLockTrancheNames =
672+
repalloc0_array(LWLockTrancheNames, const char *, LWLockTrancheNamesAllocated, newalloc);
678673
LWLockTrancheNamesAllocated = newalloc;
679674
}
680675

src/backend/utils/adt/ruleutils.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4855,14 +4855,9 @@ expand_colnames_array_to(deparse_columns *colinfo, int n)
48554855
if (n > colinfo->num_cols)
48564856
{
48574857
if (colinfo->colnames == NULL)
4858-
colinfo->colnames = (char **) palloc0(n * sizeof(char *));
4858+
colinfo->colnames = palloc0_array(char *, n);
48594859
else
4860-
{
4861-
colinfo->colnames = (char **) repalloc(colinfo->colnames,
4862-
n * sizeof(char *));
4863-
memset(colinfo->colnames + colinfo->num_cols, 0,
4864-
(n - colinfo->num_cols) * sizeof(char *));
4865-
}
4860+
colinfo->colnames = repalloc0_array(colinfo->colnames, char *, colinfo->num_cols, n);
48664861
colinfo->num_cols = n;
48674862
}
48684863
}

src/backend/utils/cache/typcache.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,14 +1714,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17141714
{
17151715
int32 newlen = pg_nextpower2_32(typmod + 1);
17161716

1717-
RecordCacheArray = (TupleDesc *) repalloc(RecordCacheArray,
1718-
newlen * sizeof(TupleDesc));
1719-
memset(RecordCacheArray + RecordCacheArrayLen, 0,
1720-
(newlen - RecordCacheArrayLen) * sizeof(TupleDesc));
1721-
RecordIdentifierArray = (uint64 *) repalloc(RecordIdentifierArray,
1722-
newlen * sizeof(uint64));
1723-
memset(RecordIdentifierArray + RecordCacheArrayLen, 0,
1724-
(newlen - RecordCacheArrayLen) * sizeof(uint64));
1717+
RecordCacheArray = repalloc0_array(RecordCacheArray, TupleDesc, RecordCacheArrayLen, newlen);
1718+
RecordIdentifierArray = repalloc0_array(RecordIdentifierArray, uint64, RecordCacheArrayLen, newlen);
17251719
RecordCacheArrayLen = newlen;
17261720
}
17271721
}

src/backend/utils/mmgr/mcxt.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,26 @@ repalloc_extended(void *pointer, Size size, int flags)
13951395
return ret;
13961396
}
13971397

1398+
/*
1399+
* repalloc0
1400+
* Adjust the size of a previously allocated chunk and zero out the added
1401+
* space.
1402+
*/
1403+
void *
1404+
repalloc0(void *pointer, Size oldsize, Size size)
1405+
{
1406+
void *ret;
1407+
1408+
/* catch wrong argument order */
1409+
if (unlikely(oldsize > size))
1410+
elog(ERROR, "invalid repalloc0 call: oldsize %zu, new size %zu",
1411+
oldsize, size);
1412+
1413+
ret = repalloc(pointer, size);
1414+
memset((char *) ret + oldsize, 0, (size - oldsize));
1415+
return ret;
1416+
}
1417+
13981418
/*
13991419
* MemoryContextAllocHuge
14001420
* Allocate (possibly-expansive) space within the specified context.

src/include/utils/palloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern void *palloc_extended(Size size, int flags);
8080
extern pg_nodiscard void *repalloc(void *pointer, Size size);
8181
extern pg_nodiscard void *repalloc_extended(void *pointer,
8282
Size size, int flags);
83+
extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size);
8384
extern void pfree(void *pointer);
8485

8586
/*
@@ -103,6 +104,7 @@ extern void pfree(void *pointer);
103104
* objects of type "type"
104105
*/
105106
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
107+
#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count)))
106108

107109
/*
108110
* The result of palloc() is always word-aligned, so we can skip testing

0 commit comments

Comments
 (0)