Add YAML to list of EXPLAIN formats. Greg Sabino Mullane, reviewed by Takahiro Itagaki.

This commit is contained in:
Andrew Dunstan 2009-12-11 01:33:35 +00:00
parent db7386187f
commit 324385d67f
6 changed files with 115 additions and 12 deletions

View File

@ -6,7 +6,7 @@
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.7 2009/08/10 05:46:49 tgl Exp $
* $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.8 2009/12/11 01:33:35 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@ -29,6 +29,7 @@ static const struct config_enum_entry format_options[] = {
{"text", EXPLAIN_FORMAT_TEXT, false},
{"xml", EXPLAIN_FORMAT_XML, false},
{"json", EXPLAIN_FORMAT_JSON, false},
{"yaml", EXPLAIN_FORMAT_YAML, false},
{NULL, 0, false}
};

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.4 2009/08/10 05:46:50 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.5 2009/12/11 01:33:35 adunstan Exp $ -->
<sect1 id="auto-explain">
<title>auto_explain</title>
@ -114,7 +114,7 @@ LOAD 'auto_explain';
<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.
<literal>json</literal>, and <literal>yaml</literal>. The default is text.
Only superusers can change this setting.
</para>
</listitem>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/explain.sgml,v 1.46 2009/08/10 05:46:50 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/explain.sgml,v 1.47 2009/12/11 01:33:35 adunstan Exp $
PostgreSQL documentation
-->
@ -31,7 +31,7 @@ PostgreSQL documentation
<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 <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,8 +143,8 @@ ROLLBACK;
<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
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>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/release-8.5.sgml,v 1.8 2009/11/26 21:20:12 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/release-8.5.sgml,v 1.9 2009/12/11 01:33:35 adunstan Exp $ -->
<sect1 id="release-8-5">
<title>Release 8.5alpha2</title>
@ -176,7 +176,7 @@
</listitem>
<listitem>
<para>
EXPLAIN allows output of plans in XML or JSON format for automated
EXPLAIN allows output of plans in XML, JSON, or YAML format for automated
processing of explain plans by analysis or visualization tools.
</para>
</listitem>

View File

@ -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.193 2009/11/04 22:26:04 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.194 2009/12/11 01:33:35 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@ -95,7 +95,9 @@ 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);
static void escape_json(StringInfo buf, const char *str);
static void escape_yaml(StringInfo buf, const char *str);
/*
@ -135,6 +137,8 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
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),
@ -1537,6 +1541,19 @@ ExplainPropertyList(const char *qlabel, List *data, ExplainState *es)
}
appendStringInfoChar(es->str, ']');
break;
case EXPLAIN_FORMAT_YAML:
ExplainYAMLLineStarting(es);
escape_yaml(es->str, qlabel);
appendStringInfoChar(es->str, ':');
foreach(lc, data)
{
appendStringInfoChar(es->str, '\n');
appendStringInfoSpaces(es->str, es->indent * 2 + 2);
appendStringInfoString(es->str, "- ");
escape_yaml(es->str, (const char *) lfirst(lc));
}
break;
}
}
@ -1584,6 +1601,15 @@ ExplainProperty(const char *qlabel, const char *value, bool numeric,
else
escape_json(es->str, value);
break;
case EXPLAIN_FORMAT_YAML:
ExplainYAMLLineStarting(es);
appendStringInfo(es->str, "%s: ", qlabel);
if (numeric)
appendStringInfoString(es->str, value);
else
escape_yaml(es->str, value);
break;
}
}
@ -1668,6 +1694,21 @@ ExplainOpenGroup(const char *objtype, const char *labelname,
es->grouping_stack = lcons_int(0, es->grouping_stack);
es->indent++;
break;
case EXPLAIN_FORMAT_YAML:
ExplainYAMLLineStarting(es);
if (labelname)
{
appendStringInfo(es->str, "%s:", labelname);
es->grouping_stack = lcons_int(1, es->grouping_stack);
}
else
{
appendStringInfoChar(es->str, '-');
es->grouping_stack = lcons_int(0, es->grouping_stack);
}
es->indent++;
break;
}
}
@ -1697,6 +1738,11 @@ ExplainCloseGroup(const char *objtype, const char *labelname,
appendStringInfoChar(es->str, labeled ? '}' : ']');
es->grouping_stack = list_delete_first(es->grouping_stack);
break;
case EXPLAIN_FORMAT_YAML:
es->indent--;
es->grouping_stack = list_delete_first(es->grouping_stack);
break;
}
}
@ -1729,6 +1775,13 @@ ExplainDummyGroup(const char *objtype, const char *labelname, ExplainState *es)
}
escape_json(es->str, objtype);
break;
case EXPLAIN_FORMAT_YAML:
ExplainYAMLLineStarting(es);
if (labelname)
appendStringInfo(es->str, "%s:", labelname);
appendStringInfoString(es->str, objtype);
break;
}
}
@ -1759,6 +1812,10 @@ ExplainBeginOutput(ExplainState *es)
es->grouping_stack = lcons_int(0, es->grouping_stack);
es->indent++;
break;
case EXPLAIN_FORMAT_YAML:
es->grouping_stack = lcons_int(0, es->grouping_stack);
break;
}
}
@ -1784,6 +1841,10 @@ ExplainEndOutput(ExplainState *es)
appendStringInfoString(es->str, "\n]");
es->grouping_stack = list_delete_first(es->grouping_stack);
break;
case EXPLAIN_FORMAT_YAML:
es->grouping_stack = list_delete_first(es->grouping_stack);
break;
}
}
@ -1796,6 +1857,7 @@ ExplainSeparatePlans(ExplainState *es)
switch (es->format)
{
case EXPLAIN_FORMAT_TEXT:
case EXPLAIN_FORMAT_YAML:
/* add a blank line */
appendStringInfoChar(es->str, '\n');
break;
@ -1858,6 +1920,25 @@ ExplainJSONLineEnding(ExplainState *es)
appendStringInfoChar(es->str, '\n');
}
/*
* Indent a YAML line.
*/
static void
ExplainYAMLLineStarting(ExplainState *es)
{
Assert(es->format == EXPLAIN_FORMAT_YAML);
if (linitial_int(es->grouping_stack) == 0)
{
appendStringInfoChar(es->str, ' ');
linitial_int(es->grouping_stack) = 1;
}
else
{
appendStringInfoChar(es->str, '\n');
appendStringInfoSpaces(es->str, es->indent * 2);
}
}
/*
* Produce a JSON string literal, properly escaping characters in the text.
*/
@ -1902,3 +1983,23 @@ escape_json(StringInfo buf, const char *str)
}
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 ((unsigned char) *p < ' ' || strchr("\"\\\b\f\n\r\t", *p))
{
escape_json(buf, str);
return;
}
}
appendStringInfo(buf, "%s", str);
}

View File

@ -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.41 2009/08/10 05:46:50 tgl Exp $
* $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.42 2009/12/11 01:33:35 adunstan Exp $
*
*-------------------------------------------------------------------------
*/
@ -19,7 +19,8 @@ typedef enum ExplainFormat
{
EXPLAIN_FORMAT_TEXT,
EXPLAIN_FORMAT_XML,
EXPLAIN_FORMAT_JSON
EXPLAIN_FORMAT_JSON,
EXPLAIN_FORMAT_YAML
} ExplainFormat;
typedef struct ExplainState