Skip to content

Commit e416830

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 a0841ec commit e416830

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
@@ -1184,11 +1184,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
11841184
/*
11851185
* We have to forcibly clean up the instrumentation state because we
11861186
* haven't done ExecutorEnd yet. This is pretty grotty ...
1187+
*
1188+
* Note: contrib/auto_explain could cause instrumentation to be set up
1189+
* even though we didn't ask for it here. Be careful not to print any
1190+
* instrumentation results the user didn't ask for. But we do the
1191+
* InstrEndLoop call anyway, if possible, to reduce the number of cases
1192+
* auto_explain has to contend with.
11871193
*/
11881194
if (planstate->instrument)
11891195
InstrEndLoop(planstate->instrument);
11901196

1191-
if (planstate->instrument && planstate->instrument->nloops > 0)
1197+
if (es->analyze &&
1198+
planstate->instrument && planstate->instrument->nloops > 0)
11921199
{
11931200
double nloops = planstate->instrument->nloops;
11941201
double startup_sec = 1000.0 * planstate->instrument->startup / nloops;
@@ -1197,7 +1204,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
11971204

11981205
if (es->format == EXPLAIN_FORMAT_TEXT)
11991206
{
1200-
if (planstate->instrument->need_timer)
1207+
if (es->timing)
12011208
appendStringInfo(es->str,
12021209
" (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
12031210
startup_sec, total_sec, rows, nloops);
@@ -1208,7 +1215,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
12081215
}
12091216
else
12101217
{
1211-
if (planstate->instrument->need_timer)
1218+
if (es->timing)
12121219
{
12131220
ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es);
12141221
ExplainPropertyFloat("Actual Total Time", total_sec, 3, es);
@@ -1219,20 +1226,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
12191226
}
12201227
else if (es->analyze)
12211228
{
1222-
12231229
if (es->format == EXPLAIN_FORMAT_TEXT)
12241230
appendStringInfoString(es->str, " (never executed)");
1225-
else if (planstate->instrument->need_timer)
1226-
{
1227-
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1228-
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1229-
}
12301231
else
12311232
{
1233+
if (es->timing)
1234+
{
1235+
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1236+
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1237+
}
12321238
ExplainPropertyFloat("Actual Rows", 0.0, 0, es);
12331239
ExplainPropertyFloat("Actual Loops", 0.0, 0, es);
12341240
}
1235-
12361241
}
12371242

12381243
/* in text format, first line ends here */
@@ -1426,7 +1431,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
14261431
}
14271432

14281433
/* Show buffer usage */
1429-
if (es->buffers)
1434+
if (es->buffers && planstate->instrument)
14301435
{
14311436
const BufferUsage *usage = &planstate->instrument->bufusage;
14321437

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