diff --git a/src/backend/partitioning/partdesc.c b/src/backend/partitioning/partdesc.c
index 4d6595b..96129e7 100644
--- a/src/backend/partitioning/partdesc.c
+++ b/src/backend/partitioning/partdesc.c
@@ -43,7 +43,6 @@ typedef struct PartitionDirectoryData
 typedef struct PartitionDirectoryEntry
 {
 	Oid			reloid;
-	Relation	rel;
 	PartitionDesc pd;
 } PartitionDirectoryEntry;
 
@@ -235,6 +234,34 @@ RelationBuildPartitionDesc(Relation rel)
 }
 
 /*
+ * copyPartitionDesc
+ *
+ * Should be somewhere else perhaps?
+ */
+static PartitionDesc
+copyPartitionDesc(PartitionDesc src, PartitionKey key)
+{
+	PartitionDesc partdesc;
+	int			nparts = src->nparts;
+
+	partdesc = (PartitionDescData *) palloc0(sizeof(PartitionDescData));
+	partdesc->nparts = nparts;
+	/* If there are no partitions, the rest of the partdesc can stay zero */
+	if (nparts > 0)
+	{
+		partdesc->oids = (Oid *) palloc(nparts * sizeof(Oid));
+		memcpy(partdesc->oids, src->oids, nparts * sizeof(Oid));
+
+		partdesc->is_leaf = (bool *) palloc(nparts * sizeof(bool));
+		memcpy(partdesc->is_leaf, src->is_leaf, nparts * sizeof(bool));
+
+		partdesc->boundinfo = partition_bounds_copy(src->boundinfo, key);
+	}
+
+	return partdesc;
+}
+
+/*
  * CreatePartitionDirectory
  *		Create a new partition directory object.
  */
@@ -265,7 +292,7 @@ CreatePartitionDirectory(MemoryContext mcxt)
  *
  * The purpose of this function is to ensure that we get the same
  * PartitionDesc for each relation every time we look it up.  In the
- * face of current DDL, different PartitionDescs may be constructed with
+ * face of concurrent DDL, different PartitionDescs may be constructed with
  * different views of the catalog state, but any single particular OID
  * will always get the same PartitionDesc for as long as the same
  * PartitionDirectory is used.
@@ -281,13 +308,16 @@ PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel)
 	if (!found)
 	{
 		/*
-		 * We must keep a reference count on the relation so that the
-		 * PartitionDesc to which we are pointing can't get destroyed.
+		 * Currently, neither RelationGetPartitionDesc nor
+		 * RelationGetPartitionKey can leak any memory; but if they start
+		 * doing so, do those calls before switching into pdir_mcxt.
 		 */
-		RelationIncrementReferenceCount(rel);
-		pde->rel = rel;
-		pde->pd = RelationGetPartitionDesc(rel);
+		MemoryContext oldcontext = MemoryContextSwitchTo(pdir->pdir_mcxt);
+
+		pde->pd = copyPartitionDesc(RelationGetPartitionDesc(rel),
+									RelationGetPartitionKey(rel));
 		Assert(pde->pd != NULL);
+		MemoryContextSwitchTo(oldcontext);
 	}
 	return pde->pd;
 }
@@ -296,17 +326,11 @@ PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel)
  * DestroyPartitionDirectory
  *		Destroy a partition directory.
  *
- * Release the reference counts we're holding.
+ * This is a no-op at present; caller is supposed to release the memory context.
  */
 void
 DestroyPartitionDirectory(PartitionDirectory pdir)
 {
-	HASH_SEQ_STATUS	status;
-	PartitionDirectoryEntry *pde;
-
-	hash_seq_init(&status, pdir->pdir_hash);
-	while ((pde = hash_seq_search(&status)) != NULL)
-		RelationDecrementReferenceCount(pde->rel);
 }
 
 /*
