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

rong pushed a commit to branch iotdb-3145
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 79bf5434ef40c792e921b2544f4b8894ebef1fee
Author: Steve Yurong Su <[email protected]>
AuthorDate: Fri May 13 16:38:09 2022 +0800

    support type inferring
---
 .../iotdb/db/mpp/plan/analyze/TypeProvider.java    |  4 +
 .../iotdb/db/query/expression/Expression.java      | 21 ++++++
 .../expression/binary/AdditionExpression.java      |  2 +-
 .../binary/ArithmeticBinaryExpression.java         | 60 +++++++++++++++
 .../expression/binary/CompareBinaryExpression.java | 85 ++++++++++++++++++++++
 .../expression/binary/DivisionExpression.java      |  2 +-
 .../query/expression/binary/EqualToExpression.java |  2 +-
 .../expression/binary/GreaterEqualExpression.java  |  2 +-
 .../expression/binary/GreaterThanExpression.java   |  2 +-
 .../expression/binary/LessEqualExpression.java     |  2 +-
 .../expression/binary/LessThanExpression.java      |  2 +-
 .../expression/binary/LogicAndExpression.java      |  2 +-
 ...rExpression.java => LogicBinaryExpression.java} | 35 ++++-----
 .../query/expression/binary/LogicOrExpression.java |  2 +-
 .../query/expression/binary/ModuloExpression.java  |  2 +-
 .../binary/MultiplicationExpression.java           |  2 +-
 .../expression/binary/NonEqualExpression.java      |  2 +-
 .../expression/binary/SubtractionExpression.java   |  2 +-
 .../db/query/expression/leaf/ConstantOperand.java  |  7 ++
 .../query/expression/leaf/TimeSeriesOperand.java   |  7 ++
 .../db/query/expression/leaf/TimestampOperand.java |  7 ++
 .../query/expression/multi/FunctionExpression.java | 18 +++++
 .../db/query/expression/unary/InExpression.java    | 11 +++
 .../db/query/expression/unary/LikeExpression.java  | 14 ++++
 .../query/expression/unary/LogicNotExpression.java | 14 ++++
 .../query/expression/unary/NegationExpression.java | 20 +++++
 .../query/expression/unary/RegularExpression.java  | 14 ++++
 .../api/customizer/parameter/UDFParameters.java    | 12 +++
 .../query/udf/core/executor/UDTFTypeInferrer.java  | 68 +++++++++++++++++
 29 files changed, 390 insertions(+), 33 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
index 34d8acfc9a..6c70c44e2d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
@@ -55,6 +55,10 @@ public class TypeProvider {
     this.typeMap.put(path, dataType);
   }
 
