You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/04/17 20:35:46 UTC

[7/8] incubator-calcite git commit: [CALCITE-686] SqlNode.unparse produces invalid SQL

[CALCITE-686] SqlNode.unparse produces invalid SQL

Enable SqlUnParserTest and RelOptPlanReaderTest


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

Branch: refs/heads/master
Commit: 057f847bf6a918ee767f597be2705d70145cabac
Parents: 01183de
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Apr 16 14:50:06 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Apr 17 00:19:58 2015 -0700

----------------------------------------------------------------------
 .../apache/calcite/sql/SqlBinaryOperator.java   |   7 +-
 .../apache/calcite/sql/SqlInfixOperator.java    |   4 -
 .../apache/calcite/sql/SqlInternalOperator.java |   4 +-
 .../java/org/apache/calcite/sql/SqlKind.java    |   2 +-
 .../org/apache/calcite/sql/SqlOperator.java     |  10 ++
 .../apache/calcite/sql/SqlSpecialOperator.java  |   4 +-
 .../java/org/apache/calcite/sql/SqlUpdate.java  |   3 -
 .../java/org/apache/calcite/sql/SqlUtil.java    |  11 +-
 .../java/org/apache/calcite/sql/SqlWith.java    |   5 +-
 .../org/apache/calcite/sql/SqlWithItem.java     |   2 +-
 .../calcite/sql/fun/SqlExtendOperator.java      |  63 ++++++++
 .../calcite/sql/fun/SqlRollupOperator.java      |  65 ++++++++
 .../calcite/sql/fun/SqlStdOperatorTable.java    |  12 +-
 .../calcite/plan/RelOptPlanReaderTest.java      |   4 +-
 .../calcite/sql/parser/SqlParserTest.java       | 157 +++++++++++--------
 .../org/apache/calcite/test/CalciteSuite.java   |   4 +
 16 files changed, 255 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
index 0c0b491..bdcf961 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
@@ -81,8 +81,7 @@ public class SqlBinaryOperator extends SqlOperator {
   }
 
   /**
-   * Returns whether this operator should be surrounded by space when
-   * unparsed.
+   * {@inheritDoc}
    *
    * <p>Returns true for most operators but false for the '.' operator;
    * consider
@@ -90,10 +89,8 @@ public class SqlBinaryOperator extends SqlOperator {
    * <blockquote>
    * <pre>x.y + 5 * 6</pre>
    * </blockquote>
-   *
-   * @return whether this operator should be surrounded by space
    */
-  boolean needsSpace() {
+  @Override boolean needsSpace() {
     return !getName().equals(".");
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlInfixOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlInfixOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlInfixOperator.java
index 2f26878..df5d176 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlInfixOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlInfixOperator.java
@@ -76,10 +76,6 @@ public class SqlInfixOperator extends SqlSpecialOperator {
       operand.e.unparse(writer, leftPrec, getLeftPrec());
     }
   }
-
-  boolean needsSpace() {
-    return true;
-  }
 }
 
 // End SqlInfixOperator.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlInternalOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlInternalOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlInternalOperator.java
