You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by xx...@apache.org on 2023/05/06 06:59:08 UTC
[kylin] 07/38: KYLIN-5524 Supports CONCAT for variable arguments
This is an automated email from the ASF dual-hosted git repository.
xxyu pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git
commit f929bd876ed54afbd1490d2717894288fd197ec6
Author: sibingzhang <74...@users.noreply.github.com>
AuthorDate: Tue Feb 14 13:54:41 2023 +0800
KYLIN-5524 Supports CONCAT for variable arguments
---
.../kylin/query/udf/stringUdf/ConcatUDF.java | 45 +++++++++++++++++++---
.../org/apache/kylin/query/udf/StringUDFTest.java | 21 +++++++---
.../kylin/query/runtime/ExpressionConverter.scala | 2 +-
3 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/src/query/src/main/java/org/apache/kylin/query/udf/stringUdf/ConcatUDF.java b/src/query/src/main/java/org/apache/kylin/query/udf/stringUdf/ConcatUDF.java
index 01f16d47e6..841cc16bfe 100644
--- a/src/query/src/main/java/org/apache/kylin/query/udf/stringUdf/ConcatUDF.java
+++ b/src/query/src/main/java/org/apache/kylin/query/udf/stringUdf/ConcatUDF.java
@@ -18,14 +18,49 @@
package org.apache.kylin.query.udf.stringUdf;
-import org.apache.calcite.linq4j.function.Parameter;
+import org.apache.calcite.adapter.enumerable.CallImplementor;
+import org.apache.calcite.adapter.enumerable.UdfMethodNameImplementor;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.fun.udf.UdfDef;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.OperandTypes;
+import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.calcite.sql.type.SqlOperandCountRanges;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.type.SqlTypeTransforms;
-public class ConcatUDF {
+import java.util.Arrays;
+import java.util.stream.Collectors;
- public String CONCAT(@Parameter(name = "col1") Object col1, @Parameter(name = "col2") Object col2) {
- if (col1 == null || col2 == null) {
+public class ConcatUDF implements UdfDef {
+
+ private static final String FUNC_NAME = "CONCAT";
+
+ private ConcatUDF() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ public static final SqlFunction OPERATOR = new SqlFunction(new SqlIdentifier(FUNC_NAME, SqlParserPos.ZERO),
+ ReturnTypes.cascade(opBinding -> {
+ int precision = opBinding.collectOperandTypes().stream().mapToInt(RelDataType::getPrecision).sum();
+ return opBinding.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, precision);
+ }, SqlTypeTransforms.TO_NULLABLE),
+ (callBinding, returnType, operandTypes) -> Arrays.fill(operandTypes,
+ callBinding.getTypeFactory().createJavaType(Object.class)),
+ OperandTypes.repeat(SqlOperandCountRanges.from(2), OperandTypes.ANY), null,
+ SqlFunctionCategory.USER_DEFINED_FUNCTION);
+
+ public static final CallImplementor IMPLEMENTOR = new UdfMethodNameImplementor(FUNC_NAME.toLowerCase(),
+ ConcatUDF.class);
+
+ public static String concat(Object... args) {
+ if (args == null) {
return null;
}
- return "" + col1 + col2;
+
+ return Arrays.stream(args).map(String::valueOf).collect(Collectors.joining());
}
}
diff --git a/src/query/src/test/java/org/apache/kylin/query/udf/StringUDFTest.java b/src/query/src/test/java/org/apache/kylin/query/udf/StringUDFTest.java
index 543795a2aa..799660a37f 100644
--- a/src/query/src/test/java/org/apache/kylin/query/udf/StringUDFTest.java
+++ b/src/query/src/test/java/org/apache/kylin/query/udf/StringUDFTest.java
@@ -33,16 +33,27 @@ import org.junit.Test;
public class StringUDFTest {
@Test
- public void testConcatUDF() throws Exception {
- ConcatUDF cu = new ConcatUDF();
- String str1 = cu.CONCAT("Apache ", "Kylin");
+ public void testConcatUDF() {
+ String str1 = ConcatUDF.concat("Apache ", "Kylin");
assertEquals("Apache Kylin", str1);
- String str2 = cu.CONCAT("", "Kylin");
+ String str2 = ConcatUDF.concat("", "Kylin");
assertEquals("Kylin", str2);
- String str3 = cu.CONCAT("Apache", "");
+ String str3 = ConcatUDF.concat("Apache", "");
assertEquals("Apache", str3);
+
+ String str4 = ConcatUDF.concat("Apache", 1);
+ assertEquals("Apache1", str4);
+
+ String str5 = ConcatUDF.concat(1, 1);
+ assertEquals("11", str5);
+
+ String str6 = ConcatUDF.concat("Apache ", "Kylin", " Kyligence");
+ assertEquals("Apache Kylin Kyligence", str6);
+
+ String str7 = ConcatUDF.concat(null);
+ assertNull(str7);
}
@Test
diff --git a/src/spark-project/sparder/src/main/scala/org/apache/kylin/query/runtime/ExpressionConverter.scala b/src/spark-project/sparder/src/main/scala/org/apache/kylin/query/runtime/ExpressionConverter.scala
index a839116059..856c19f50f 100644
--- a/src/spark-project/sparder/src/main/scala/org/apache/kylin/query/runtime/ExpressionConverter.scala
+++ b/src/spark-project/sparder/src/main/scala/org/apache/kylin/query/runtime/ExpressionConverter.scala
@@ -284,7 +284,7 @@ object ExpressionConverter {
else children.apply(2).asInstanceOf[Int]
new Column(StringLocate(k_lit(children.head).expr, k_lit(children.apply(1)).expr, lit(pos).expr)) //position(substr,str,start)
case "concat" =>
- concat(k_lit(children.head), k_lit(children.apply(1)))
+ concat(children.map(k_lit): _*)
case "concat_ws" =>
concat_ws(children.head.toString, k_lit(children.apply(1)))
case "split_part" =>