Skip to content

Commit de57004

Browse files
committed
Fix some oversights in commit 2455ab4.
The idea was to generate all the junk in a destroyable subcontext rather than leaking it in the caller's context, but partition_bounds_create was still being called in the caller's context, allowing plenty of scope for leakage. Also, get_rel_relkind() was still being called in the rel's rd_pdcxt, creating a risk of session-lifespan memory wastage. Simplify the logic a bit while at it. Also, reduce rd_pdcxt to ALLOCSET_SMALL_SIZES, since it seems likely to not usually be big. Probably something like this needs to be back-patched into v11, but for now let's get some buildfarm testing on this. Discussion: https://postgr.es/m/15943.1552601288@sss.pgh.pa.us
1 parent 61dc407 commit de57004

File tree

1 file changed

+33
-39
lines changed

1 file changed

+33
-39
lines changed

src/backend/partitioning/partdesc.c

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ RelationBuildPartitionDesc(Relation rel)
6767
nparts;
6868
PartitionKey key = RelationGetPartitionKey(rel);
6969
MemoryContext oldcxt;
70+
MemoryContext rbcontext;
7071
int *mapping;
71-
MemoryContext rbcontext = NULL;
7272

7373
/*
7474
* While building the partition descriptor, we create various temporary
@@ -187,56 +187,50 @@ RelationBuildPartitionDesc(Relation rel)
187187
/* Now build the actual relcache partition descriptor */
188188
rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext,
189189
"partition descriptor",
190-
ALLOCSET_DEFAULT_SIZES);
190+
ALLOCSET_SMALL_SIZES);
191191
MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt,
192192
RelationGetRelationName(rel));
193193

194-
MemoryContextSwitchTo(rel->rd_pdcxt);
195-
partdesc = (PartitionDescData *) palloc0(sizeof(PartitionDescData));
194+
partdesc = (PartitionDescData *)
195+
MemoryContextAllocZero(rel->rd_pdcxt, sizeof(PartitionDescData));
196196
partdesc->nparts = nparts;
197-
/* oids and boundinfo are allocated below. */
198-
199-
MemoryContextSwitchTo(oldcxt);
200-
201-
if (nparts == 0)
197+
/* If there are no partitions, the rest of the partdesc can stay zero */
198+
if (nparts > 0)
202199
{
203-
/* We can exit early in this case. */
204-
rel->rd_partdesc = partdesc;
200+
/* Create PartitionBoundInfo, using the temporary context. */
201+
boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping);
205202

206-
/* Blow away the temporary context. */
207-
MemoryContextDelete(rbcontext);
208-
return;
209-
}
203+
/* Now copy all info into relcache's partdesc. */
204+
MemoryContextSwitchTo(rel->rd_pdcxt);
205+
partdesc->boundinfo = partition_bounds_copy(boundinfo, key);
206+
partdesc->oids = (Oid *) palloc(nparts * sizeof(Oid));
207+
partdesc->is_leaf = (bool *) palloc(nparts * sizeof(bool));
210208

211-
/* First create PartitionBoundInfo */
212-
boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping);
213-
214-
/* Now copy boundinfo and oids into partdesc. */
215-
oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt);
216-
partdesc->boundinfo = partition_bounds_copy(boundinfo, key);
217-
partdesc->oids = (Oid *) palloc(partdesc->nparts * sizeof(Oid));
218-
partdesc->is_leaf = (bool *) palloc(partdesc->nparts * sizeof(bool));
219-
220-
/*
221-
* Now assign OIDs from the original array into mapped indexes of the
222-
* result array. The order of OIDs in the former is defined by the
223-
* catalog scan that retrieved them, whereas that in the latter is defined
224-
* by canonicalized representation of the partition bounds.
225-
*/
226-
for (i = 0; i < partdesc->nparts; i++)
227-
{
228-
int index = mapping[i];
209+
/*
210+
* Assign OIDs from the original array into mapped indexes of the
211+
* result array. The order of OIDs in the former is defined by the
212+
* catalog scan that retrieved them, whereas that in the latter is
213+
* defined by canonicalized representation of the partition bounds.
214+
*
215+
* Also record leaf-ness of each partition. For this we use
216+
* get_rel_relkind() which may leak memory, so be sure to run it in
217+
* the temporary context.
218+
*/
219+
MemoryContextSwitchTo(rbcontext);
220+
for (i = 0; i < nparts; i++)
221+
{
222+
int index = mapping[i];
229223

230-
partdesc->oids[index] = oids[i];
231-
/* Record if the partition is a leaf partition */
232-
partdesc->is_leaf[index] =
233-
(get_rel_relkind(oids[i]) != RELKIND_PARTITIONED_TABLE);
224+
partdesc->oids[index] = oids[i];
225+
partdesc->is_leaf[index] =
226+
(get_rel_relkind(oids[i]) != RELKIND_PARTITIONED_TABLE);
227+
}
234228
}
235-
MemoryContextSwitchTo(oldcxt);
236229

237230
rel->rd_partdesc = partdesc;
238231

239-
/* Blow away the temporary context. */
232+
/* Return to caller's context, and blow away the temporary context. */
233+
MemoryContextSwitchTo(oldcxt);
240234
MemoryContextDelete(rbcontext);
241235
}
242236

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy