Skip to content

Commit 0266a9c

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 e0c04b7 commit 0266a9c

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
@@ -1145,11 +1145,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
11451145
/*
11461146
* We have to forcibly clean up the instrumentation state because we
11471147
* haven't done ExecutorEnd yet. This is pretty grotty ...
1148+
*
1149+
* Note: contrib/auto_explain could cause instrumentation to be set up
1150+
* even though we didn't ask for it here. Be careful not to print any
1151+
* instrumentation results the user didn't ask for. But we do the
1152+
* InstrEndLoop call anyway, if possible, to reduce the number of cases
1153+
* auto_explain has to contend with.
11481154
*/
11491155
if (planstate->instrument)
11501156
InstrEndLoop(planstate->instrument);
11511157

1152-
if (planstate->instrument && planstate->instrument->nloops > 0)
1158+
if (es->analyze &&
1159+
planstate->instrument && planstate->instrument->nloops > 0)
11531160
{
11541161
double nloops = planstate->instrument->nloops;
11551162
double startup_sec = 1000.0 * planstate->instrument->startup / nloops;
@@ -1158,7 +1165,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
11581165

11591166
if (es->format == EXPLAIN_FORMAT_TEXT)
11601167
{
1161-
if (planstate->instrument->need_timer)
1168+
if (es->timing)
11621169
appendStringInfo(es->str,
11631170
" (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
11641171
startup_sec, total_sec, rows, nloops);
@@ -1169,7 +1176,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
11691176
}
11701177
else
11711178
{
1172-
if (planstate->instrument->need_timer)
1179+
if (es->timing)
11731180
{
11741181
ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es);
11751182
ExplainPropertyFloat("Actual Total Time", total_sec, 3, es);
@@ -1180,20 +1187,18 @@ ExplainNode(PlanState *planstate, List *ancestors,
11801187
}
11811188
else if (es->analyze)
11821189
{
1183-
11841190
if (es->format == EXPLAIN_FORMAT_TEXT)
11851191
appendStringInfo(es->str, " (never executed)");
1186-
else if (planstate->instrument->need_timer)
1187-
{
1188-
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1189-
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1190-
}
11911192
else
11921193
{
1194+
if (es->timing)
1195+
{
1196+
ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
1197+
ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
1198+
}
11931199
ExplainPropertyFloat("Actual Rows", 0.0, 0, es);
11941200
ExplainPropertyFloat("Actual Loops", 0.0, 0, es);
11951201
}
1196-
11971202
}
11981203

11991204
/* in text format, first line ends here */
@@ -1362,7 +1367,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
13621367
}
13631368

13641369
/* Show buffer usage */
1365-
if (es->buffers)
1370+
if (es->buffers && planstate->instrument)
13661371
{
13671372
const BufferUsage *usage = &planstate->instrument->bufusage;
13681373

0 commit comments

Comments
 (0)