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,