diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index e8d11a1d0e..de6d6b3555 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1029,28 +1029,8 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
 	Oid			relid;
 	HeapTuple	pg_class_tuple;
 	Form_pg_class relp;
-
-	/*
-	 * This function and its subroutines can allocate a good deal of transient
-	 * data in CurrentMemoryContext.  Traditionally we've just leaked that
-	 * data, reasoning that the caller's context is at worst of transaction
-	 * scope, and relcache loads shouldn't happen so often that it's essential
-	 * to recover transient data before end of statement/transaction.  However
-	 * that's definitely not true in clobber-cache test builds, and perhaps
-	 * it's not true in other cases.  If RECOVER_RELATION_BUILD_MEMORY is not
-	 * zero, arrange to allocate the junk in a temporary context that we'll
-	 * free before returning.  Make it a child of caller's context so that it
-	 * will get cleaned up appropriately if we error out partway through.
-	 */
-#if RECOVER_RELATION_BUILD_MEMORY
-	MemoryContext tmpcxt;
-	MemoryContext oldcxt;
-
-	tmpcxt = AllocSetContextCreate(CurrentMemoryContext,
-								   "RelationBuildDesc workspace",
-								   ALLOCSET_DEFAULT_SIZES);
-	oldcxt = MemoryContextSwitchTo(tmpcxt);
-#endif
+	MemoryContext tmpcxt = NULL;
+	MemoryContext oldcxt = NULL;
 
 	/*
 	 * find the tuple in pg_class corresponding to the given relation id
@@ -1061,14 +1041,7 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
 	 * if no such tuple exists, return NULL
 	 */
 	if (!HeapTupleIsValid(pg_class_tuple))
-	{
-#if RECOVER_RELATION_BUILD_MEMORY
-		/* Return to caller's context, and blow away the temporary context */
-		MemoryContextSwitchTo(oldcxt);
-		MemoryContextDelete(tmpcxt);
-#endif
 		return NULL;
-	}
 
 	/*
 	 * get information from the pg_class_tuple
@@ -1077,6 +1050,33 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
 	relid = relp->oid;
 	Assert(relid == targetRelId);
 
+	/*
+	 * This function and its subroutines can allocate a good deal of transient
+	 * data in CurrentMemoryContext.  Traditionally we've just leaked that
+	 * data, reasoning that the caller's context is at worst of transaction
+	 * scope, and relcache loads shouldn't happen so often that it's essential
+	 * to recover transient data before end of statement/transaction.  However
+	 * that's definitely not true in clobber-cache test builds, and perhaps
+	 * it's not true in other cases.  If RECOVER_RELATION_BUILD_MEMORY is not
+	 * zero, arrange to allocate the junk in a temporary context that we'll
+	 * free before returning.  Make it a child of caller's context so that it
+	 * will get cleaned up appropriately if we error out partway through.
+	 *
+	 * Partitioned tables are notoriously leaky to build, so we do this for
+	 * them always.
+	 */
+	if ((relp->relkind == RELKIND_PARTITIONED_TABLE)
+#if RECOVER_RELATION_BUILD_MEMORY
+		|| true
+#endif
+	   )
+	{
+		tmpcxt = AllocSetContextCreate(CurrentMemoryContext,
+									   "RelationBuildDesc workspace",
+									   ALLOCSET_DEFAULT_SIZES);
+		oldcxt = MemoryContextSwitchTo(tmpcxt);
+	}
+
 	/*
 	 * allocate storage for the relation descriptor, and copy pg_class_tuple
 	 * to relation->rd_rel.
@@ -1252,11 +1252,16 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
 	/* It's fully valid */
 	relation->rd_isvalid = true;
 
+	if ((relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
 #if RECOVER_RELATION_BUILD_MEMORY
-	/* Return to caller's context, and blow away the temporary context */
-	MemoryContextSwitchTo(oldcxt);
-	MemoryContextDelete(tmpcxt);
+		|| true
 #endif
+	   )
+	{
+		/* Return to caller's context, and blow away the temporary context */
+		MemoryContextSwitchTo(oldcxt);
+		MemoryContextDelete(tmpcxt);
+	}
 
 	return relation;
 }