index deba96b..6f1e33c 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlInternalOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlInternalOperator.java
@@ -44,14 +44,14 @@ public class SqlInternalOperator extends SqlSpecialOperator {
   public SqlInternalOperator(
       String name,
       SqlKind kind) {
-    super(name, kind, 2, true, ReturnTypes.ARG0, null, OperandTypes.VARIADIC);
+    this(name, kind, 2);
   }
 
   public SqlInternalOperator(
       String name,
       SqlKind kind,
       int prec) {
-    super(name, kind, prec, true, ReturnTypes.ARG0, null, null);
+    this(name, kind, prec, true, ReturnTypes.ARG0, null, OperandTypes.VARIADIC);
   }
 
   public SqlInternalOperator(

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlKind.java b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
index 5fa715e..3843231 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
@@ -652,7 +652,7 @@ public enum SqlKind {
               SELECT, JOIN, OTHER_FUNCTION, CAST, TRIM, FLOOR, CEIL,
               LITERAL_CHAIN, JDBC_FN, PRECEDING, FOLLOWING, ORDER_BY,
               NULLS_FIRST, NULLS_LAST, COLLECTION_TABLE, TABLESAMPLE,
-              WITH, WITH_ITEM));
+              VALUES, WITH, WITH_ITEM));
 
   /**
    * Category consisting of all DML operators.

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
index 08325ab..e8914b2 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
@@ -493,6 +493,16 @@ public abstract class SqlOperator {
   }
 
   /**
+   * Returns whether this operator should be surrounded by space when
+   * unparsed.
+   *
+   * @return whether this operator should be surrounded by space
+   */
+  boolean needsSpace() {
+    return true;
+  }
+
+  /**
    * Validates and determines coercibility and resulting collation name of
    * binary operator if needed.
    */

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlSpecialOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSpecialOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlSpecialOperator.java
index 22b748d..85da998 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlSpecialOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlSpecialOperator.java
@@ -32,14 +32,14 @@ public class SqlSpecialOperator extends SqlOperator {
   public SqlSpecialOperator(
       String name,
       SqlKind kind) {
-    super(name, kind, 2, true, null, null, null);
+    this(name, kind, 2);
   }
 
   public SqlSpecialOperator(
       String name,
       SqlKind kind,
       int prec) {
-    super(name, kind, prec, true, null, null, null);
+    this(name, kind, prec, true, null, null, null);
   }
 
   public SqlSpecialOperator(

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java b/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
index 23afb22..5d8ebfa 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUpdate.java
@@ -162,9 +162,6 @@ public class SqlUpdate extends SqlCall {
     final int opLeft = getOperator().getLeftPrec();
     final int opRight = getOperator().getRightPrec();
     targetTable.unparse(writer, opLeft, opRight);
-    if (targetColumnList != null) {
-      targetColumnList.unparse(writer, opLeft, opRight);
-    }
     if (alias != null) {
       writer.keyword("AS");
       alias.unparse(writer, opLeft, opRight);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
index 4ee7ece..405b385 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
@@ -272,19 +272,18 @@ public abstract class SqlUtil {
       SqlWriter writer,
       int leftPrec,
       int rightPrec) {
-    SqlBinaryOperator binop = (SqlBinaryOperator) operator;
     assert call.operandCount() == 2;
     final SqlWriter.Frame frame =
         writer.startList(
-            (binop instanceof SqlSetOperator)
+            (operator instanceof SqlSetOperator)
                 ? SqlWriter.FrameTypeEnum.SETOP
                 : SqlWriter.FrameTypeEnum.SIMPLE);
-    call.operand(0).unparse(writer, leftPrec, binop.getLeftPrec());
-    final boolean needsSpace = binop.needsSpace();
+    call.operand(0).unparse(writer, leftPrec, operator.getLeftPrec());
+    final boolean needsSpace = operator.needsSpace();
     writer.setNeedWhitespace(needsSpace);
-    writer.sep(binop.getName());
+    writer.sep(operator.getName());
     writer.setNeedWhitespace(needsSpace);
-    call.operand(1).unparse(writer, binop.getRightPrec(), rightPrec);
+    call.operand(1).unparse(writer, operator.getRightPrec(), rightPrec);
     writer.endList(frame);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlWith.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWith.java b/core/src/main/java/org/apache/calcite/sql/SqlWith.java
index f0cd2c3..e680fe8 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlWith.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlWith.java
@@ -99,7 +99,10 @@ public class SqlWith extends SqlCall {
         node.unparse(writer, 0, 0);
       }
       writer.endList(frame1);
-      with.body.unparse(writer, 0, 0);
+      final SqlWriter.Frame frame2 =
+          writer.startList(SqlWriter.FrameTypeEnum.SIMPLE);
+      with.body.unparse(writer, 100, 100);
+      writer.endList(frame2);
       writer.endList(frame);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java b/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java
index 7fe5c62..63692c7 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java
@@ -93,7 +93,7 @@ public class SqlWithItem extends SqlCall {
         withItem.columnList.unparse(writer, getLeftPrec(), getRightPrec());
       }
       writer.keyword("AS");
-      withItem.query.unparse(writer, getLeftPrec(), getRightPrec());
+      withItem.query.unparse(writer, 10, 10);
     }
 
     @Override public SqlCall createCall(SqlLiteral functionQualifier,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/fun/SqlExtendOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlExtendOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlExtendOperator.java
new file mode 100644
index 0000000..6e0cfb7
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlExtendOperator.java
@@ -0,0 +1,63 @@
+/*
+ * 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.fun;
+
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlInternalOperator;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlWriter;
+
+/** {@code EXTEND} operator.
+ *
+ * <p>Adds columns to a table's schema, as in
+ * {@code SELECT ... FROM emp EXTEND (horoscope VARCHAR(100))}.
+ *
+ * <p>Not standard SQL. Added to Calcite to support Phoenix, but can be used to
+ * achieve schema-on-query against other adapters.
+ */
+class SqlExtendOperator extends SqlInternalOperator {
+  public SqlExtendOperator() {
+    super("EXTEND", SqlKind.EXTEND, MDX_PRECEDENCE);
+  }
+
+  @Override public void unparse(SqlWriter writer, SqlCall call, int leftPrec,
+      int rightPrec) {
+    final SqlOperator operator = call.getOperator();
+    assert call.operandCount() == 2;
+    final SqlWriter.Frame frame =
+        writer.startList(SqlWriter.FrameTypeEnum.SIMPLE);
+    call.operand(0).unparse(writer, leftPrec, operator.getLeftPrec());
+    writer.setNeedWhitespace(true);
+    writer.sep(operator.getName());
+    final SqlNodeList list = call.operand(1);
+    final SqlWriter.Frame frame2 = writer.startList("(", ")");
+    for (Ord<SqlNode> node2 : Ord.zip(list)) {
+      if (node2.i > 0 && node2.i % 2 == 0) {
+        writer.sep(",");
+      }
+      node2.e.unparse(writer, 2, 3);
+    }
+    writer.endList(frame2);
+    writer.endList(frame);
+  }
+}
+
+// End SqlExtendOperator.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/fun/SqlRollupOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlRollupOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlRollupOperator.java
new file mode 100644
index 0000000..6e3efc8
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlRollupOperator.java
@@ -0,0 +1,65 @@
+/*
+ * 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.fun;
+
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlInternalOperator;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlWriter;
+
+/**
+ * Operator that appears in a {@code GROUP BY} clause: {@code CUBE},
+ * {@code ROLLUP}, {@code GROUPING SETS}.
+ */
+class SqlRollupOperator extends SqlInternalOperator {
+  public SqlRollupOperator(String name, SqlKind kind) {
+    super(name, kind, 4);
+  }
+
+  @Override public void unparse(SqlWriter writer, SqlCall call, int leftPrec,
+      int rightPrec) {
+    unparseCube(writer, call);
+  }
+
+  private static void unparseCube(SqlWriter writer, SqlCall call) {
+    writer.keyword(call.getOperator().getName());
+    final SqlWriter.Frame frame =
+        writer.startList(SqlWriter.FrameTypeEnum.FUN_CALL, "(", ")");
+    for (SqlNode operand : call.getOperandList()) {
+      writer.sep(",");
+      if (operand.getKind() == SqlKind.ROW) {
+        final SqlWriter.Frame frame2 =
+            writer.startList(SqlWriter.FrameTypeEnum.SIMPLE, "(", ")");
+        for (SqlNode operand2 : ((SqlCall) operand).getOperandList()) {
+          writer.sep(",");
+          operand2.unparse(writer, 0, 0);
+        }
+        writer.endList(frame2);
+      } else if (operand instanceof SqlNodeList
+          && ((SqlNodeList) operand).size() == 0) {
+        writer.keyword("()");
+      } else {
+        operand.unparse(writer, 0, 0);
+      }
+    }
+    writer.endList(frame);
+  }
+}
+
+// End SqlRollupOperator.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index ef7133b..0a86799 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -152,17 +152,17 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
   /** {@code CUBE} operator, occurs within {@code GROUP BY} clause
    * or nested within a {@code GROUPING SETS}. */
   public static final SqlInternalOperator CUBE =
-      new SqlInternalOperator("CUBE", SqlKind.CUBE);
+      new SqlRollupOperator("CUBE", SqlKind.CUBE);
 
   /** {@code ROLLUP} operator, occurs within {@code GROUP BY} clause
    * or nested within a {@code GROUPING SETS}. */
   public static final SqlInternalOperator ROLLUP =
-      new SqlInternalOperator("ROLLUP", SqlKind.ROLLUP);
+      new SqlRollupOperator("ROLLUP", SqlKind.ROLLUP);
 
   /** {@code GROUPING SETS} operator, occurs within {@code GROUP BY} clause
    * or nested within a {@code GROUPING SETS}. */
   public static final SqlInternalOperator GROUPING_SETS =
-      new SqlInternalOperator("GROUPING_SETS", SqlKind.GROUPING_SETS);
+      new SqlRollupOperator("GROUPING SETS", SqlKind.GROUPING_SETS);
 
   /** {@code GROUPING} function. Occurs in similar places to an aggregate
    * function ({@code SELECT}, {@code HAVING} clause, etc. of an aggregate
@@ -178,10 +178,8 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
   public static final SqlGroupingIdFunction GROUPING_ID =
       new SqlGroupingIdFunction();
 
-  /** {@code EXTEND} operator to add columns to a table's schema, as in
-   * {@code SELECT ... FROM emp EXTEND (horoscope VARCHAR(100))}. */
-  public static final SqlInternalOperator EXTEND =
-      new SqlInternalOperator("EXTEND", SqlKind.EXTEND);
+  /** {@code EXTEND} operator. */
+  public static final SqlInternalOperator EXTEND = new SqlExtendOperator();
 
   /**
    * String concatenation operator, '<code>||</code>'.

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/test/java/org/apache/calcite/plan/RelOptPlanReaderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/plan/RelOptPlanReaderTest.java b/core/src/test/java/org/apache/calcite/plan/RelOptPlanReaderTest.java
index 8c95301..777cf5b 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelOptPlanReaderTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelOptPlanReaderTest.java
@@ -44,8 +44,8 @@ public class RelOptPlanReaderTest {
 
     // in org.apache.calcite.adapter.jdbc.JdbcRules outer class
     assertThat(relJson.classToTypeName(JdbcRules.JdbcProject.class),
-        is("JdbcProjectRel"));
-    assertThat(relJson.typeNameToClass("JdbcProjectRel"),
+        is("JdbcProject"));
+    assertThat(relJson.typeNameToClass("JdbcProject"),
         equalTo((Class) JdbcRules.JdbcProject.class));
 
     try {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/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 9b32900..11eaf7c 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
@@ -354,7 +354,7 @@ public class SqlParserTest {
 
     check(
         "values a between c and d and e and f between g and h",
-        "(VALUES (ROW((((`A` BETWEEN ASYMMETRIC `C` AND `D`) AND `E`) AND (`F` BETWEEN ASYMMETRIC `G` AND `H`)))))");
+        "VALUES (ROW((((`A` BETWEEN ASYMMETRIC `C` AND `D`) AND `E`) AND (`F` BETWEEN ASYMMETRIC `G` AND `H`))))");
 
     checkFails(
         "values a between b or c^",
@@ -371,17 +371,17 @@ public class SqlParserTest {
     // precedence of BETWEEN is higher than AND and OR, but lower than '+'
     check(
         "values a between b and c + 2 or d and e",
-        "(VALUES (ROW(((`A` BETWEEN ASYMMETRIC `B` AND (`C` + 2)) OR (`D` AND `E`)))))");
+        "VALUES (ROW(((`A` BETWEEN ASYMMETRIC `B` AND (`C` + 2)) OR (`D` AND `E`))))");
 
     // '=' and BETWEEN have same precedence, and are left-assoc
     check(
         "values x = a between b and c = d = e",
-        "(VALUES (ROW(((((`X` = `A`) BETWEEN ASYMMETRIC `B` AND `C`) = `D`) = `E`))))");
+        "VALUES (ROW(((((`X` = `A`) BETWEEN ASYMMETRIC `B` AND `C`) = `D`) = `E`)))");
 
     // AND doesn't match BETWEEN if it's between parentheses!
     check(
         "values a between b or (c and d) or e and f",
-        "(VALUES (ROW((`A` BETWEEN ASYMMETRIC ((`B` OR (`C` AND `D`)) OR `E`) AND `F`))))");
+        "VALUES (ROW((`A` BETWEEN ASYMMETRIC ((`B` OR (`C` AND `D`)) OR `E`) AND `F`)))");
   }
 
   @Test public void testOperateOnColumn() {
@@ -549,33 +549,33 @@ public class SqlParserTest {
 
     check(
         "values a and b like c",
-        "(VALUES (ROW((`A` AND (`B` LIKE `C`)))))");
+        "VALUES (ROW((`A` AND (`B` LIKE `C`))))");
 
     // LIKE has higher precedence than AND
     check(
         "values a and b like c escape d and e",
-        "(VALUES (ROW(((`A` AND (`B` LIKE `C` ESCAPE `D`)) AND `E`))))");
+        "VALUES (ROW(((`A` AND (`B` LIKE `C` ESCAPE `D`)) AND `E`)))");
 
     // LIKE has same precedence as '='; LIKE is right-assoc, '=' is left
     check(
         "values a = b like c = d",
-        "(VALUES (ROW(((`A` = `B`) LIKE (`C` = `D`)))))");
+        "VALUES (ROW(((`A` = `B`) LIKE (`C` = `D`))))");
 
     // Nested LIKE
     check(
         "values a like b like c escape d",
-        "(VALUES (ROW((`A` LIKE (`B` LIKE `C` ESCAPE `D`)))))");
+        "VALUES (ROW((`A` LIKE (`B` LIKE `C` ESCAPE `D`))))");
     check(
         "values a like b like c escape d and false",
-        "(VALUES (ROW(((`A` LIKE (`B` LIKE `C` ESCAPE `D`)) AND FALSE))))");
+        "VALUES (ROW(((`A` LIKE (`B` LIKE `C` ESCAPE `D`)) AND FALSE)))");
     check(
         "values a like b like c like d escape e escape f",
-        "(VALUES (ROW((`A` LIKE (`B` LIKE (`C` LIKE `D` ESCAPE `E`) ESCAPE `F`)))))");
+        "VALUES (ROW((`A` LIKE (`B` LIKE (`C` LIKE `D` ESCAPE `E`) ESCAPE `F`))))");
 
     // Mixed LIKE and SIMILAR TO
     check(
         "values a similar to b like c similar to d escape e escape f",
-        "(VALUES (ROW((`A` SIMILAR TO (`B` LIKE (`C` SIMILAR TO `D` ESCAPE `E`) ESCAPE `F`)))))");
+        "VALUES (ROW((`A` SIMILAR TO (`B` LIKE (`C` SIMILAR TO `D` ESCAPE `E`) ESCAPE `F`))))");
 
     // FIXME should fail at "escape"
     checkFails(
@@ -585,12 +585,12 @@ public class SqlParserTest {
     // LIKE with +
     check(
         "values a like b + c escape d",
-        "(VALUES (ROW((`A` LIKE (`B` + `C`) ESCAPE `D`))))");
+        "VALUES (ROW((`A` LIKE (`B` + `C`) ESCAPE `D`)))");
 
     // LIKE with ||
     check(
         "values a like b || c escape d",
-        "(VALUES (ROW((`A` LIKE (`B` || `C`) ESCAPE `D`))))");
+        "VALUES (ROW((`A` LIKE (`B` || `C`) ESCAPE `D`)))");
 
     // ESCAPE with no expression
     // FIXME should fail at "escape"
@@ -627,14 +627,14 @@ public class SqlParserTest {
     // Mixed LIKE and SIMILAR TO
     check(
         "values a similar to b like c similar to d escape e escape f",
-        "(VALUES (ROW((`A` SIMILAR TO (`B` LIKE (`C` SIMILAR TO `D` ESCAPE `E`) ESCAPE `F`)))))");
+        "VALUES (ROW((`A` SIMILAR TO (`B` LIKE (`C` SIMILAR TO `D` ESCAPE `E`) ESCAPE `F`))))");
 
     // SIMILAR TO with subquery
     check(
         "values a similar to (select * from t where a like b escape c) escape d",
-        "(VALUES (ROW((`A` SIMILAR TO (SELECT *\n"
+        "VALUES (ROW((`A` SIMILAR TO (SELECT *\n"
             + "FROM `T`\n"
-            + "WHERE (`A` LIKE `B` ESCAPE `C`)) ESCAPE `D`))))");
+            + "WHERE (`A` LIKE `B` ESCAPE `C`)) ESCAPE `D`)))");
   }
 
   @Test public void testFoo() {
@@ -791,7 +791,7 @@ public class SqlParserTest {
         + "group by grouping sets (deptno, (deptno, gender), ())")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (GROUPING_SETS(`DEPTNO`, (ROW(`DEPTNO`, `GENDER`)),))");
+            + "GROUP BY GROUPING SETS(`DEPTNO`, (`DEPTNO`, `GENDER`), ())");
 
     // Grouping sets must have parentheses
     sql("select deptno from emp\n"
@@ -807,14 +807,14 @@ public class SqlParserTest {
         + "order by a")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (GROUPING_SETS(`DEPTNO`, GROUPING_SETS(`E`, `D`),, CUBE(`X`, `Y`), ROLLUP(`P`, `Q`)))\n"
+            + "GROUP BY GROUPING SETS(`DEPTNO`, GROUPING SETS(`E`, `D`), (), CUBE(`X`, `Y`), ROLLUP(`P`, `Q`))\n"
             + "ORDER BY `A`");
 
     sql("select deptno from emp\n"
         + "group by grouping sets (())")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (GROUPING_SETS())");
+            + "GROUP BY GROUPING SETS(())");
   }
 
   @Test public void testGroupByCube() {
@@ -822,7 +822,7 @@ public class SqlParserTest {
         + "group by cube ((a, b), (c, d))")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (CUBE((ROW(`A`, `B`)), (ROW(`C`, `D`))))");
+            + "GROUP BY CUBE((`A`, `B`), (`C`, `D`))");
   }
 
   @Test public void testGroupByCube2() {
@@ -830,7 +830,7 @@ public class SqlParserTest {
         + "group by cube ((a, b), (c, d)) order by a")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (CUBE((ROW(`A`, `B`)), (ROW(`C`, `D`))))\n"
+            + "GROUP BY CUBE((`A`, `B`), (`C`, `D`))\n"
             + "ORDER BY `A`");
     sql("select deptno from emp\n"
         + "group by cube (^)")
@@ -842,7 +842,7 @@ public class SqlParserTest {
         + "group by rollup (deptno, deptno + 1, gender)")
         .ok("SELECT `DEPTNO`\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (ROLLUP(`DEPTNO`, (`DEPTNO` + 1), `GENDER`))");
+            + "GROUP BY ROLLUP(`DEPTNO`, (`DEPTNO` + 1), `GENDER`)");
 
     // Nested rollup not ok
     sql("select deptno from emp\n"
@@ -855,7 +855,7 @@ public class SqlParserTest {
         + "group by grouping sets (deptno, (deptno, gender), ())")
         .ok("SELECT `DEPTNO`, (GROUPING(`DEPTNO`))\n"
             + "FROM `EMP`\n"
-            + "GROUP BY (GROUPING_SETS(`DEPTNO`, (ROW(`DEPTNO`, `GENDER`)),))");
+            + "GROUP BY GROUPING SETS(`DEPTNO`, (`DEPTNO`, `GENDER`), ())");
   }
 
   @Test public void testWith() {
@@ -864,8 +864,8 @@ public class SqlParserTest {
             + "select deptno from femaleEmps",
         "WITH `FEMALEEMPS` AS (SELECT *\n"
             + "FROM `EMPS`\n"
-            + "WHERE (`GENDER` = 'F')) SELECT `DEPTNO`\n"
-            + "FROM `FEMALEEMPS`");
+            + "WHERE (`GENDER` = 'F')) (SELECT `DEPTNO`\n"
+            + "FROM `FEMALEEMPS`)");
   }
 
   @Test public void testWith2() {
@@ -877,8 +877,8 @@ public class SqlParserTest {
             + "FROM `EMPS`\n"
             + "WHERE (`GENDER` = 'F')), `MARRIEDFEMALEEMPS` (`X`, `Y`) AS (SELECT *\n"
             + "FROM `FEMALEEMPS`\n"
-            + "WHERE (`MARITASTATUS` = 'M')) SELECT `DEPTNO`\n"
-            + "FROM `FEMALEEMPS`");
+            + "WHERE (`MARITASTATUS` = 'M')) (SELECT `DEPTNO`\n"
+            + "FROM `FEMALEEMPS`)");
   }
 
   @Test public void testWithFails() {
@@ -891,8 +891,8 @@ public class SqlParserTest {
     check(
         "with v(i,c) as (values (1, 'a'), (2, 'bb'))\n"
             + "select c, i from v",
-        "WITH `V` (`I`, `C`) AS (VALUES (ROW(1, 'a')), (ROW(2, 'bb'))) SELECT `C`, `I`\n"
-            + "FROM `V`");
+        "WITH `V` (`I`, `C`) AS (VALUES (ROW(1, 'a')), (ROW(2, 'bb'))) (SELECT `C`, `I`\n"
+            + "FROM `V`)");
   }
 
   @Test public void testWithNestedFails() {
@@ -910,9 +910,9 @@ public class SqlParserTest {
             + "  with dept2 as (select * from dept)\n"
             + "  select 1 as one from empDept)",
         "WITH `EMP2` AS (SELECT *\n"
-            + "FROM `EMP`) WITH `DEPT2` AS (SELECT *\n"
-            + "FROM `DEPT`) SELECT 1 AS `ONE`\n"
-            + "FROM `EMPDEPT`");
+            + "FROM `EMP`) (WITH `DEPT2` AS (SELECT *\n"
+            + "FROM `DEPT`) (SELECT 1 AS `ONE`\n"
+            + "FROM `EMPDEPT`))");
   }
 
   @Test public void testWithUnion() {
@@ -1627,12 +1627,12 @@ public class SqlParserTest {
     // stuff inside comment
     check(
         "values ( /** 1, 2 + ** */ 3)",
-        "(VALUES (ROW(3)))");
+        "VALUES (ROW(3))");
 
     // comment in string is preserved
     check(
         "values ('a string with /* a comment */ in it')",
-        "(VALUES (ROW('a string with /* a comment */ in it')))");
+        "VALUES (ROW('a string with /* a comment */ in it'))");
 
     // SQL:2003, 5.2, syntax rule # 8 "There shall be no <separator>
     // separating the <minus sign>s of a <simple comment introducer>".
@@ -1640,12 +1640,12 @@ public class SqlParserTest {
     check(
         "values (- -1\n"
             + ")",
-        "(VALUES (ROW((- -1))))");
+        "VALUES (ROW((- -1)))");
 
     check(
         "values (--1+\n"
             + "2)",
-        "(VALUES (ROW(2)))");
+        "VALUES (ROW(2))");
 
     // end of multiline commment without start
     if (Bug.FRG73_FIXED) {
@@ -1692,29 +1692,29 @@ public class SqlParserTest {
     check(
         "values (1 + /* comment -- rest of line\n"
             + " rest of comment */ 2)",
-        "(VALUES (ROW((1 + 2))))");
+        "VALUES (ROW((1 + 2)))");
 
     // multiline comment inside singleline comment
     check(
         "values -- rest of line /* a comment */ \n"
             + "(1)",
-        "(VALUES (ROW(1)))");
+        "VALUES (ROW(1))");
 
     // non-terminated multiline comment inside singleline comment
     check(
         "values -- rest of line /* a comment  \n"
             + "(1)",
-        "(VALUES (ROW(1)))");
+        "VALUES (ROW(1))");
 
     // even if comment abuts the tokens at either end, it becomes a space
     check(
         "values ('abc'/* a comment*/'def')",
-        "(VALUES (ROW('abc'\n'def')))");
+        "VALUES (ROW('abc'\n'def'))");
 
     // comment which starts as soon as it has begun
     check(
         "values /**/ (1)",
-        "(VALUES (ROW(1)))");
+        "VALUES (ROW(1))");
   }
 
   // expressions
