calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [4/8] calcite git commit: [CALCITE-917] Add AS JSON as output option for EXPLAIN
Date Wed, 12 Oct 2016 00:00:10 GMT
[CALCITE-917] Add AS JSON as output option for EXPLAIN

Close apache/calcite#295


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/accc059c
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/accc059c
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/accc059c

Branch: refs/heads/master
Commit: accc059c72d7b364b9857eb51c2b384465ebd73c
Parents: 07e59a2
Author: Michael Mior <mmior@uwaterloo.ca>
Authored: Tue Jan 19 16:18:14 2016 -0500
Committer: Julian Hyde <jhyde@apache.org>
Committed: Tue Oct 11 16:13:42 2016 -0700

----------------------------------------------------------------------
 core/src/main/codegen/templates/Parser.jj       | 21 ++++++----
 .../calcite/plan/RelOptMaterialization.java     |  9 ++--
 .../org/apache/calcite/plan/RelOptUtil.java     | 32 +++++++++++----
 .../calcite/prepare/CalcitePrepareImpl.java     | 11 ++---
 .../org/apache/calcite/prepare/Prepare.java     | 30 +++++++-------
 .../calcite/rel/externalize/RelJsonWriter.java  |  8 ++--
 .../java/org/apache/calcite/sql/SqlExplain.java | 37 +++++++++++++----
 .../apache/calcite/sql/SqlExplainFormat.java    | 43 ++++++++++++++++++++
 .../apache/calcite/sql2rel/RelDecorrelator.java |  8 ++--
 .../apache/calcite/sql2rel/RelFieldTrimmer.java |  4 +-
 .../calcite/sql2rel/SqlToRelConverter.java      | 14 +++----
 .../org/apache/calcite/plan/RelWriterTest.java  |  6 +--
 .../plan/volcano/TraitPropagationTest.java      |  5 ++-
 .../calcite/sql/parser/SqlParserTest.java       | 29 ++++++++++---
 .../java/org/apache/calcite/test/JdbcTest.java  | 38 +++++++++++++++++
 .../apache/calcite/tools/FrameworksTest.java    |  4 +-
 .../org/apache/calcite/tools/PlannerTest.java   |  3 +-
 site/_docs/reference.md                         |  2 +
 18 files changed, 223 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 2869e97..a351424 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -52,6 +52,7 @@ import org.apache.calcite.sql.SqlDescribeSchema;
 import org.apache.calcite.sql.SqlDescribeTable;
 import org.apache.calcite.sql.SqlDynamicParam;
 import org.apache.calcite.sql.SqlExplain;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
@@ -1055,18 +1056,18 @@ SqlNode SqlExplain() :
     SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
     SqlExplain.Depth depth;
     SqlParserPos pos;
-    boolean asXml;
+    final SqlExplainFormat format;
 }
 {
     <EXPLAIN> <PLAN>
     [ detailLevel = ExplainDetailLevel() ]
     depth = ExplainDepth()
     (
-        <AS> <XML> { asXml = true; }
-        |
-        {
-            asXml = false;
-        }
+        <AS> <XML> { format = SqlExplainFormat.XML; }
+    |
+        <AS> <JSON> { format = SqlExplainFormat.JSON; }
+    |
+        { format = SqlExplainFormat.TEXT; }
     )
     <FOR> stmt = SqlQueryOrDml() {
         pos = getPos();
@@ -1074,7 +1075,7 @@ SqlNode SqlExplain() :
             stmt,
             detailLevel.symbol(SqlParserPos.ZERO),
             depth.symbol(SqlParserPos.ZERO),
-            SqlLiteral.createBoolean(asXml, SqlParserPos.ZERO),
+            format.symbol(SqlParserPos.ZERO),
             nDynamicParams);
     }
 }
@@ -1196,12 +1197,12 @@ SqlNode SqlDescribe() :
             //   [CALCITE-1221] Implement DESCRIBE DATABASE, CATALOG, STATEMENT
             final SqlExplainLevel detailLevel = SqlExplainLevel.EXPPLAN_ATTRIBUTES;
             final SqlExplain.Depth depth = SqlExplain.Depth.PHYSICAL;
