On 08/28/2009 02:16 PM, Greg Sabino Mullane wrote:
> Attached patch adds YAML output option to explain:
> 
> explain (format YAML) select * from information_schema.columns;

Updated version of the patch attached, fixes two small errors.


--
Greg Sabino Mullane g...@turnstep.com
PGP Key: 0x14964AC8 200908310847
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8

Index: contrib/auto_explain/auto_explain.c
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/auto_explain/auto_explain.c,v
retrieving revision 1.7
diff -c -r1.7 auto_explain.c
*** contrib/auto_explain/auto_explain.c	10 Aug 2009 05:46:49 -0000	1.7
--- contrib/auto_explain/auto_explain.c	31 Aug 2009 13:36:41 -0000
***************
*** 29,34 ****
--- 29,35 ----
          {"text", EXPLAIN_FORMAT_TEXT, false},
          {"xml", EXPLAIN_FORMAT_XML, false},
          {"json", EXPLAIN_FORMAT_JSON, false},
+         {"yaml", EXPLAIN_FORMAT_YAML, false},
          {NULL, 0, false}
  };
  
Index: doc/src/sgml/auto-explain.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/auto-explain.sgml,v
retrieving revision 1.4
diff -c -r1.4 auto-explain.sgml
*** doc/src/sgml/auto-explain.sgml	10 Aug 2009 05:46:50 -0000	1.4
--- doc/src/sgml/auto-explain.sgml	31 Aug 2009 13:36:41 -0000
***************
*** 114,120 ****
        <varname>auto_explain.log_format</varname> selects the
        <command>EXPLAIN</> output format to be used.
        The allowed values are <literal>text</literal>, <literal>xml</literal>,
!       and <literal>json</literal>.  The default is text.
        Only superusers can change this setting.
       </para>
      </listitem>
--- 114,120 ----
        <varname>auto_explain.log_format</varname> selects the
        <command>EXPLAIN</> output format to be used.
        The allowed values are <literal>text</literal>, <literal>xml</literal>,
!       <literal>json</literal>, and <literal>yaml</literal>.  The default is text.
        Only superusers can change this setting.
       </para>
      </listitem>
Index: doc/src/sgml/release-8.5.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/release-8.5.sgml,v
retrieving revision 1.4
diff -c -r1.4 release-8.5.sgml
*** doc/src/sgml/release-8.5.sgml	19 Aug 2009 08:18:48 -0000	1.4
--- doc/src/sgml/release-8.5.sgml	31 Aug 2009 13:36:41 -0000
***************
*** 96,102 ****
        <itemizedlist>
          <listitem>
            <para>
!             EXPLAIN allows output of plans in XML or JSON format for automated
              processing of explain plans by analysis or visualization tools.
            </para>
          </listitem>
--- 96,102 ----
        <itemizedlist>
          <listitem>
            <para>
!             EXPLAIN allows output of plans in XML, JSON, or YAML format for automated
              processing of explain plans by analysis or visualization tools.
            </para>
          </listitem>
Index: doc/src/sgml/ref/explain.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/explain.sgml,v
retrieving revision 1.46
diff -c -r1.46 explain.sgml
*** doc/src/sgml/ref/explain.sgml	10 Aug 2009 05:46:50 -0000	1.46
--- doc/src/sgml/ref/explain.sgml	31 Aug 2009 13:36:41 -0000
***************
*** 31,37 ****
  
   <refsynopsisdiv>
  <synopsis>
! EXPLAIN [ ( { ANALYZE <replaceable class="parameter">boolean</replaceable> | VERBOSE <replaceable class="parameter">boolean</replaceable> | COSTS <replaceable class="parameter">boolean</replaceable> | FORMAT { TEXT | XML | JSON } } [, ...] ) ] <replaceable class="parameter">statement</replaceable>
  EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
  </synopsis>
   </refsynopsisdiv>
--- 31,37 ----
  
   <refsynopsisdiv>
  <synopsis>
! EXPLAIN [ ( { ANALYZE <replaceable class="parameter">boolean</replaceable> | VERBOSE <replaceable class="parameter">boolean</replaceable> | COSTS <replaceable class="parameter">boolean</replaceable> | FORMAT { TEXT | XML | JSON | YAML } } [, ...] ) ] <replaceable class="parameter">statement</replaceable>
  EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
  </synopsis>
   </refsynopsisdiv>
***************
*** 143,150 ****
      <term><literal>FORMAT</literal></term>
      <listitem>
       <para>
!       Specify the output format, which can be TEXT, XML, or JSON.
!       XML or JSON output contains the same information as the text output
        format, but is easier for programs to parse.  This parameter defaults to
        <literal>TEXT</literal>.
       </para>
--- 143,150 ----
      <term><literal>FORMAT</literal></term>
      <listitem>
       <para>
!       Specify the output format, which can be TEXT, XML, JSON, or YAML.
!       Non-text output contains the same information as the text output
        format, but is easier for programs to parse.  This parameter defaults to
        <literal>TEXT</literal>.
       </para>
Index: src/backend/commands/explain.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/explain.c,v
retrieving revision 1.190
diff -c -r1.190 explain.c
*** src/backend/commands/explain.c	22 Aug 2009 02:06:32 -0000	1.190
--- src/backend/commands/explain.c	31 Aug 2009 13:36:41 -0000
***************
*** 96,101 ****
--- 96,102 ----
  static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es);
  static void ExplainJSONLineEnding(ExplainState *es);
  static void escape_json(StringInfo buf, const char *str);
