8000 Prevent auto_explain from changing the output of a user's EXPLAIN. · larkly/postgres-docker@31f579f · GitHub
[go: up one dir, main page]

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