Add YAML to list of EXPLAIN formats. Greg Sabino Mullane, reviewed by Takahiro Itagaki.
This commit is contained in:
parent
db7386187f
commit
324385d67f
@ -6,7 +6,7 @@
|
|||||||
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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},
|
{"text", EXPLAIN_FORMAT_TEXT, false},
|
||||||
{"xml", EXPLAIN_FORMAT_XML, false},
|
{"xml", EXPLAIN_FORMAT_XML, false},
|
||||||
{"json", EXPLAIN_FORMAT_JSON, false},
|
{"json", EXPLAIN_FORMAT_JSON, false},
|
||||||
|
{"yaml", EXPLAIN_FORMAT_YAML, false},
|
||||||
{NULL, 0, false}
|
{NULL, 0, false}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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">
|
<sect1 id="auto-explain">
|
||||||
<title>auto_explain</title>
|
<title>auto_explain</title>
|
||||||
@ -114,7 +114,7 @@ LOAD 'auto_explain';
|
|||||||
<varname>auto_explain.log_format</varname> selects the
|
<varname>auto_explain.log_format</varname> selects the
|
||||||
<command>EXPLAIN</> output format to be used.
|
<command>EXPLAIN</> output format to be used.
|
||||||
The allowed values are <literal>text</literal>, <literal>xml</literal>,
|
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.
|
Only superusers can change this setting.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<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>
|
EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
@ -143,8 +143,8 @@ ROLLBACK;
|
|||||||
<term><literal>FORMAT</literal></term>
|
<term><literal>FORMAT</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specify the output format, which can be TEXT, XML, or JSON.
|
Specify the output format, which can be TEXT, XML, JSON, or YAML.
|
||||||
XML or JSON output contains the same information as the text output
|
Non-text output contains the same information as the text output
|
||||||
format, but is easier for programs to parse. This parameter defaults to
|
format, but is easier for programs to parse. This parameter defaults to
|
||||||
<literal>TEXT</literal>.
|
<literal>TEXT</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
@ -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">
|
<sect1 id="release-8-5">
|
||||||
<title>Release 8.5alpha2</title>
|
<title>Release 8.5alpha2</title>
|
||||||
@ -176,7 +176,7 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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.
|
processing of explain plans by analysis or visualization tools.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 ExplainEndOutput(ExplainState *es);
|
||||||
static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es);
|
static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es);
|
||||||
static void ExplainJSONLineEnding(ExplainState *es);
|
static void ExplainJSONLineEnding(ExplainState *es);
|
||||||
|
static void ExplainYAMLLineStarting(ExplainState *es);
|
||||||
static void escape_json(StringInfo buf, const char *str);
|
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;
|
es.format = EXPLAIN_FORMAT_XML;
|
||||||
else if (strcmp(p, "json") == 0)
|
else if (strcmp(p, "json") == 0)
|
||||||
es.format = EXPLAIN_FORMAT_JSON;
|
es.format = EXPLAIN_FORMAT_JSON;
|
||||||
|
else if (strcmp(p, "yaml") == 0)
|
||||||
|
es.format = EXPLAIN_FORMAT_YAML;
|
||||||
else
|
else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
@ -1537,6 +1541,19 @@ ExplainPropertyList(const char *qlabel, List *data, ExplainState *es)
|
|||||||
}
|
}
|
||||||
appendStringInfoChar(es->str, ']');
|
appendStringInfoChar(es->str, ']');
|
||||||
break;
|
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
|
else
|
||||||
escape_json(es->str, value);
|
escape_json(es->str, value);
|
||||||
break;
|
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->grouping_stack = lcons_int(0, es->grouping_stack);
|
||||||
es->indent++;
|
es->indent++;
|
||||||
break;
|
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 ? '}' : ']');
|
appendStringInfoChar(es->str, labeled ? '}' : ']');
|
||||||
es->grouping_stack = list_delete_first(es->grouping_stack);
|
es->grouping_stack = list_delete_first(es->grouping_stack);
|
||||||
break;
|
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);
|
escape_json(es->str, objtype);
|
||||||
break;
|
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->grouping_stack = lcons_int(0, es->grouping_stack);
|
||||||
es->indent++;
|
es->indent++;
|
||||||
break;
|
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]");
|
appendStringInfoString(es->str, "\n]");
|
||||||
es->grouping_stack = list_delete_first(es->grouping_stack);
|
es->grouping_stack = list_delete_first(es->grouping_stack);
|
||||||
break;
|
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)
|
switch (es->format)
|
||||||
{
|
{
|
||||||
case EXPLAIN_FORMAT_TEXT:
|
case EXPLAIN_FORMAT_TEXT:
|
||||||
|
case EXPLAIN_FORMAT_YAML:
|
||||||
/* add a blank line */
|
/* add a blank line */
|
||||||
appendStringInfoChar(es->str, '\n');
|
appendStringInfoChar(es->str, '\n');
|
||||||
break;
|
break;
|
||||||
@ -1858,6 +1920,25 @@ ExplainJSONLineEnding(ExplainState *es)
|
|||||||
appendStringInfoChar(es->str, '\n');
|
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.
|
* Produce a JSON string literal, properly escaping characters in the text.
|
||||||
*/
|
*/
|
||||||
@ -1902,3 +1983,23 @@ escape_json(StringInfo buf, const char *str)
|
|||||||
}
|
}
|
||||||
appendStringInfoCharMacro(buf, '\"');
|
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);
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* 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_TEXT,
|
||||||
EXPLAIN_FORMAT_XML,
|
EXPLAIN_FORMAT_XML,
|
||||||
EXPLAIN_FORMAT_JSON
|
EXPLAIN_FORMAT_JSON,
|
||||||
|
EXPLAIN_FORMAT_YAML
|
||||||
} ExplainFormat;
|
} ExplainFormat;
|
||||||
|
|
||||||
typedef struct ExplainState
|
typedef struct ExplainState
|
||||||
|
Loading…
x
Reference in New Issue
Block a user