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)
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