]> granicus.if.org Git - postgresql/commitdiff
Add YAML to list of EXPLAIN formats. Greg Sabino Mullane, reviewed by Takahiro Itagaki.
authorAndrew Dunstan <andrew@dunslane.net>
Fri, 11 Dec 2009 01:33:35 +0000 (01:33 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Fri, 11 Dec 2009 01:33:35 +0000 (01:33 +0000)
contrib/auto_explain/auto_explain.c
doc/src/sgml/auto-explain.sgml
doc/src/sgml/ref/explain.sgml
doc/src/sgml/release-8.5.sgml
src/backend/commands/explain.c
src/include/commands/explain.h

index 6d3435be1f75f11a7a7b9c03622d0b706c03cf92..531f076525488e1f92c412e52b3bd8e79f8bbedf 100644 (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}
 };
 
index 72487f944ce6432168dbe2729d327b2b90ee6ad9..39c7bc20f592b01940c06742169f8c33e890233b 100644 (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>
index 9670bd06f193a265fb3b53220e8daacf6e2306cf..4de5a4aba63f083af6e65597085c57176a5e5cf5 100644 (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>
index caca7508250b4a029f17312022418f252a32d80c..f95b35505c3647ff00dee18b7223b89848271420 100644 (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>
        </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>
index 21fa3add4f662352c666c68b7dc7f29d904c87d1..0970723a6deb57ef86281a532d8c5c2ca7305834 100644 (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);
+}
index fa2c8aac668872767fd24c322c88929998b12ad8..7137a7ab41ef53271ca727844dfd650ee09a3888 100644 (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