+ static void escape_yaml(StringInfo buf, const char *str);
  
  
  /*
***************
*** 137,142 ****
--- 138,145 ----
  				es.format = EXPLAIN_FORMAT_XML;
  			else if (strcmp(p, "json") == 0)
  				es.format = EXPLAIN_FORMAT_JSON;
+ 			else if (strcmp(p, "yaml") == 0)
+ 				es.format = EXPLAIN_FORMAT_YAML;
  			else
  				ereport(ERROR,
  					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
***************
*** 1509,1514 ****
--- 1512,1529 ----
  			}
  			appendStringInfoChar(es->str, ']');
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			appendStringInfoSpaces(es->str, es->indent * 2);
+ 			appendStringInfo(es->str, "%s:\n", qlabel);
+ 			foreach(lc, data)
+ 			{
+ 			    appendStringInfoSpaces(es->str, es->indent * 2 + 2);
+ 				appendStringInfoString(es->str, "- ");
+ 				escape_yaml(es->str, (const char *) lfirst(lc));
+ 				appendStringInfoChar(es->str, '\n');
+ 			}
+ 			break;
  	}
  }
  
***************
*** 1556,1561 ****
--- 1571,1587 ----
  			else
  				escape_json(es->str, value);
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			appendStringInfoSpaces(es->str, es->indent * 2);
+ 			appendStringInfo(es->str, "%s: ", qlabel);
+ 			if (numeric)
+ 				appendStringInfoString(es->str, value);
+ 			else
+ 				escape_yaml(es->str, value);
+ 			appendStringInfoChar(es->str, '\n');
+ 			break;
+ 
  	}
  }
  
***************
*** 1640,1645 ****
--- 1666,1684 ----
  			es->grouping_stack = lcons_int(0, es->grouping_stack);
  			es->indent++;
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			appendStringInfoSpaces(es->str, 2 * es->indent);
+ 			if (labelname)
+ 			{
+ 				appendStringInfo(es->str, "%s:\n", labelname);
+ 			}
+ 			else {
+ 				appendStringInfoString(es->str, "-\n");
+ 			}
+ 			es->indent++;
+ 			break;
+ 
  	}
  }
  
***************
*** 1669,1674 ****
--- 1708,1717 ----
  			appendStringInfoChar(es->str, labeled ? '}' : ']');
  			es->grouping_stack = list_delete_first(es->grouping_stack);
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			es->indent--;
+ 			break;
  	}
  }
  
***************
*** 1701,1706 ****
--- 1744,1758 ----
  			}
  			escape_json(es->str, objtype);
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			appendStringInfoSpaces(es->str, 2 * es->indent);
+ 			if (labelname)
+ 			{
+ 				appendStringInfo(es->str, "%s:", labelname);
+ 			}
+ 			appendStringInfo(es->str, "%s\n", objtype);
+ 			break;
  	}
  }
  
***************
*** 1716,1721 ****
--- 1768,1774 ----
  	switch (es->format)
  	{
  		case EXPLAIN_FORMAT_TEXT:
+ 		case EXPLAIN_FORMAT_YAML:
  			/* nothing to do */
  			break;
  
***************
*** 1756,1761 ****
--- 1809,1818 ----
  			appendStringInfoString(es->str, "\n]");
  			es->grouping_stack = list_delete_first(es->grouping_stack);
  			break;
+ 
+ 		case EXPLAIN_FORMAT_YAML:
+ 			es->indent--;
+ 			break;
  	}
  }
  
***************
*** 1773,1778 ****
--- 1830,1836 ----
  			break;
  
  		case EXPLAIN_FORMAT_XML:
+ 		case EXPLAIN_FORMAT_YAML:
  			/* nothing to do */
  			break;
  
***************
*** 1874,1876 ****
--- 1932,1962 ----
  	}
  	appendStringInfoCharMacro(buf, '\"');
  }
+ 
+ /*
+  * YAML is a superset of JSON: if we find quotable characters, we call escape_json
+  */
+ static void
+ escape_yaml(StringInfo buf, const char *str)
+ {
+ 	const char *p;
+ 
+ 	for (p = str; *p; p++)
+ 	{
+ 		if ('"' == *p
+ 			|| '\\' == *p
+ 			|| '\t' == *p
+ 			|| '\n' == *p
+ 			|| '\r' == *p
+ 			|| '\b' == *p
+ 			|| '\f' == *p
+ 			|| (unsigned char) *p < ' '
+ 			)
+ 		{
+ 			escape_json(buf, str);
+ 			return;
+ 		}
+ 	}
+ 
+ 	appendStringInfo(buf, "%s", str);
+ }
Index: src/include/commands/explain.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/explain.h,v
retrieving revision 1.41
diff -c -r1.41 explain.h
*** src/include/commands/explain.h	10 Aug 2009 05:46:50 -0000	1.41
--- src/include/commands/explain.h	31 Aug 2009 13:36:41 -0000
***************
*** 19,25 ****
  {
  	EXPLAIN_FORMAT_TEXT,
  	EXPLAIN_FORMAT_XML,
! 	EXPLAIN_FORMAT_JSON
  } ExplainFormat;
  
  typedef struct ExplainState
--- 19,26 ----
  {
  	EXPLAIN_FORMAT_TEXT,
  	EXPLAIN_FORMAT_XML,
! 	EXPLAIN_FORMAT_JSON,
! 	EXPLAIN_FORMAT_YAML
  } ExplainFormat;
  
  typedef struct ExplainState

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to