@@ -1939,11 +1939,11 @@ public class SqlParserTest {
   }
 
   @Test public void testValues() {
-    check("values(1,'two')", "(VALUES (ROW(1, 'two')))");
+    check("values(1,'two')", "VALUES (ROW(1, 'two'))");
   }
 
   @Test public void testValuesExplicitRow() {
-    check("values row(1,'two')", "(VALUES (ROW(1, 'two')))");
+    check("values row(1,'two')", "VALUES (ROW(1, 'two'))");
   }
 
   @Test public void testFromValues() {
@@ -1980,34 +1980,34 @@ public class SqlParserTest {
   @Test public void testTableExtend() {
     sql("select * from emp extend (x int, y varchar(10) not null)")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10)))");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10))");
     sql("select * from emp extend (x int, y varchar(10) not null) where true")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10)))\n"
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10))\n"
             + "WHERE TRUE");
     // with table alias
     sql("select * from emp extend (x int, y varchar(10) not null) as t")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10))) AS `T`");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10)) AS `T`");
     // as previous, without AS
     sql("select * from emp extend (x int, y varchar(10) not null) t")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10))) AS `T`");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10)) AS `T`");
     // with table alias and column alias list
     sql("select * from emp extend (x int, y varchar(10) not null) as t(a, b)")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10))) AS `T` (`A`, `B`)");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10)) AS `T` (`A`, `B`)");
     // as previous, without AS
     sql("select * from emp extend (x int, y varchar(10) not null) t(a, b)")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10))) AS `T` (`A`, `B`)");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10)) AS `T` (`A`, `B`)");
     // omit EXTEND
     sql("select * from emp (x int, y varchar(10) not null) t(a, b)")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10))) AS `T` (`A`, `B`)");
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10)) AS `T` (`A`, `B`)");
     sql("select * from emp (x int, y varchar(10) not null) where x = y")
         .ok("SELECT *\n"
-            + "FROM (EXTEND(`EMP`, `X`, INTEGER, `Y`, VARCHAR(10)))\n"
+            + "FROM `EMP` EXTEND (`X` INTEGER, `Y` VARCHAR(10))\n"
             + "WHERE (`X` = `Y`)");
   }
 