-            final boolean asXml = false;
+            final SqlExplainFormat format = SqlExplainFormat.TEXT;
             return new SqlExplain(pos,
                 stmt,
                 detailLevel.symbol(SqlParserPos.ZERO),
                 depth.symbol(SqlParserPos.ZERO),
-                SqlLiteral.createBoolean(asXml, SqlParserPos.ZERO),
+                format.symbol(SqlParserPos.ZERO),
                 nDynamicParams);
         }
     )
@@ -5056,6 +5057,7 @@ SqlPostfixOperator PostfixRowOperator() :
     | < ISOLATION: "ISOLATION" >
     | < JAVA: "JAVA" >
     | < JOIN: "JOIN" >
+    | < JSON: "JSON" >
     | < K: "K" >
     | < KEY: "KEY" >
     | < KEY_MEMBER: "KEY_MEMBER" >
@@ -5494,6 +5496,7 @@ String CommonNonReservedKeyWord() :
         | <INVOKER>
         | <ISOLATION>
         | <JAVA>
+        | <JSON>
         | <K>
         | <KEY>
         | <KEY_MEMBER>

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
index 1da831d..df3fac5 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
@@ -35,6 +35,7 @@ import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.impl.StarTable;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.tools.Program;
 import org.apache.calcite.tools.Programs;
@@ -276,14 +277,14 @@ public class RelOptMaterialization {
         DefaultRelMetadataProvider.INSTANCE);
     if (CalcitePrepareImpl.DEBUG) {
       System.out.println(
-          RelOptUtil.dumpPlan(
-              "before", rel, false, SqlExplainLevel.DIGEST_ATTRIBUTES));
+          RelOptUtil.dumpPlan("before", rel, SqlExplainFormat.TEXT,
+              SqlExplainLevel.DIGEST_ATTRIBUTES));
     }
     final RelNode rel2 = program.run(null, rel, null);
     if (CalcitePrepareImpl.DEBUG) {
       System.out.println(
-          RelOptUtil.dumpPlan(
-              "after", rel2, false, SqlExplainLevel.DIGEST_ATTRIBUTES));
+          RelOptUtil.dumpPlan("after", rel2, SqlExplainFormat.TEXT,
+              SqlExplainLevel.DIGEST_ATTRIBUTES));
     }
     return rel2;
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index da405a0..ebac3f0 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -34,6 +34,7 @@ import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.core.SemiJoin;
 import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.externalize.RelJsonWriter;
 import org.apache.calcite.rel.externalize.RelWriterImpl;
 import org.apache.calcite.rel.externalize.RelXmlWriter;
 import org.apache.calcite.rel.logical.LogicalAggregate;
@@ -68,6 +69,7 @@ import org.apache.calcite.rex.RexShuttle;
 import org.apache.calcite.rex.RexSubQuery;
 import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.rex.RexVisitorImpl;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlOperator;
