You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mm...@apache.org on 2019/06/07 14:47:43 UTC

[calcite] branch master updated: [CALCITE-2721] Support parsing record-type [DOT] member-functions

This is an automated email from the ASF dual-hosted git repository.

mmior pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 4513a72  [CALCITE-2721] Support parsing record-type [DOT] member-functions
4513a72 is described below

commit 4513a7293c7ce2307ecdb8129a9167165fc59ab5
Author: Rong Rong <wa...@hotmail.com>
AuthorDate: Thu Jan 24 19:48:21 2019 -0800

    [CALCITE-2721] Support parsing record-type [DOT] member-functions
    
    Close apache/calcite#1011
---
 core/src/main/codegen/templates/Parser.jj          | 54 ++++++++++++++++++++--
 .../apache/calcite/sql/parser/SqlParserTest.java   | 22 ++++++++-
 .../org/apache/calcite/test/SqlValidatorTest.java  | 12 ++++-
 3 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 5161984..bebc52f 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -3060,7 +3060,7 @@ void Expression2b(ExprContext exprContext, List<Object> list) :
 {
     SqlNode e;
     SqlOperator op;
-    SqlIdentifier p;
+    SqlNode ext;
 }
 {
     (
@@ -3075,11 +3075,11 @@ void Expression2b(ExprContext exprContext, List<Object> list) :
     }
     (
         LOOKAHEAD(2) <DOT>
-        p = SimpleIdentifier() {
+        ext = RowExpressionExtension() {
             list.add(
                 new SqlParserUtil.ToTreeListItem(
                     SqlStdOperatorTable.DOT, getPos()));
-            list.add(p);
+            list.add(ext);
         }
     )*
 }
@@ -3437,6 +3437,54 @@ SqlNode UnsignedNumericLiteralOrParam() :
 }
 
 /**
+ * Parses a row expression extension, it can be either an identifier,
+ * or a call to a named function.
+ */
+SqlNode RowExpressionExtension() :
+{
+    final SqlFunctionCategory funcType;
+    final SqlIdentifier p;
+    final Span s;
+    final List<SqlNode> args;
+    SqlCall call;
+    SqlNode e;
+    SqlLiteral quantifier = null;
+}
+{
+    p = SimpleIdentifier() {
+        e = p;
+    }
+    (
+        LOOKAHEAD( <LPAREN> ) { s = span(); }
+        {
+            funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
+        }
+        (
+            LOOKAHEAD(2) <LPAREN> <STAR> {
+                args = startList(SqlIdentifier.star(getPos()));
+            }
+            <RPAREN>
+        |
+            LOOKAHEAD(2) <LPAREN> <RPAREN> {
+                args = Collections.emptyList();
+            }
+        |
+            args = FunctionParameterList(ExprContext.ACCEPT_SUB_QUERY) {
+                quantifier = (SqlLiteral) args.get(0);
+                args.remove(0);
+            }
+        )
+        {
+            call = createCall(p, s.end(this), funcType, quantifier, args);
+            e = call;
+        }
+    )?
+    {
+        return e;
+    }
+}
+
+/**
  * Parses an atomic row expression.
  */
 SqlNode AtomicRowExpression() :
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 5fc871d..3160d9c 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
@@ -1128,9 +1128,11 @@ public class SqlParserTest {
     return false;
   }
 
-  @Test public void testRowWitDot() {
+  @Test public void testRowWithDot() {
     check("select (1,2).a from c.t", "SELECT ((ROW(1, 2)).`A`)\nFROM `C`.`T`");
     check("select row(1,2).a from c.t", "SELECT ((ROW(1, 2)).`A`)\nFROM `C`.`T`");
+    check("select tbl.foo(0).col.bar from tbl",
+        "SELECT ((`TBL`.`FOO`(0).`COL`).`BAR`)\nFROM `TBL`");
   }
 
   @Test public void testPeriod() {
@@ -7526,6 +7528,24 @@ public class SqlParserTest {
         "(?s).*Encountered \"from\" at .*");
   }
 
+  /**
+   * Tests that applying member function of a specific type as a suffix function
+   */
+  @Test public void testMemberFunction() {
+    check("SELECT myColumn.func(a, b) FROM tbl",
+        "SELECT `MYCOLUMN`.`FUNC`(`A`, `B`)\n"
+            + "FROM `TBL`");
+    check("SELECT myColumn.mySubField.func() FROM tbl",
+        "SELECT `MYCOLUMN`.`MYSUBFIELD`.`FUNC`()\n"
+            + "FROM `TBL`");
+    check("SELECT tbl.myColumn.mySubField.func() FROM tbl",
+        "SELECT `TBL`.`MYCOLUMN`.`MYSUBFIELD`.`FUNC`()\n"
+            + "FROM `TBL`");
+    check("SELECT tbl.foo(0).col.bar(2, 3) FROM tbl",
+        "SELECT ((`TBL`.`FOO`(0).`COL`).`BAR`(2, 3))\n"
+            + "FROM `TBL`");
+  }
+
   @Test public void testUnicodeLiteral() {
     // Note that here we are constructing a SQL statement which directly
     // contains Unicode characters (not SQL Unicode escape sequences).  The
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index c5e4b61..89e0d3b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -1240,6 +1240,16 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
     }
   }
 
+  /**
+   * Not able to parse member function yet.
+   */
+  @Test public void testInvalidMemberFunction() {
+    checkExpFails("myCol.^func()^",
+        "(?s).*No match found for function signature FUNC().*");
+    checkExpFails("myCol.mySubschema.^memberFunc()^",
+        "(?s).*No match found for function signature MEMBERFUNC().*");
+  }
+
   @Test public void testRowtype() {
     check("values (1),(2),(1)");
     checkResultType(
@@ -1267,7 +1277,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
         "INTEGER NOT NULL");
   }
 
-  @Test public void testRowWitValidDot() {
+  @Test public void testRowWithValidDot() {
     checkColumnType("select ((1,2),(3,4,5)).\"EXPR$1\".\"EXPR$2\"\n from dept",
         "INTEGER NOT NULL");
     checkColumnType("select row(1,2).\"EXPR$1\" from dept",