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 da71139 [CALCITE-3929] When deserialize UDAF aggregate call from json string, throws NPE (Xu Zhaohui) da71139 is described below commit da7113949d6e22979cbb6981c1992a44db70cd4e Author: xzh <953396...@qq.com> AuthorDate: Thu Jun 11 20:56:32 2020 +0800 [CALCITE-3929] When deserialize UDAF aggregate call from json string, throws NPE (Xu Zhaohui) --- .../org/apache/calcite/rel/externalize/RelJson.java | 6 +++++- .../java/org/apache/calcite/plan/RelWriterTest.java | 21 +++++++++++++++++++++ .../apache/calcite/test/MockSqlOperatorTable.java | 10 ++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) 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 2c9a0ca..7ee8519 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 @@ -273,7 +273,11 @@ public class RelJson { public Object toJson(AggregateCall node) { final Map<String, Object> map = jsonBuilder.map(); - map.put("agg", toJson(node.getAggregation())); + final Map<String, Object> aggMap = toJson(node.getAggregation()); + if (node.getAggregation().getFunctionType().isUserDefined()) { + aggMap.put("class", node.getAggregation().getClass().getName()); + } + map.put("agg", aggMap); map.put("type", toJson(node.getType())); map.put("distinct", node.isDistinct()); map.put("operands", node.getArgList()); 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 55a3d58..f64793e 100644 --- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java +++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java @@ -797,6 +797,27 @@ class RelWriterTest { assertThat(s, isLinux(expected)); } + @Test void testUDAF() { + final FrameworkConfig config = RelBuilderTest.config().build(); + final RelBuilder builder = RelBuilder.create(config); + final RelNode rel = builder + .scan("EMP") + .project(builder.field("ENAME"), builder.field("DEPTNO")) + .aggregate( + builder.groupKey("ENAME"), + builder.aggregateCall(new MockSqlOperatorTable.MyAggFunc(), + builder.field("DEPTNO"))) + .build(); + final String relJson = RelOptUtil.dumpPlan("", rel, + SqlExplainFormat.JSON, SqlExplainLevel.EXPPLAN_ATTRIBUTES); + final String result = deserializeAndDumpToTextFormat(getSchema(rel), relJson); + final String expected = "" + + "LogicalAggregate(group=[{0}], agg#0=[myAggFunc($1)])\n" + + " LogicalProject(ENAME=[$1], DEPTNO=[$7])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(result, isLinux(expected)); + } + @Test void testArrayType() { final FrameworkConfig config = RelBuilderTest.config().build(); final RelBuilder builder = RelBuilder.create(config); diff --git a/core/src/test/java/org/apache/calcite/test/MockSqlOperatorTable.java b/core/src/test/java/org/apache/calcite/test/MockSqlOperatorTable.java index 0c574a5..b1ac440 100644 --- a/core/src/test/java/org/apache/calcite/test/MockSqlOperatorTable.java +++ b/core/src/test/java/org/apache/calcite/test/MockSqlOperatorTable.java @@ -125,6 +125,16 @@ public class MockSqlOperatorTable extends ChainedSqlOperatorTable { } } + /** "MYAGGFUNC" user-defined aggregate function. This agg function accept one or more arguments + * in order to reproduce the throws of CALCITE-3929. */ + public static class MyAggFunc extends SqlAggFunction { + public MyAggFunc() { + super("myAggFunc", null, SqlKind.OTHER_FUNCTION, ReturnTypes.BIGINT, null, + OperandTypes.ONE_OR_MORE, SqlFunctionCategory.USER_DEFINED_FUNCTION, false, false, + Optionality.FORBIDDEN); + } + } + /** * "SPLIT" user-defined function. This function return array type * in order to reproduce the throws of CALCITE-4062.