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 2022/07/11 20:13:40 UTC
[calcite] 01/01: [CALCITE-5194] Cannot parse parenthesized UNION in FROM
This is an automated email from the ASF dual-hosted git repository.
jhyde pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit d40b55cb7af21d170ff10eff026351d8b034b917
Author: Julian Hyde <jh...@apache.org>
AuthorDate: Wed Jun 22 17:26:56 2022 -0700
[CALCITE-5194] Cannot parse parenthesized UNION in FROM
---
core/src/main/codegen/templates/Parser.jj | 6 +-
.../apache/calcite/sql/parser/SqlParserTest.java | 96 ++++++++++++++++++++++
2 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index c7186f3fbd..f466664850 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -612,6 +612,7 @@ JAVACODE boolean matchesPrefix(int[] seq, int[][] prefixes)
SqlNode ExprOrJoinOrOrderedQuery(ExprContext exprContext) :
{
SqlNode e;
+ final List<Object> list = new ArrayList<Object>();
}
{
// Lookhead to distinguish between "TABLE emp" (which will be
@@ -621,11 +622,14 @@ SqlNode ExprOrJoinOrOrderedQuery(ExprContext exprContext) :
LOOKAHEAD(2)
e = Query(exprContext)
e = OrderByLimitOpt(e)
+ { return e; }
|
e = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
( e = JoinTable(e) )*
+ { list.add(e); }
+ ( AddSetOpQuery(list, exprContext) )*
+ { return SqlParserUtil.toTree(list); }
)
- { return e; }
}
/**
diff --git a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 6be9d3e3e8..fd6d29cd8d 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -8186,6 +8186,102 @@ public class SqlParserTest {
sql(sql2).ok(expected2);
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-5194">[CALCITE-5194]
+ * Cannot parse parenthesized UNION in FROM</a>. */
+ @Test void testParenthesizedUnionInFrom() {
+ final String sql = "select *\n"
+ + "from (\n"
+ + " (select x from a)\n"
+ + " union\n"
+ + " (select y from b))";
+ final String expected = "SELECT *\n"
+ + "FROM (SELECT `X`\n"
+ + "FROM `A`\n"
+ + "UNION\n"
+ + "SELECT `Y`\n"
+ + "FROM `B`)";
+ sql(sql).ok(expected);
+ }
+
+ @Test void testParenthesizedUnionAndJoinInFrom() {
+ final String sql = "select *\n"
+ + "from (\n"
+ + " (select x from a) as a"
+ + " cross join\n"
+ + " (select x from a\n"
+ + " union\n"
+ + " select y from b) as b)";
+ final String expected = "SELECT *\n"
+ + "FROM (SELECT `X`\n"
+ + "FROM `A`) AS `A`\n"
+ + "CROSS JOIN (SELECT `X`\n"
+ + "FROM `A`\n"
+ + "UNION\n"
+ + "SELECT `Y`\n"
+ + "FROM `B`) AS `B`";
+ sql(sql).ok(expected);
+ }
+
+ /** As {@link #testParenthesizedUnionAndJoinInFrom()}
+ * but the UNION is the first input to the JOIN. */
+ @Test void testParenthesizedUnionAndJoinInFrom2() {
+ final String sql = "select *\n"
+ + "from (\n"
+ + " (select x from a\n"
+ + " union\n"
+ + " select y from b) as b\n"
+ + " cross join\n"
+ + " (select x from a) as a)";
+ final String expected = "SELECT *\n"
+ + "FROM (SELECT `X`\n"
+ + "FROM `A`\n"
+ + "UNION\n"
+ + "SELECT `Y`\n"
+ + "FROM `B`) AS `B`\n"
+ + "CROSS JOIN (SELECT `X`\n"
+ + "FROM `A`) AS `A`";
+ sql(sql).ok(expected);
+ }
+
+ /** As {@link #testParenthesizedUnionAndJoinInFrom2()}
+ * but INNER JOIN rather than CROSS JOIN. */
+ @Test void testParenthesizedUnionAndJoinInFrom3() {
+ final String sql = "select *\n"
+ + "from (\n"
+ + " (select x from a\n"
+ + " union\n"
+ + " select y from b) as b\n"
+ + " join\n"
+ + " (select x from a) as a on b.x = a.x)";
+ final String expected = "SELECT *\n"
+ + "FROM (SELECT `X`\n"
+ + "FROM `A`\n"
+ + "UNION\n"
+ + "SELECT `Y`\n"
+ + "FROM `B`) AS `B`\n"
+ + "INNER JOIN (SELECT `X`\n"
+ + "FROM `A`) AS `A` ON (`B`.`X` = `A`.`X`)";
+ sql(sql).ok(expected);
+ }
+
+ @Test void testParenthesizedUnion() {
+ final String sql = "(select x from a\n"
+ + " union\n"
+ + " select y from b)\n"
+ + "except\n"
+ + "(select z from c)";
+ final String expected = "((SELECT `X`\n"
+ + "FROM `A`\n"
+ + "UNION\n"
+ + "SELECT `Y`\n"
+ + "FROM `B`)\n"
+ + "EXCEPT\n"
+ + "SELECT `Z`\n"
+ + "FROM `C`)";
+ sql(sql).ok(expected);
+ }
+
@Test void testFromExpr() {
String sql0 = "select * from a cross join b";
String sql1 = "select * from (a cross join b)";