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
signature.asc
Description: OpenPGP digital signature