@@ -2188,7 +2188,7 @@ public class SqlParserTest {
 
   @Test public void testUpdate() {
     sql("update emps set empno = empno + 1, sal = sal - 1 where empno=12")
-        .ok("UPDATE `EMPS` (`EMPNO`, `SAL`) SET `EMPNO` = (`EMPNO` + 1)\n"
+        .ok("UPDATE `EMPS` SET `EMPNO` = (`EMPNO` + 1)\n"
                 + ", `SAL` = (`SAL` - 1)\n"
                 + "WHERE (`EMPNO` = 12)");
   }
@@ -5655,8 +5655,8 @@ public class SqlParserTest {
         "values _UTF16'"
             + ConversionUtil.TEST_UNICODE_STRING + "'";
     String out1 =
-        "(VALUES (ROW(_UTF16'"
-            + ConversionUtil.TEST_UNICODE_STRING + "')))";
+        "VALUES (ROW(_UTF16'"
+            + ConversionUtil.TEST_UNICODE_STRING + "'))";
     check(in1, out1);
 
     // Without the U& prefix, escapes are left unprocessed
@@ -5664,8 +5664,8 @@ public class SqlParserTest {
         "values '"
             + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "'";
     String out2 =
-        "(VALUES (ROW('"
-            + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "')))";
+        "VALUES (ROW('"
+            + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "'))";
     check(in2, out2);
 
     // Likewise, even with the U& prefix, if some other escape
@@ -5676,8 +5676,8 @@ public class SqlParserTest {
             + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL
             + "' UESCAPE '!'";
     String out3 =
-        "(VALUES (ROW(_UTF16'"
-            + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "')))";
+        "VALUES (ROW(_UTF16'"
+            + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "'))";
     check(in3, out3);
   }
 
@@ -5689,8 +5689,8 @@ public class SqlParserTest {
         "values U&'"
             + ConversionUtil.TEST_UNICODE_SQL_ESCAPED_LITERAL + "'";
     String out =
-        "(VALUES (ROW(_UTF16'"
-            + ConversionUtil.TEST_UNICODE_STRING + "')))";
+        "VALUES (ROW(_UTF16'"
+            + ConversionUtil.TEST_UNICODE_STRING + "'))";
     check(in, out);
 
     // Verify that we can override with an explicit escape character
@@ -5915,15 +5915,22 @@ public class SqlParserTest {
 
       // Unparse with no dialect, always parenthesize.
       final String actual = sqlNode.toSqlString(null, true).getSql();
-      assertEquals(expected, actual);
+      assertEquals(expected, linux(actual));
 
-      // Unparse again in Eigenbase dialect (which we can parse), and
+      // Unparse again in Calcite dialect (which we can parse), and
       // minimal parentheses.
       final String sql1 =
           sqlNode.toSqlString(SqlDialect.CALCITE, false).getSql();
 
       // Parse and unparse again.
-      SqlNode sqlNode2 = parseStmtAndHandleEx(sql1);
+      SqlNode sqlNode2;
+      final Quoting q = quoting;
+      try {
+        quoting = Quoting.DOUBLE_QUOTE;
+        sqlNode2 = parseStmtAndHandleEx(sql1);
+      } finally {
+        quoting = q;
+      }
       final String sql2 =
           sqlNode2.toSqlString(SqlDialect.CALCITE, false).getSql();
 
@@ -5934,7 +5941,7 @@ public class SqlParserTest {
       // If the unparser is not including sufficient parens to override
       // precedence, the problem will show up here.
       final String actual2 = sqlNode2.toSqlString(null, true).getSql();
-      assertEquals(expected, actual2);
+      assertEquals(expected, linux(actual2));
     }
 
     public void checkExp(String sql, String expected) {
@@ -5942,15 +5949,22 @@ public class SqlParserTest {
 
       // Unparse with no dialect, always parenthesize.
       final String actual = sqlNode.toSqlString(null, true).getSql();
-      assertEquals(expected, actual);
+      assertEquals(expected, linux(actual));
 
-      // Unparse again in Eigenbase dialect (which we can parse), and
+      // Unparse again in Calcite dialect (which we can parse), and
       // minimal parentheses.
       final String sql1 =
           sqlNode.toSqlString(SqlDialect.CALCITE, false).getSql();
 
       // Parse and unparse again.
-      SqlNode sqlNode2 = parseExpressionAndHandleEx(sql1);
+      SqlNode sqlNode2;
+      final Quoting q = quoting;
+      try {
+        quoting = Quoting.DOUBLE_QUOTE;
+        sqlNode2 = parseExpressionAndHandleEx(sql1);
+      } finally {
+        quoting = q;
+      }
       final String sql2 =
           sqlNode2.toSqlString(SqlDialect.CALCITE, false).getSql();
 
@@ -5961,7 +5975,7 @@ public class SqlParserTest {
       // If the unparser is not including sufficient parens to override
       // precedence, the problem will show up here.
       final String actual2 = sqlNode2.toSqlString(null, true).getSql();
-      assertEquals(expected, actual2);
+      assertEquals(expected, linux(actual2));
     }
 
     public void checkFails(String sql, String expectedMsgPattern) {
@@ -5973,6 +5987,13 @@ public class SqlParserTest {
     }
   }
 
+  private String linux(String s) {
+    if (LINUXIFY.get()[0]) {
+      s = Util.toLinux(s);
+    }
+    return s;
+  }
+
   /** Helper class for building fluent code such as
    * {@code sql("values 1").ok();}. */
   private class Sql {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/057f847b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
index f50a8f1..09c9aa7 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
@@ -18,6 +18,7 @@ package org.apache.calcite.test;
 
 import org.apache.calcite.adapter.clone.ArrayTableTest;
 import org.apache.calcite.jdbc.CalciteRemoteDriverTest;
+import org.apache.calcite.plan.RelOptPlanReaderTest;
 import org.apache.calcite.plan.RelOptUtilTest;
 import org.apache.calcite.plan.RelWriterTest;
 import org.apache.calcite.plan.volcano.TraitPropagationTest;
@@ -28,6 +29,7 @@ import org.apache.calcite.rex.RexExecutorTest;
 import org.apache.calcite.runtime.BinarySearchTest;
 import org.apache.calcite.runtime.EnumerablesTest;
 import org.apache.calcite.sql.parser.SqlParserTest;
+import org.apache.calcite.sql.parser.SqlUnParserTest;
 import org.apache.calcite.sql.test.SqlAdvisorTest;
 import org.apache.calcite.sql.test.SqlOperatorTest;
 import org.apache.calcite.sql.test.SqlPrettyWriterTest;
@@ -88,9 +90,11 @@ import org.junit.runners.Suite;
     EnumerablesTest.class,
     ExceptionMessageTest.class,
     InduceGroupingTypeTest.class,
+    RelOptPlanReaderTest.class,
 
     // medium tests (above 0.1s)
     SqlParserTest.class,
+    SqlUnParserTest.class,
     SqlPrettyWriterTest.class,
     SqlValidatorTest.class,
     SqlAdvisorTest.class,