+  public boolean containsTypeInfoOf(String path) {
+    return typeMap.containsKey(path);
+  }
+
   public void serialize(ByteBuffer byteBuffer) {
     ReadWriteIOUtils.write(typeMap.size(), byteBuffer);
     for (Map.Entry<String, TSDataType> entry : typeMap.entrySet()) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java 
b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
index 14d5007739..b666e70fc9 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
@@ -22,6 +22,8 @@ package org.apache.iotdb.db.query.expression;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.query.expression.binary.AdditionExpression;
 import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
@@ -56,6 +58,7 @@ import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.time.ZoneId;
+import java.util.Arrays;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -108,6 +111,24 @@ public abstract class Expression {
   public abstract void constructUdfExecutors(
       Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId);
 
+  
/////////////////////////////////////////////////////////////////////////////////////////////////
+  // type inference
+  
/////////////////////////////////////////////////////////////////////////////////////////////////
+  public abstract TSDataType inferTypes(TypeProvider typeProvider);
+
+  protected static void checkInputExpressionDataType(
+      String expressionString, TSDataType actual, TSDataType... expected) {
+    for (TSDataType type : expected) {
+      if (actual.equals(type)) {
+        return;
+      }
+    }
+    throw new SemanticException(
+        String.format(
+            "Invalid input expression data type. expression: %s, actual data 
type: %s, expected data type(s): %s.",
+            expressionString, actual.name(), Arrays.toString(expected)));
+  }
+
   
/////////////////////////////////////////////////////////////////////////////////////////////////
   // For expression evaluation DAG building
   
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
index 6ec5ce8399..6fd5e698fc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticBinaryTra
 
 import java.nio.ByteBuffer;
 
-public class AdditionExpression extends BinaryExpression {
+public class AdditionExpression extends ArithmeticBinaryExpression {
 
   public AdditionExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
new file mode 100644
index 0000000000..185a8ce617
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.expression.binary;
+
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.nio.ByteBuffer;
+
+public abstract class ArithmeticBinaryExpression extends BinaryExpression {
+
+  protected ArithmeticBinaryExpression(Expression leftExpression, Expression 
rightExpression) {
+    super(leftExpression, rightExpression);
+  }
+
+  protected ArithmeticBinaryExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
+  @Override
+  public final TSDataType inferTypes(TypeProvider typeProvider) {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      checkInputExpressionDataType(
+          leftExpression.toString(),
+          leftExpression.inferTypes(typeProvider),
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      checkInputExpressionDataType(
+          rightExpression.toString(),
+          rightExpression.inferTypes(typeProvider),
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      typeProvider.setType(expressionString, TSDataType.DOUBLE);
+    }
+    return TSDataType.DOUBLE;
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
new file mode 100644
index 0000000000..66f795faa1
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.expression.binary;
+
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.nio.ByteBuffer;
+
+public abstract class CompareBinaryExpression extends BinaryExpression {
+
+  protected CompareBinaryExpression(Expression leftExpression, Expression 
rightExpression) {
+    super(leftExpression, rightExpression);
+  }
+
+  protected CompareBinaryExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    final String expressionString = toString();
+
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      final TSDataType leftExpressionDataType = 
leftExpression.inferTypes(typeProvider);
+      final TSDataType rightExpressionDataType = 
rightExpression.inferTypes(typeProvider);
+
+      if (!leftExpressionDataType.equals(rightExpressionDataType)) {
+        final String leftExpressionString = leftExpression.toString();
+        final String rightExpressionString = rightExpression.toString();
+
+        if (TSDataType.BOOLEAN.equals(leftExpressionDataType)
+            || TSDataType.BOOLEAN.equals(rightExpressionDataType)) {
+          checkInputExpressionDataType(
+              leftExpressionString, leftExpressionDataType, 
TSDataType.BOOLEAN);
+          checkInputExpressionDataType(
+              rightExpressionString, rightExpressionDataType, 
TSDataType.BOOLEAN);
+        } else if (TSDataType.TEXT.equals(leftExpressionDataType)
+            || TSDataType.TEXT.equals(rightExpressionDataType)) {
+          checkInputExpressionDataType(
+              leftExpressionString, leftExpressionDataType, TSDataType.TEXT);
+          checkInputExpressionDataType(
+              rightExpressionString, rightExpressionDataType, TSDataType.TEXT);
+        } else {
+          checkInputExpressionDataType(
+              leftExpressionString,
+              leftExpressionDataType,
+              TSDataType.INT32,
+              TSDataType.INT64,
+              TSDataType.FLOAT,
+              TSDataType.DOUBLE);
+          checkInputExpressionDataType(
+              rightExpressionString,
+              rightExpressionDataType,
+              TSDataType.INT32,
+              TSDataType.INT64,
+              TSDataType.FLOAT,
+              TSDataType.DOUBLE);
+        }
+      }
+
+      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+    }
+
+    return TSDataType.BOOLEAN;
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
index 5ba106f459..8eb9308d91 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticDivisionT
 
 import java.nio.ByteBuffer;
 
-public class DivisionExpression extends BinaryExpression {
+public class DivisionExpression extends ArithmeticBinaryExpression {
 
   public DivisionExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
index aa85becd07..d966284402 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareEqualToTrans
 
 import java.nio.ByteBuffer;
 
-public class EqualToExpression extends BinaryExpression {
+public class EqualToExpression extends CompareBinaryExpression {
 
   public EqualToExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
index 0364212ac8..6d06a29284 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareGreaterEqual
 
 import java.nio.ByteBuffer;
 
-public class GreaterEqualExpression extends BinaryExpression {
+public class GreaterEqualExpression extends CompareBinaryExpression {
 
   public GreaterEqualExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
index 56589b5e10..6a574f68e9 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareGreaterThanT
 
 import java.nio.ByteBuffer;
 
-public class GreaterThanExpression extends BinaryExpression {
+public class GreaterThanExpression extends CompareBinaryExpression {
 
   public GreaterThanExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
index 599a05f67b..a0fff83b49 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareLessEqualTra
 
 import java.nio.ByteBuffer;
 
-public class LessEqualExpression extends BinaryExpression {
+public class LessEqualExpression extends CompareBinaryExpression {
 
   public LessEqualExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
index 1852771e8e..8f49780392 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareLessThanTran
 
 import java.nio.ByteBuffer;
 
-public class LessThanExpression extends BinaryExpression {
+public class LessThanExpression extends CompareBinaryExpression {
 
   public LessThanExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
index 35f19c258b..26ac76b3c2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicBinaryTransfor
 
 import java.nio.ByteBuffer;
 
-public class LogicAndExpression extends BinaryExpression {
+public class LogicAndExpression extends LogicBinaryExpression {
 
   public LogicAndExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
similarity index 53%
copy from 
server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
copy to 
server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
index ee0609ae16..9ad7e20bfa 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
@@ -19,37 +19,32 @@
 
 package org.apache.iotdb.db.query.expression.binary;
 
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.ExpressionType;
-import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
-import 
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicBinaryTransformer;
-import 
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicOrTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
-public class LogicOrExpression extends BinaryExpression {
+public abstract class LogicBinaryExpression extends BinaryExpression {
 
-  public LogicOrExpression(Expression leftExpression, Expression 
rightExpression) {
+  protected LogicBinaryExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
   }
 
-  public LogicOrExpression(ByteBuffer byteBuffer) {
+  protected LogicBinaryExpression(ByteBuffer byteBuffer) {
     super(byteBuffer);
   }
 
   @Override
-  protected LogicBinaryTransformer constructTransformer(
-      LayerPointReader leftParentLayerPointReader, LayerPointReader 
rightParentLayerPointReader) {
-    return new LogicOrTransformer(leftParentLayerPointReader, 
rightParentLayerPointReader);
-  }
-
-  @Override
-  protected String operator() {
-    return "|";
-  }
-
-  @Override
-  public ExpressionType getExpressionType() {
-    return ExpressionType.LOGIC_OR;
+  public final TSDataType inferTypes(TypeProvider typeProvider) {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      checkInputExpressionDataType(
+          leftExpression.toString(), leftExpression.inferTypes(typeProvider), 
TSDataType.BOOLEAN);
+      checkInputExpressionDataType(
+          rightExpression.toString(), 
rightExpression.inferTypes(typeProvider), TSDataType.BOOLEAN);
+      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+    }
+    return TSDataType.BOOLEAN;
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
index ee0609ae16..eff1d56357 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicOrTransformer;
 
 import java.nio.ByteBuffer;
 
-public class LogicOrExpression extends BinaryExpression {
+public class LogicOrExpression extends LogicBinaryExpression {
 
   public LogicOrExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
index e43f23f3c5..39f4738aca 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticModuloTra
 
 import java.nio.ByteBuffer;
 
-public class ModuloExpression extends BinaryExpression {
+public class ModuloExpression extends ArithmeticBinaryExpression {
 
   public ModuloExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
index d5b15dc55d..6b72d5a2d2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticMultiplic
 
 import java.nio.ByteBuffer;
 
-public class MultiplicationExpression extends BinaryExpression {
+public class MultiplicationExpression extends ArithmeticBinaryExpression {
 
   public MultiplicationExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
index 6c9337fa57..542d4a7c25 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareNonEqualTran
 
 import java.nio.ByteBuffer;
 
-public class NonEqualExpression extends BinaryExpression {
+public class NonEqualExpression extends CompareBinaryExpression {
 
   public NonEqualExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
index 3e31ad9039..372d56cc73 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticSubtracti
 
 import java.nio.ByteBuffer;
 
-public class SubtractionExpression extends BinaryExpression {
+public class SubtractionExpression extends ArithmeticBinaryExpression {
 
   public SubtractionExpression(Expression leftExpression, Expression 
rightExpression) {
     super(leftExpression, rightExpression);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
index d92c8021c3..7acd877fc0 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.query.expression.leaf;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -91,6 +92,12 @@ public class ConstantOperand extends LeafOperand {
     // Do nothing
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    typeProvider.setType(toString(), dataType);
+    return dataType;
+  }
+
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     // Do nothing
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
index 11a6b72912..5d896a932f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -87,6 +88,11 @@ public class TimeSeriesOperand extends LeafOperand {
     pathSet.add(path);
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    return typeProvider.getType(toString());
+  }
+
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
@@ -125,6 +131,7 @@ public class TimeSeriesOperand extends LeafOperand {
     return expressionIntermediateLayerMap.get(this);
   }
 
+  @Override
   public String getExpressionStringInternal() {
     return path.isMeasurementAliasExists() ? path.getFullPathWithAlias() : 
path.getFullPath();
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
index 73c77a2b37..bb473451b7 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.db.query.expression.leaf;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -75,6 +76,12 @@ public class TimestampOperand extends LeafOperand {
     pathSet.add(TIMESTAMP_PARTIAL_PATH);
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    typeProvider.setType(toString(), TSDataType.INT64);
+    return TSDataType.INT64;
+  }
+
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     // do nothing
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
index b2bd93b05c..7fe3f1e14e 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
@@ -32,6 +33,7 @@ import 
org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.query.udf.api.customizer.strategy.AccessStrategy;
 import org.apache.iotdb.db.query.udf.core.executor.UDTFContext;
 import org.apache.iotdb.db.query.udf.core.executor.UDTFExecutor;
+import org.apache.iotdb.db.query.udf.core.executor.UDTFTypeInferrer;
 import org.apache.iotdb.db.query.udf.core.layer.IntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
 import 
org.apache.iotdb.db.query.udf.core.layer.MultiInputColumnIntermediateLayer;
@@ -238,6 +240,22 @@ public class FunctionExpression extends Expression {
     expressionName2Executor.put(expressionString, new UDTFExecutor(this, 
zoneId));
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    final String expressionString = toString();
+
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      for (Expression expression : expressions) {
+        expression.inferTypes(typeProvider);
+      }
+
+      typeProvider.setType(
+          expressionString, new 
UDTFTypeInferrer(this).inferOutputType(typeProvider));
+    }
+
+    return typeProvider.getType(expressionString);
+  }
+
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     for (Expression expression : expressions) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
index 9f329b3728..979d4c2bbc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
@@ -19,11 +19,13 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.db.query.udf.core.transformer.unary.InTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
@@ -59,6 +61,15 @@ public class InExpression extends UnaryExpression {
     return values;
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      typeProvider.setType(expressionString, 
expression.inferTypes(typeProvider));
+    }
+    return typeProvider.getType(expressionString);
+  }
+
   @Override
   protected String getExpressionStringInternal() {
     StringBuilder valuesStringBuilder = new StringBuilder();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
index 2d91ac0720..0e94037e72 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
@@ -19,11 +19,14 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.db.query.udf.core.transformer.unary.RegularTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
@@ -115,6 +118,17 @@ public class LikeExpression extends UnaryExpression {
     return stringBuilder.toString();
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) throws 
SemanticException {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      checkInputExpressionDataType(
+          expression.toString(), expression.inferTypes(typeProvider), 
TSDataType.TEXT);
+      typeProvider.setType(expressionString, TSDataType.TEXT);
+    }
+    return TSDataType.TEXT;
+  }
+
   @Override
   protected String getExpressionStringInternal() {
     return expression + " LIKE '" + pattern + "'";
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
index 2c22a52841..a538e4a028 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
@@ -27,6 +29,7 @@ import 
org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import 
org.apache.iotdb.db.query.udf.core.transformer.unary.LogicNotTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -50,6 +53,17 @@ public class LogicNotExpression extends UnaryExpression {
     return new LogicNotExpression(childExpression);
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) throws 
SemanticException {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      checkInputExpressionDataType(
+          expression.toString(), expression.inferTypes(typeProvider), 
TSDataType.BOOLEAN);
+      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+    }
+    return TSDataType.BOOLEAN;
+  }
+
   @Override
   public String getExpressionStringInternal() {
     return expression instanceof FunctionExpression
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
index 8e12a85a57..6d8c111078 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
@@ -27,6 +29,7 @@ import 
org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import 
org.apache.iotdb.db.query.udf.core.transformer.unary.ArithmeticNegationTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -50,6 +53,23 @@ public class NegationExpression extends UnaryExpression {
     return new NegationExpression(childExpression);
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) throws 
SemanticException {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      TSDataType inputExpressionType = expression.inferTypes(typeProvider);
+      checkInputExpressionDataType(
+          expression.toString(),
+          inputExpressionType,
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      typeProvider.setType(expressionString, inputExpressionType);
+    }
+    return typeProvider.getType(expressionString);
+  }
+
   @Override
   public String getExpressionStringInternal() {
     return expression instanceof TimeSeriesOperand
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
index f6027a9c8e..a8b30f0d5a 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
@@ -19,11 +19,14 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.db.query.udf.core.transformer.unary.RegularTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import org.apache.commons.lang3.Validate;
@@ -72,6 +75,17 @@ public class RegularExpression extends UnaryExpression {
     return new RegularExpression(childExpression, patternString, pattern);
   }
 
+  @Override
+  public TSDataType inferTypes(TypeProvider typeProvider) throws 
SemanticException {
+    final String expressionString = toString();
+    if (!typeProvider.containsTypeInfoOf(expressionString)) {
+      checkInputExpressionDataType(
+          expression.toString(), expression.inferTypes(typeProvider), 
TSDataType.TEXT);
+      typeProvider.setType(expressionString, TSDataType.TEXT);
+    }
+    return TSDataType.TEXT;
+  }
+
   @Override
   protected String getExpressionStringInternal() {
     return expression + " REGEXP '" + patternString + "'";
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
 
b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
index 5f057ccf8d..9b9b6640f0 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
@@ -22,6 +22,7 @@ package 
org.apache.iotdb.db.query.udf.api.customizer.parameter;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.udf.api.UDTF;
@@ -63,6 +64,17 @@ public class UDFParameters {
     }
   }
 
+  public UDFParameters(FunctionExpression functionExpression, TypeProvider 
typeProvider)
+      throws QueryProcessException {
+    expressions = functionExpression.getExpressions();
+    paths = functionExpression.getPaths();
+    attributes = functionExpression.getFunctionAttributes();
+    dataTypes = new ArrayList<>();
+    for (Expression expression : expressions) {
+      dataTypes.add(typeProvider.getType(expression.toString()));
+    }
+  }
+
   public List<Expression> getExpressions() {
     return expressions;
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
 
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
new file mode 100644
index 0000000000..ca7233906a
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.udf.core.executor;
+
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.query.udf.api.UDTF;
+import org.apache.iotdb.db.query.udf.api.customizer.config.UDTFConfigurations;
+import 
org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameterValidator;
+import org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameters;
+import org.apache.iotdb.db.query.udf.service.UDFRegistrationService;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.ZoneId;
+
+public class UDTFTypeInferrer {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(UDTFTypeInferrer.class);
+
+  protected final FunctionExpression expression;
+
+  public UDTFTypeInferrer(FunctionExpression expression) {
+    this.expression = expression;
+  }
+
+  public TSDataType inferOutputType(TypeProvider typeProvider) {
+    try {
+      UDTF udtf = (UDTF) 
UDFRegistrationService.getInstance().reflect(expression);
+
+      UDFParameters parameters = new UDFParameters(expression, typeProvider);
+      udtf.validate(new UDFParameterValidator(parameters));
+
+      // use ZoneId.systemDefault() because UDF's data type is ZoneId 
independent
+      UDTFConfigurations configurations = new 
UDTFConfigurations(ZoneId.systemDefault());
+      udtf.beforeStart(parameters, configurations);
+
+      udtf.beforeDestroy();
+
+      return configurations.getOutputDataType();
+    } catch (Exception e) {
+      LOGGER.warn("Error occurred during inferring UDF data type", e);
+      throw new SemanticException(
+          String.format("Error occurred during inferring UDF data type: %s", 
System.lineSeparator())
+              + e);
+    }
+  }
+}

Reply via email to