diff --git a/src/backend/utils/mmgr/README b/src/backend/utils/mmgr/README
index 45e610dd061f01fbc9f94222c0857da23da0076f..4ebb78e4eb046a611f3eb74de5b7e76a86058d90 100644
--- a/src/backend/utils/mmgr/README
+++ b/src/backend/utils/mmgr/README
@@ -125,9 +125,14 @@ lifetimes that only partially overlap can be handled by allocating
 from different trees of the context forest (there are some examples
 in the next section).
 
-For convenience we will also want operations like "reset/delete all
-children of a given context, but don't reset or delete that context
-itself".
+Actually, it turns out that resetting a given context should almost
+always imply deleting (not just resetting) any child contexts it has.
+So MemoryContextReset() means that, and if you really do want a tree of
+empty contexts you need to call MemoryContextResetOnly() plus
+MemoryContextResetChildren().
+
+For convenience we also provide operations like "reset/delete all children
+of a given context, but don't reset or delete that context itself".
 
 
 Globally Known Contexts
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 72a32abdddb671769d8999a3f30b009ea603b900..e2fbfd420b661bdcc88b9bcb023414425fb46b8c 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -132,11 +132,8 @@ MemoryContextInit(void)
 
 /*
  * MemoryContextReset
- *		Release all space allocated within a context and its descendants,
- *		but don't delete the contexts themselves.
- *
- * The type-specific reset routine handles the context itself, but we
- * have to do the recursion for the children.
+ *		Release all space allocated within a context and delete all its
+ *		descendant contexts (but not the named context itself).
  */
 void
 MemoryContextReset(MemoryContext context)
@@ -145,7 +142,22 @@ MemoryContextReset(MemoryContext context)
 
 	/* save a function call in common case where there are no children */
 	if (context->firstchild != NULL)
-		MemoryContextResetChildren(context);
+		MemoryContextDeleteChildren(context);
+
+	/* save a function call if no pallocs since startup or last reset */
+	if (!context->isReset)
+		MemoryContextResetOnly(context);
+}
+
+/*
+ * MemoryContextResetOnly
+ *		Release all space allocated within a context.
+ *		Nothing is done to the context's descendant contexts.
+ */
+void
+MemoryContextResetOnly(MemoryContext context)
+{
+	AssertArg(MemoryContextIsValid(context));
 
 	/* Nothing to do if no pallocs since startup or last reset */
 	if (!context->isReset)
@@ -172,7 +184,10 @@ MemoryContextResetChildren(MemoryContext context)
 	AssertArg(MemoryContextIsValid(context));
 
 	for (child = context->firstchild; child != NULL; child = child->nextchild)
-		MemoryContextReset(child);
+	{
+		MemoryContextResetChildren(child);
+		MemoryContextResetOnly(child);
+	}
 }
 
 /*
@@ -234,23 +249,6 @@ MemoryContextDeleteChildren(MemoryContext context)
 		MemoryContextDelete(context->firstchild);
 }
 
-/*
- * MemoryContextResetAndDeleteChildren
- *		Release all space allocated within a context and delete all
- *		its descendants.
- *
- * This is a common combination case where we want to preserve the
- * specific context but get rid of absolutely everything under it.
- */
-void
-MemoryContextResetAndDeleteChildren(MemoryContext context)
-{
-	AssertArg(MemoryContextIsValid(context));
-
-	MemoryContextDeleteChildren(context);
-	MemoryContextReset(context);
-}
-
 /*
  * MemoryContextRegisterResetCallback
  *		Register a function to be called before next context reset/delete.
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 76ad7d443b03053f4637467e72d2f1bb1fc4f26a..dbb163a15364cb79254d9f43d68531b17edabf36 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -84,6 +84,9 @@ extern PGDLLIMPORT MemoryContext CurTransactionContext;
 /* This is a transient link to the active portal's memory context: */
 extern PGDLLIMPORT MemoryContext PortalContext;
 
+/* Backwards compatibility macro */
+#define MemoryContextResetAndDeleteChildren(ctx) MemoryContextReset(ctx)
+
 
 /*
  * Memory-context-type-independent functions in mcxt.c
@@ -91,9 +94,9 @@ extern PGDLLIMPORT MemoryContext PortalContext;
 extern void MemoryContextInit(void);
 extern void MemoryContextReset(MemoryContext context);
 extern void MemoryContextDelete(MemoryContext context);
+extern void MemoryContextResetOnly(MemoryContext context);
 extern void MemoryContextResetChildren(MemoryContext context);
 extern void MemoryContextDeleteChildren(MemoryContext context);
-extern void MemoryContextResetAndDeleteChildren(MemoryContext context);
 extern void MemoryContextRegisterResetCallback(MemoryContext context,
 								   MemoryContextCallback *cb);
 extern void MemoryContextSetParent(MemoryContext context,