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

chunwei 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 f99ff5f  [CALCITE-3246] NullPointerException while deserializing udf 
operator (Wang Yanlin).
f99ff5f is described below

commit f99ff5f4b5bb305f5fd3726d212363f75e8150f2
Author: yanzhi <yanzhi....@antfin.com>
AuthorDate: Tue Aug 13 13:56:44 2019 +0800

    [CALCITE-3246] NullPointerException while deserializing udf operator (Wang 
Yanlin).
---
 .../apache/calcite/rel/externalize/RelJson.java    | 14 ++++++----
 .../calcite/rel/externalize/RelJsonReader.java     |  2 +-
 .../org/apache/calcite/plan/RelWriterTest.java     | 32 ++++++++++++++++++++++
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java 
b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
index c7fe76f..abb240e 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
@@ -440,13 +440,15 @@ public class RelJson {
       final Map<String, Object> opMap = (Map) map.get("op");
       final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
       if (opMap != null) {
-        final String op = (String) opMap.get("name");
+        if (map.containsKey("class")) {
+          opMap.put("class", map.get("class"));
+        }
         final List operands = (List) map.get("operands");
         final List<RexNode> rexOperands = toRexList(relInput, operands);
         final Object jsonType = map.get("type");
         final Map window = (Map) map.get("window");
         if (window != null) {
-          final SqlAggFunction operator = toAggregation(relInput, op, opMap);
+          final SqlAggFunction operator = toAggregation(opMap);
           final RelDataType type = toType(typeFactory, jsonType);
           final List<RexNode> partitionKeys = toRexList(relInput, (List) 
window.get("partition"));
           final List<RexFieldCollation> orderKeys =
@@ -473,7 +475,7 @@ public class RelJson {
               ImmutableList.copyOf(orderKeys), lowerBound, upperBound, 
physical,
               true, false, distinct, false);
         } else {
-          final SqlOperator operator = toOp(relInput, opMap);
+          final SqlOperator operator = toOp(opMap);
           final RelDataType type;
           if (jsonType != null) {
             type = toType(typeFactory, jsonType);
@@ -607,7 +609,7 @@ public class RelJson {
     return list;
   }
 
-  SqlOperator toOp(RelInput relInput, Map<String, Object> map) {
+  SqlOperator toOp(Map<String, Object> map) {
     // in case different operator has the same kind, check with both name and 
kind.
     String name = map.get("name").toString();
     String kind = map.get("kind").toString();
@@ -633,8 +635,8 @@ public class RelJson {
     return null;
   }
 
-  SqlAggFunction toAggregation(RelInput relInput, String agg, Map<String, 
Object> map) {
-    return (SqlAggFunction) toOp(relInput, map);
+  SqlAggFunction toAggregation(Map<String, Object> map) {
+    return (SqlAggFunction) toOp(map);
   }
 
   private Map toJson(SqlOperator operator) {
diff --git 
a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java 
b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java
index e7a73a8..4cef915 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java
@@ -275,7 +275,7 @@ public class RelJsonReader {
   private AggregateCall toAggCall(RelInput relInput, Map<String, Object> 
jsonAggCall) {
     final Map<String, Object> aggMap = (Map) jsonAggCall.get("agg");
     final SqlAggFunction aggregation =
-        relJson.toAggregation(relInput, (String) aggMap.get("name"), aggMap);
+        relJson.toAggregation(aggMap);
     final Boolean distinct = (Boolean) jsonAggCall.get("distinct");
     @SuppressWarnings("unchecked")
     final List<Integer> operands = (List<Integer>) jsonAggCall.get("operands");
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 0e74702..3feb934 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -41,6 +41,7 @@ import org.apache.calcite.sql.fun.SqlTrimFunction;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.test.JdbcTest;
+import org.apache.calcite.test.MockSqlOperatorTable;
 import org.apache.calcite.test.RelBuilderTest;
 import org.apache.calcite.tools.FrameworkConfig;
 import org.apache.calcite.tools.Frameworks;
@@ -581,6 +582,37 @@ public class RelWriterTest {
     assertThat(s, isLinux(expected));
   }
 
+  @Test public void testUdf() {
+    final FrameworkConfig config = RelBuilderTest.config().build();
+    final RelBuilder builder = RelBuilder.create(config);
+    final RelNode rel = builder
+        .scan("EMP")
+        .project(
+            builder.call(new MockSqlOperatorTable.MyFunction(),
+                builder.field("EMPNO")))
+        .build();
+    RelJsonWriter jsonWriter = new RelJsonWriter();
+    rel.explain(jsonWriter);
+    String relJson = jsonWriter.asString();
+    String s =
+        Frameworks.withPlanner((cluster, relOptSchema, rootSchema) -> {
+          final RelJsonReader reader = new RelJsonReader(
+              cluster, getSchema(rel), rootSchema);
+          RelNode node;
+          try {
+            node = reader.read(relJson);
+          } catch (IOException e) {
+            throw TestUtil.rethrow(e);
+          }
+          return RelOptUtil.dumpPlan("", node, SqlExplainFormat.TEXT,
+              SqlExplainLevel.EXPPLAN_ATTRIBUTES);
+        });
+    final String expected = ""
+        + "LogicalProject($f0=[MYFUN($0)])\n"
+        + "  LogicalTableScan(table=[[scott, EMP]])\n";
+    assertThat(s, isLinux(expected));
+  }
+
   /** Returns the schema of a {@link org.apache.calcite.rel.core.TableScan}
    * in this plan, or null if there are no scans. */
   private RelOptSchema getSchema(RelNode rel) {

Reply via email to