OK, I propose the following further minor tweaks. (I modified the docs
following the wording we have for COSTS and BUFFERS).
There are two things that still trouble me a bit. First, we assume that
the planner is using an AllocSet context, which I guess is true, but if
somebody runs the planner in a context of a different memcxt type, it's
going to be a problem. So far we don't have infrastructure for creating
a context of the same type as another context. Maybe it's too fine a
point to worry about, for sure.
The other question is about trying to support the EXPLAIN EXECUTE case.
Do you find that case really useful? In a majority of cases planning is
not going to happen because it was already done by PREPARE (where we
_don't_ report memory, because we don't have EXPLAIN there), so it seems
a bit weird. I suppose you could make it useful if you instructed the
user to set plan_cache_mode to custom, assuming that does actually work
(I didn't try).
--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"El hombre nunca sabe de lo que es capaz hasta que lo intenta" (C. Dickens)
diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml
index 49c61cce69..26809d68d5 100644
--- a/doc/src/sgml/ref/explain.sgml
+++ b/doc/src/sgml/ref/explain.sgml
@@ -256,8 +256,9 @@ ROLLBACK;
<listitem>
<para>
Include information on memory consumption by the query planning phase.
- Report the precise amount of storage used by planner in-memory
- structures, and total memory considering allocation overhead.
+ Specifically, include the precise amount of storage used by planner
+ in-memory structures, as well as total memory considering allocation
+ overhead.
The parameter defaults to <literal>FALSE</literal>.
</para>
</listitem>
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 0a18a7abd8..2fa93998a3 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -660,7 +660,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into,
ExplainState *es,
ExplainPropertyFloat("Planning Time", "ms", 1000.0 * plantime,
3, es);
}
- if (mem_counts)
+ if (es->memory && mem_counts != NULL)
{
ExplainOpenGroup("Planner Memory", "Planner Memory", true, es);
show_planner_memory(es, mem_counts);
@@ -3813,9 +3813,9 @@ show_planner_memory(ExplainState *es,
if (es->format == EXPLAIN_FORMAT_TEXT)
{
appendStringInfo(es->str,
- "Planner Memory: used=%zu
bytes allocated=%zu bytes",
- mem_counts->totalspace -
mem_counts->freespace,
- mem_counts->totalspace);
+ "Planner Memory: used=%lld
bytes allocated=%lld bytes",
+ (long long)
(mem_counts->totalspace - mem_counts->freespace),
+ (long long)
mem_counts->totalspace);
appendStringInfoChar(es->str, '\n');
}
else
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7e947e023b..e1577c791a 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -590,9 +590,12 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause
*into, ExplainState *es,
if (es->memory)
{
/*
- * Create a new memory context to measure planner's memory
consumption
- * accurately. We should use the same type of memory context as
the
- * planner would use. That's usually AllocSet but ensure that.
+ * In order to measure planner's memory consumption accurately,
create
+ * a separate AllocSet memory context.
+ *
+ * XXX if planner is called under some other memory context
type, this
+ * code overrides that. Do we need support to create context of
+ * programmatically determined type?
*/
Assert(IsA(CurrentMemoryContext, AllocSetContext));
planner_ctx = AllocSetContextCreate(CurrentMemoryContext,