From 02490d4692c46bee3e9279e79c5d07c576d2a32c Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Sat, 12 Dec 2009 00:35:34 +0000
Subject: [PATCH] Export ExplainBeginOutput() and ExplainEndOutput() for
 auto_explain.

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 | 4 +++-
 src/backend/commands/explain.c      | 8 +++-----
 src/include/commands/explain.h      | 4 +++-
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/contrib/auto_explain/auto_explain.c b/contrib/auto_explain/auto_explain.c
index 531f0765254..88d40c71887 100644
--- a/contrib/auto_explain/auto_explain.c
+++ b/contrib/auto_explain/auto_explain.c
@@ -6,7 +6,7 @@
  * Copyright (c) 2008-2009, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.8 2009/12/11 01:33:35 adunstan Exp $
+ *	  $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.9 2009/12/12 00:35:33 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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')
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 0970723a6de..c34b5751e46 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.194 2009/12/11 01:33:35 adunstan Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.195 2009/12/12 00:35:33 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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)
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index 7137a7ab41e..75b5ed3d3c7 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.42 2009/12/11 01:33:35 adunstan Exp $
+ * $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.43 2009/12/12 00:35:34 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 */
-- 
GitLab