Skip to content

Commit 31f579f

Browse files
committed
Prevent auto_explain from changing the output of a user's EXPLAIN.
Commit af7914c, which introduced the EXPLAIN (TIMING) option, for some reason coded explain.c to look at planstate->instrument->need_timer rather than es->timing to decide whether to print timing info. However, the former flag might get set as a result of contrib/auto_explain wanting timing information. We certainly don't want activation of auto_explain to change user-visible statement behavior, so fix that. Also fix an independent bug introduced in the same patch: in the code path for a never-executed node with a machine-friendly output format, if timing was selected, it would fail to print the Actual Rows and Actual Loops items. Per bug #10404 from Tomonari Katsumata. Back-patch to 9.2 where the faulty code was introduced.
1 parent 0128a77 commit 31f579f

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

src/backend/commands/explain.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,11 +1006,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
10061006
/*
10071007
* We have to forcibly clean up the instrumentation state because we
10081008
* haven't done ExecutorEnd yet. This is pretty grotty ...
1009+
*
1010+
* Note: contrib/auto_explain could cause instrumentation to be set up
1011+
* even though we didn't ask for it here. Be careful not to print any
1012+
* instrumentation results the user didn't ask for. But we do the
1013+
* InstrEndLoop call anyway, if possible, to reduce the number of cases
1014+
* auto_explain has to contend with.
10091015
*/
10101016
if (planstate->instrument)
10111017
InstrEndLoop(planstate->instrument);
10121018

1013-
if (planstate->instrument && planstate->instrument->nloops > 0)
1019+
if (es->analyze &&
1020+
planstate->instrument && planstate->instrument->nloops > 0)
10141021
{
10151022
double nloops = planstate->instrument->nloops;
10161023
double startup_sec = 1000.0 * planstate->instrument->startup / nloops;
@@ -1019,7 +1026,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
10191026

10201027
if (es->format == EXPLAIN_FORMAT_TEXT)
10211028
{
1022-
if (planstate->instrument->need_timer)
1029+
if (es->timing)
10231030
appendStringInfo(es->str,
10241031
" (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
10251032
startup_sec, total_sec, rows, nloops);
@@ -1030,7 +1037,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
10301037
}
10311038
else
10321039
{
1033-
if (planstate->instrument->need_timer)
1040+
if (es->timing)
10341041
{
10351042
ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es);
10361043
ExplainPropertyFloat("Actual Total Time", total_sec, 3, es);
@@ -1041,20 +1048,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
10411048
}
10421049
else if (es->analyze)
10431050
{
1044-
10451051
if (es->format == EXPLAIN_FORMAT_TEXT)
10461052
appendStringInfo(es->str, " (never executed)");
1047-
else if (planstate->instrument->need_timer)
1048-
{
1049-
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1050-
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1051-
}
10521053
else
10531054
{
1055+
if (es->timing)
1056+
{
1057+
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1058+
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1059+
}
10541060
ExplainPropertyFloat("Actual Rows", 0.0, 0, es);
10551061
ExplainPropertyFloat("Actual Loops", 0.0, 0, es);
10561062
}
1057-
10581063
}
10591064

10601065
/* in text format, first line ends here */
@@ -1220,7 +1225,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
12201225
}
12211226

12221227
/* Show buffer usage */
1223-
if (es->buffers)
1228+
if (es->buffers && planstate->instrument)
12241229
{
12251230
const BufferUsage *usage = &planstate->instrument->bufusage;
12261231

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy