Export ExplainBeginOutput() and ExplainEndOutput() for auto_explain.
authorRobert Haas <[email protected]>
Sat, 12 Dec 2009 00:35:34 +0000 (00:35 +0000)
committerRobert Haas <[email protected]>
Sat, 12 Dec 2009 00:35:34 +0000 (00:35 +0000)
Without these functions, anyone outside of explain.c can't actually use
ExplainPrintPlan, because the ExplainState won't be initialized properly.
The user-visible result of this was a crash when using auto_explain with
the JSON output format.

Report by Euler Taveira de Oliveira.  Analysis by Tom Lane.  Patch by me.

contrib/auto_explain/auto_explain.c
src/backend/commands/explain.c
src/include/commands/explain.h

index 75ac9ca6aa48e81d42be1ef76b3d5d8645aac515..f0d907d1c9024c137f51918a1843a4ff84917124 100644 (file)
@@ -223,7 +223,9 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
            es.verbose = auto_explain_log_verbose;
            es.format = auto_explain_log_format;
 
+           ExplainBeginOutput(&es);
            ExplainPrintPlan(&es, queryDesc);
+           ExplainEndOutput(&es);
 
            /* Remove last line break */
            if (es.str->len > 0 && es.str->data[es.str->len - 1] == '\n')
index 0437ffa17f3022b2bd3e1d7b9dac8532d5b32983..2067636b49502a3c8a509b132d3f254583aca911 100644 (file)
@@ -91,8 +91,6 @@ static void ExplainCloseGroup(const char *objtype, const char *labelname,
                 bool labeled, ExplainState *es);
 static void ExplainDummyGroup(const char *objtype, const char *labelname,
                              ExplainState *es);
-static void ExplainBeginOutput(ExplainState *es);
-static void ExplainEndOutput(ExplainState *es);
 static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es);
 static void ExplainJSONLineEnding(ExplainState *es);
 static void ExplainYAMLLineStarting(ExplainState *es);
@@ -1791,7 +1789,7 @@ ExplainDummyGroup(const char *objtype, const char *labelname, ExplainState *es)
  * This is just enough different from processing a subgroup that we need
  * a separate pair of subroutines.
  */
-static void
+void
 ExplainBeginOutput(ExplainState *es)
 {
    switch (es->format)
@@ -1822,7 +1820,7 @@ ExplainBeginOutput(ExplainState *es)
 /*
  * Emit the end-of-output boilerplate.
  */
-static void
+void
 ExplainEndOutput(ExplainState *es)
 {
    switch (es->format)
index ab48825d79b39fa3e8305d2d302db4f0c9300981..ba2ba0803604f600288056ee951dbd6e112ee0b1 100644 (file)
@@ -65,6 +65,8 @@ extern void ExplainOnePlan(PlannedStmt *plannedstmt, ExplainState *es,
 
 extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc);
 
+extern void ExplainBeginOutput(ExplainState *es);
+extern void ExplainEndOutput(ExplainState *es);
 extern void ExplainSeparatePlans(ExplainState *es);
 
 #endif   /* EXPLAIN_H */