@@ -1728,16 +1730,16 @@ public abstract class RelOptUtil {
    * Dumps a plan as a string.
    *
    * @param header      Header to print before the plan. Ignored if the format
-   *                    is XML.
-   * @param rel         Relational expression to explain.
-   * @param asXml       Whether to format as XML.
-   * @param detailLevel Detail level.
+   *                    is XML
+   * @param rel         Relational expression to explain
+   * @param format      Output format
+   * @param detailLevel Detail level
    * @return Plan
    */
   public static String dumpPlan(
       String header,
       RelNode rel,
-      boolean asXml,
+      SqlExplainFormat format,
       SqlExplainLevel detailLevel) {
     StringWriter sw = new StringWriter();
     PrintWriter pw = new PrintWriter(sw);
@@ -1745,9 +1747,15 @@ public abstract class RelOptUtil {
       pw.println(header);
     }
     RelWriter planWriter;
-    if (asXml) {
+    switch (format) {
+    case XML:
       planWriter = new RelXmlWriter(pw, detailLevel);
-    } else {
+      break;
+    case JSON:
+      planWriter = new RelJsonWriter();
+      rel.explain(planWriter);
+      return ((RelJsonWriter) planWriter).asString();
+    default:
       planWriter = new RelWriterImpl(pw, detailLevel, false);
     }
     rel.explain(planWriter);
@@ -1755,6 +1763,16 @@ public abstract class RelOptUtil {
     return sw.toString();
   }
 
+  @Deprecated // to be removed before 2.0
+  public static String dumpPlan(
+      String header,
+      RelNode rel,
+      boolean asXml,
+      SqlExplainLevel detailLevel) {
+    return dumpPlan(header, rel,
+        asXml ? SqlExplainFormat.XML : SqlExplainFormat.TEXT, detailLevel);
+  }
+
   /**
    * Creates the row type descriptor for the result of a DML operation, which
    * is a single column named ROWCOUNT of type BIGINT for INSERT;

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index c0567ce..360677c 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -110,6 +110,7 @@ import org.apache.calcite.schema.Schemas;
 import org.apache.calcite.schema.Table;
 import org.apache.calcite.server.CalciteServerStatement;
 import org.apache.calcite.sql.SqlBinaryOperator;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
@@ -1169,10 +1170,10 @@ public class CalcitePrepareImpl implements CalcitePrepare {
         RelDataType resultType,
         RelDataType parameterRowType,
         RelRoot root,
-        boolean explainAsXml,
+        SqlExplainFormat format,
         SqlExplainLevel detailLevel) {
-      return new CalcitePreparedExplain(
-          resultType, parameterRowType, root, explainAsXml, detailLevel);
+      return new CalcitePreparedExplain(resultType, parameterRowType, root,
+          format, detailLevel);
     }
 
     @Override protected PreparedResult implement(RelRoot root) {
@@ -1257,9 +1258,9 @@ public class CalcitePrepareImpl implements CalcitePrepare {
         RelDataType resultType,
         RelDataType parameterRowType,
         RelRoot root,
-        boolean explainAsXml,
+        SqlExplainFormat format,
         SqlExplainLevel detailLevel) {
-      super(resultType, parameterRowType, root, explainAsXml, detailLevel);
+      super(resultType, parameterRowType, root, format, detailLevel);
     }
 
     public Bindable getBindable() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/prepare/Prepare.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/Prepare.java b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
index 70cddf6..0860d16 100644
--- a/core/src/main/java/org/apache/calcite/prepare/Prepare.java
+++ b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
@@ -40,6 +40,7 @@ import org.apache.calcite.runtime.Hook;
 import org.apache.calcite.runtime.Typed;
 import org.apache.calcite.schema.impl.StarTable;
 import org.apache.calcite.sql.SqlExplain;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
@@ -109,7 +110,7 @@ public abstract class Prepare {
       RelDataType resultType,
       RelDataType parameterRowType,
       RelRoot root,
-      boolean explainAsXml,
+      SqlExplainFormat format,
       SqlExplainLevel detailLevel);
 
   /**
@@ -243,15 +244,15 @@ public abstract class Prepare {
     // storage and decorrelation
     if (sqlExplain != null) {
       SqlExplain.Depth explainDepth = sqlExplain.getDepth();
-      boolean explainAsXml = sqlExplain.isXml();
+      SqlExplainFormat format = sqlExplain.getFormat();
       SqlExplainLevel detailLevel = sqlExplain.getDetailLevel();
       switch (explainDepth) {
       case TYPE:
-        return createPreparedExplanation(
-            resultType, parameterRowType, null, explainAsXml, detailLevel);
+        return createPreparedExplanation(resultType, parameterRowType, null,
+            format, detailLevel);
       case LOGICAL:
-        return createPreparedExplanation(
-            null, parameterRowType, root, explainAsXml, detailLevel);
+        return createPreparedExplanation(null, parameterRowType, root, format,
+            detailLevel);
       default:
       }
     }
@@ -272,15 +273,12 @@ public abstract class Prepare {
 
     // Display physical plan after decorrelation.
     if (sqlExplain != null) {
-      SqlExplain.Depth explainDepth = sqlExplain.getDepth();
-      boolean explainAsXml = sqlExplain.isXml();
-      SqlExplainLevel detailLevel = sqlExplain.getDetailLevel();
-      switch (explainDepth) {
+      switch (sqlExplain.getDepth()) {
       case PHYSICAL:
       default:
         root = optimize(root, getMaterializations(), getLattices());
-        return createPreparedExplanation(
-            null, parameterRowType, root, explainAsXml, detailLevel);
+        return createPreparedExplanation(null, parameterRowType, root,
+            sqlExplain.getFormat(), sqlExplain.getDetailLevel());
       }
     }
 
@@ -403,19 +401,19 @@ public abstract class Prepare {
     private final RelDataType rowType;
     private final RelDataType parameterRowType;
     private final RelRoot root;
-    private final boolean asXml;
+    private final SqlExplainFormat format;
     private final SqlExplainLevel detailLevel;
 
     public PreparedExplain(
         RelDataType rowType,
         RelDataType parameterRowType,
         RelRoot root,
-        boolean asXml,
+        SqlExplainFormat format,
         SqlExplainLevel detailLevel) {
       this.rowType = rowType;
       this.parameterRowType = parameterRowType;
       this.root = root;
-      this.asXml = asXml;
+      this.format = format;
       this.detailLevel = detailLevel;
     }
 
@@ -423,7 +421,7 @@ public abstract class Prepare {
       if (root == null) {
         return RelOptUtil.dumpType(rowType);
       } else {
-        return RelOptUtil.dumpPlan("", root.rel, asXml, detailLevel);
+        return RelOptUtil.dumpPlan("", root.rel, format, detailLevel);
       }
     }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
index 28981c8..2db46a1 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonWriter.java
@@ -39,11 +39,9 @@ public class RelJsonWriter implements RelWriter {
 
   private final JsonBuilder jsonBuilder;
   private final RelJson relJson;
-  private final Map<RelNode, String> relIdMap =
-      new IdentityHashMap<RelNode, String>();
+  private final Map<RelNode, String> relIdMap = new IdentityHashMap<>();
   private final List<Object> relList;
-  private final List<Pair<String, Object>> values =
-      new ArrayList<Pair<String, Object>>();
+  private final List<Pair<String, Object>> values = new ArrayList<>();
   private String previousId;
 
   //~ Constructors -------------------------------------------------------------
@@ -122,7 +120,7 @@ public class RelJsonWriter implements RelWriter {
         return (List<Object>) value.right;
       }
     }
-    final List<Object> list = new ArrayList<Object>();
+    final List<Object> list = new ArrayList<>();
     values.add(Pair.of(tag, (Object) list));
     return list;
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/sql/SqlExplain.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlExplain.java b/core/src/main/java/org/apache/calcite/sql/SqlExplain.java
index fc0e710..573e4a6 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlExplain.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlExplain.java
@@ -57,7 +57,7 @@ public class SqlExplain extends SqlCall {
   SqlNode explicandum;
   SqlLiteral detailLevel;
   SqlLiteral depth;
-  SqlLiteral asXml;
+  SqlLiteral format;
   private final int dynamicParameterCount;
 
   //~ Constructors -----------------------------------------------------------
@@ -66,13 +66,13 @@ public class SqlExplain extends SqlCall {
       SqlNode explicandum,
       SqlLiteral detailLevel,
       SqlLiteral depth,
-      SqlLiteral asXml,
+      SqlLiteral format,
       int dynamicParameterCount) {
     super(pos);
     this.explicandum = explicandum;
     this.detailLevel = detailLevel;
     this.depth = depth;
-    this.asXml = asXml;
+    this.format = format;
     this.dynamicParameterCount = dynamicParameterCount;
   }
 
@@ -87,7 +87,7 @@ public class SqlExplain extends SqlCall {
   }
 
   public List<SqlNode> getOperandList() {
-    return ImmutableNullableList.of(explicandum, detailLevel, depth, asXml);
+    return ImmutableNullableList.of(explicandum, detailLevel, depth, format);
   }
 
   @Override public void setOperand(int i, SqlNode operand) {
@@ -102,7 +102,7 @@ public class SqlExplain extends SqlCall {
       depth = (SqlLiteral) operand;
       break;
     case 3:
-      asXml = (SqlLiteral) operand;
+      format = (SqlLiteral) operand;
       break;
     default:
       throw new AssertionError(i);
@@ -152,10 +152,27 @@ public class SqlExplain extends SqlCall {
   }
 
   /**
+   * Returns the desired output format.
+   */
+  public SqlExplainFormat getFormat() {
+    return format.symbolValue(SqlExplainFormat.class);
+  }
+
+  /**
    * Returns whether result is to be in XML format.
+   *
+   * @deprecated Use {@link #getFormat()}
    */
+  @Deprecated // to be removed before 2.0
   public boolean isXml() {
-    return asXml.booleanValue();
+    return getFormat() == SqlExplainFormat.XML;
+  }
+
+  /**
+   * Returns whether result is to be in JSON format.
+   */
+  public boolean isJson() {
+    return getFormat() == SqlExplainFormat.XML;
   }
 
   @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
@@ -184,8 +201,14 @@ public class SqlExplain extends SqlCall {
     default:
       throw new UnsupportedOperationException();
     }
-    if (isXml()) {
+    switch (getFormat()) {
+    case XML:
       writer.keyword("AS XML");
+      break;
+    case JSON:
+      writer.keyword("AS JSON");
+      break;
+    default:
     }
     writer.keyword("FOR");
     writer.newlineAndIndent();

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/sql/SqlExplainFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlExplainFormat.java b/core/src/main/java/org/apache/calcite/sql/SqlExplainFormat.java
new file mode 100644
index 0000000..c1bc2a2
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/SqlExplainFormat.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql;
+
+import org.apache.calcite.sql.parser.SqlParserPos;
+
+/**
+ * Output format for {@code EXPLAIN PLAN} statement.
+ */
+public enum SqlExplainFormat {
+  /** Indicates that the plan should be output as a piece of indented text. */
+  TEXT,
+
+  /** Indicates that the plan should be output in XML format. */
+  XML,
+
+  /** Indicates that the plan should be output in JSON format. */
+  JSON;
+
+  /**
+   * Creates a parse-tree node representing an occurrence of this symbol at
+   * a particular position in the parsed text.
+   */
+  public SqlLiteral symbol(SqlParserPos pos) {
+    return SqlLiteral.createSymbol(this, pos);
+  }
+}
+
+// End SqlExplainFormat.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 024cb5f..1fb6e4f 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -65,6 +65,7 @@ import org.apache.calcite.rex.RexShuttle;
 import org.apache.calcite.rex.RexSubQuery;
 import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.rex.RexVisitorImpl;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlKind;
@@ -202,11 +203,8 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     if (SQL2REL_LOGGER.isDebugEnabled()) {
       SQL2REL_LOGGER.debug(
-          RelOptUtil.dumpPlan(
-              "Plan after removing Correlator",
-              newRootRel,
-              false,
-              SqlExplainLevel.EXPPLAN_ATTRIBUTES));
+          RelOptUtil.dumpPlan("Plan after removing Correlator", newRootRel,
+              SqlExplainFormat.TEXT, SqlExplainLevel.EXPPLAN_ATTRIBUTES));
     }
 
     if (!decorrelator.cm.mapCorVarToCorRel.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
index 3532b08..723fb78 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java
@@ -49,6 +49,7 @@ import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexPermuteInputsShuttle;
 import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.rex.RexVisitor;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.tools.RelBuilder;
@@ -164,7 +165,8 @@ public class RelFieldTrimmer implements ReflectiveVisitor {
     if (SqlToRelConverter.SQL2REL_LOGGER.isDebugEnabled()) {
       SqlToRelConverter.SQL2REL_LOGGER.debug(
           RelOptUtil.dumpPlan("Plan after trimming unused fields",
-              trimResult.left, false, SqlExplainLevel.EXPPLAN_ATTRIBUTES));
+              trimResult.left, SqlExplainFormat.TEXT,
+              SqlExplainLevel.EXPPLAN_ATTRIBUTES));
     }
     return trimResult.left;
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index e68ee2f..0a57aa0 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -97,6 +97,7 @@ import org.apache.calcite.sql.SqlCallBinding;
 import org.apache.calcite.sql.SqlDataTypeSpec;
 import org.apache.calcite.sql.SqlDelete;
 import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlIdentifier;
@@ -511,11 +512,8 @@ public class SqlToRelConverter {
       }
       if (SQL2REL_LOGGER.isDebugEnabled()) {
         SQL2REL_LOGGER.debug(
-            RelOptUtil.dumpPlan(
-                "Plan after trimming unused fields",
-                rootRel,
-                false,
-                SqlExplainLevel.EXPPLAN_ATTRIBUTES));
+            RelOptUtil.dumpPlan("Plan after trimming unused fields", rootRel,
+                SqlExplainFormat.TEXT, SqlExplainLevel.EXPPLAN_ATTRIBUTES));
       }
     }
     return rootRel;
@@ -569,10 +567,8 @@ public class SqlToRelConverter {
 
     if (SQL2REL_LOGGER.isDebugEnabled()) {
       SQL2REL_LOGGER.debug(
-          RelOptUtil.dumpPlan(
-              "Plan after converting SqlNode to RelNode",
-              result,
-              false,
+          RelOptUtil.dumpPlan("Plan after converting SqlNode to RelNode",
+              result, SqlExplainFormat.TEXT,
               SqlExplainLevel.EXPPLAN_ATTRIBUTES));
     }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
index c766110..b7a0bd2 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.logical.LogicalTableScan;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.SqlTypeName;
@@ -172,10 +173,7 @@ public class RelWriterTest {
                 } catch (IOException e) {
                   throw new RuntimeException(e);
                 }
-                return RelOptUtil.dumpPlan(
-                    "",
-                    node,
-                    false,
+                return RelOptUtil.dumpPlan("", node, SqlExplainFormat.TEXT,
                     SqlExplainLevel.EXPPLAN_ATTRIBUTES);
               }
             });

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
index 8d4dbd4..b04bc8c 100644
--- a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java
@@ -61,6 +61,7 @@ import org.apache.calcite.schema.Statistics;
 import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.calcite.server.CalciteServerStatement;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.SqlTypeName;
@@ -107,7 +108,7 @@ public class TraitPropagationTest {
     RelNode planned = run(new PropAction(), RULES);
     if (CalcitePrepareImpl.DEBUG) {
       System.out.println(
-          RelOptUtil.dumpPlan("LOGICAL PLAN", planned, false,
+          RelOptUtil.dumpPlan("LOGICAL PLAN", planned, SqlExplainFormat.TEXT,
               SqlExplainLevel.ALL_ATTRIBUTES));
     }
     final RelMetadataQuery mq = RelMetadataQuery.instance();
@@ -172,7 +173,7 @@ public class TraitPropagationTest {
 
       final RelNode rootRel = agg;
 
-      RelOptUtil.dumpPlan("LOGICAL PLAN", rootRel, false,
+      RelOptUtil.dumpPlan("LOGICAL PLAN", rootRel, SqlExplainFormat.TEXT,
           SqlExplainLevel.DIGEST_ATTRIBUTES);
 
       RelTraitSet desiredTraits = rootRel.getTraitSet().replace(PHYSICAL);

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 081bd2a..7ddac8a 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -2904,11 +2904,30 @@ public class SqlParserTest {
   }
 
   @Test public void testExplain() {
-    check(
-        "explain plan for select * from emps",
-        "EXPLAIN PLAN INCLUDING ATTRIBUTES WITH IMPLEMENTATION FOR\n"
-            + "SELECT *\n"
-            + "FROM `EMPS`");
+    final String sql = "explain plan for select * from emps";
+    final String expected = "EXPLAIN PLAN"
+        + " INCLUDING ATTRIBUTES WITH IMPLEMENTATION FOR\n"
+        + "SELECT *\n"
+        + "FROM `EMPS`";
+    sql(sql).ok(expected);
+  }
+
+  @Test public void testExplainAsXml() {
+    final String sql = "explain plan as xml for select * from emps";
+    final String expected = "EXPLAIN PLAN"
+        + " INCLUDING ATTRIBUTES WITH IMPLEMENTATION AS XML FOR\n"
+        + "SELECT *\n"
+        + "FROM `EMPS`";
+    sql(sql).ok(expected);
+  }
+
+  @Test public void testExplainAsJson() {
+    final String sql = "explain plan as json for select * from emps";
+    final String expected = "EXPLAIN PLAN"
+        + " INCLUDING ATTRIBUTES WITH IMPLEMENTATION AS JSON FOR\n"
+        + "SELECT *\n"
+        + "FROM `EMPS`";
+    sql(sql).ok(expected);
   }
 
   @Test public void testExplainWithImpl() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index a33c1af..678846c 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -5477,6 +5477,44 @@ public class JdbcTest {
         CalciteAssert.that().with(CalciteAssert.Config.FOODMART_CLONE);
     with.query("explain plan for values (1, 'ab')")
         .returns("PLAN=EnumerableValues(tuples=[[{ 1, 'ab' }]])\n\n");
+    final String expectedXml = "PLAN=<RelNode type=\"EnumerableValues\">\n"
+        + "\t<Property name=\"tuples\">\n"
+        + "\t\t[{ 1, &#39;ab&#39; }]\t</Property>\n"
+        + "\t<Inputs/>\n"
+        + "</RelNode>\n"
+        + "\n";
+    with.query("explain plan as xml for values (1, 'ab')")
+        .returns(expectedXml);
+    final String expectedJson = "PLAN={\n"
+        + "  \"rels\": [\n"
+        + "    {\n"
+        + "      \"id\": \"0\",\n"
+        + "      \"relOp\": \"org.apache.calcite.adapter.enumerable.EnumerableValues\",\n"
+        + "      \"type\": [\n"
+        + "        {\n"
+        + "          \"type\": \"INTEGER\",\n"
+        + "          \"nullable\": false,\n"
+        + "          \"name\": \"EXPR$0\"\n"
+        + "        },\n"
+        + "        {\n"
+        + "          \"type\": \"CHAR\",\n"
+        + "          \"nullable\": false,\n"
+        + "          \"precision\": 2,\n"
+        + "          \"name\": \"EXPR$1\"\n"
+        + "        }\n"
+        + "      ],\n"
+        + "      \"tuples\": [\n"
+        + "        [\n"
+        + "          1,\n"
+        + "          \"ab\"\n"
+        + "        ]\n"
+        + "      ],\n"
+        + "      \"inputs\": []\n"
+        + "    }\n"
+        + "  ]\n"
+        + "}\n";
+    with.query("explain plan as json for values (1, 'ab')")
+        .returns(expectedJson);
     with.query("explain plan with implementation for values (1, 'ab')")
         .returns("PLAN=EnumerableValues(tuples=[[{ 1, 'ab' }]])\n\n");
     with.query("explain plan without implementation for values (1, 'ab')")

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
index 7e2bcaf..6170563 100644
--- a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
@@ -40,6 +40,7 @@ import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.calcite.server.CalciteServerStatement;
 import org.apache.calcite.sql.SqlDialect;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -114,7 +115,8 @@ public class FrameworksTest {
           }
         });
     String s =
-        RelOptUtil.dumpPlan("", x, false, SqlExplainLevel.DIGEST_ATTRIBUTES);
+        RelOptUtil.dumpPlan("", x, SqlExplainFormat.TEXT,
+            SqlExplainLevel.DIGEST_ATTRIBUTES);
     assertThat(Util.toLinux(s),
         equalTo("EnumerableFilter(condition=[>($1, 1)])\n"
             + "  EnumerableTableScan(table=[[myTable]])\n"));

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
index e70767f..648786b 100644
--- a/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/PlannerTest.java
@@ -55,6 +55,7 @@ import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.SqlAggFunction;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlDialect;
+import org.apache.calcite.sql.SqlExplainFormat;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
@@ -155,7 +156,7 @@ public class PlannerTest {
 
   private String toString(RelNode rel) {
     return Util.toLinux(
-        RelOptUtil.dumpPlan("", rel, false,
+        RelOptUtil.dumpPlan("", rel, SqlExplainFormat.TEXT,
             SqlExplainLevel.DIGEST_ATTRIBUTES));
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/accc059c/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index bb4796a..1081df7 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -52,6 +52,7 @@ explain:
       EXPLAIN PLAN
       [ WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION ]
       [ EXCLUDING ATTRIBUTES | INCLUDING [ ALL ] ATTRIBUTES ]
+      [ AS JSON | AS XML ]
       FOR ( query | insert | update | merge | delete )
 
 describe:
@@ -450,6 +451,7 @@ INVOKER,
 ISOLATION,
 JAVA,
 **JOIN**,
+JSON,
 K,
 KEY,
 KEY_MEMBER,


Mime
View raw message