@@ -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