Skip to content

Commit 4fbfdde

Browse files
committed
Avoid leakage of zero-length arrays in partition_bounds_copy().
If ndatums is zero, the code would allocate zero-length boundKinds and boundDatums chunks, which would have nothing pointing to them, leading to Valgrind complaints. Rearrange the code to avoid the useless pallocs, and also to not bother computing byval/typlen when they aren't used. I'm unsure why I didn't see this in my Valgrind testing back in May. This code hasn't changed since then, but maybe we added a regression test that reaches this edge case. Or possibly I just failed to notice the reports, which do say "0 bytes lost". Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/285483.1746756246@sss.pgh.pa.us
1 parent b102c8c commit 4fbfdde

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

src/backend/partitioning/partbounds.c

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,9 +1007,6 @@ partition_bounds_copy(PartitionBoundInfo src,
10071007
int ndatums;
10081008
int nindexes;
10091009
int partnatts;
1010-
bool hash_part;
1011-
int natts;
1012-
Datum *boundDatums;
10131010

10141011
dest = (PartitionBoundInfo) palloc(sizeof(PartitionBoundInfoData));
10151012

@@ -1023,7 +1020,7 @@ partition_bounds_copy(PartitionBoundInfo src,
10231020

10241021
dest->datums = (Datum **) palloc(sizeof(Datum *) * ndatums);
10251022

1026-
if (src->kind != NULL)
1023+
if (src->kind != NULL && ndatums > 0)
10271024
{
10281025
PartitionRangeDatumKind *boundKinds;
10291026

@@ -1058,36 +1055,40 @@ partition_bounds_copy(PartitionBoundInfo src,
10581055
* For hash partitioning, datums array will have two elements - modulus
10591056
* and remainder.
10601057
*/
1061-
hash_part = (key->strategy == PARTITION_STRATEGY_HASH);
1062-
natts = hash_part ? 2 : partnatts;
1063-
boundDatums = palloc(ndatums * natts * sizeof(Datum));
1064-
1065-
for (i = 0; i < ndatums; i++)
1058+
if (ndatums > 0)
10661059
{
1067-
int j;
1068-
1069-
dest->datums[i] = &boundDatums[i * natts];
1060+
bool hash_part = (key->strategy == PARTITION_STRATEGY_HASH);
1061+
int natts = hash_part ? 2 : partnatts;
1062+
Datum *boundDatums = palloc(ndatums * natts * sizeof(Datum));
10701063

1071-
for (j = 0; j < natts; j++)
1064+
for (i = 0; i < ndatums; i++)
10721065
{
1073-
bool byval;
1074-
int typlen;
1066+
int j;
10751067

1076-
if (hash_part)
1077-
{
1078-
typlen = sizeof(int32); /* Always int4 */
1079-
byval = true; /* int4 is pass-by-value */
1080-
}
1081-
else
1068+
dest->datums[i] = &boundDatums[i * natts];
1069+
1070+
for (j = 0; j < natts; j++)
10821071
{
1083-
byval = key->parttypbyval[j];
1084-
typlen = key->parttyplen[j];
1085-
}
1072+
if (dest->kind == NULL ||
1073+
dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE)
1074+
{
1075+
bool byval;
1076+
int typlen;
10861077

1087-
if (dest->kind == NULL ||
1088-
dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE)
1089-
dest->datums[i][j] = datumCopy(src->datums[i][j],
1090-
byval, typlen);
1078+
if (hash_part)
1079+
{
1080+
typlen = sizeof(int32); /* Always int4 */
1081+
byval = true; /* int4 is pass-by-value */
1082+
}
1083+
else
1084+
{
1085+
byval = key->parttypbyval[j];
1086+
typlen = key->parttyplen[j];
1087+
}
1088+
dest->datums[i][j] = datumCopy(src->datums[i][j],
1089+
byval, typlen);
1090+
}
1091+
}
10911092
}
10921093
}
10931094

0 commit comments

Comments
 (0)