You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2022/05/13 09:47:31 UTC

[iotdb] branch iotdb-3145 created (now 2f0128e29f)

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

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


      at 2f0128e29f support comparing BOOLEAN and TEXT

This branch includes the following new commits:

     new 79bf5434ef support type inferring
     new 2f0128e29f support comparing BOOLEAN and TEXT

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[iotdb] 02/02: support comparing BOOLEAN and TEXT

Posted by ro...@apache.org.
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 2f0128e29f75f33f560337a1f003cdaaf0ffb1ce
Author: Steve Yurong Su <ro...@apache.org>
AuthorDate: Fri May 13 17:47:10 2022 +0800

    support comparing BOOLEAN and TEXT
---
 .../binary/ArithmeticBinaryTransformer.java        |  9 ++--
 .../binary/CompareBinaryTransformer.java           | 60 ++++++++++++++++++----
 .../binary/CompareEqualToTransformer.java          | 27 +++++-----
 .../binary/CompareGreaterEqualTransformer.java     | 17 +++++-
 .../binary/CompareGreaterThanTransformer.java      | 17 +++++-
 .../binary/CompareLessEqualTransformer.java        | 17 +++++-
 .../binary/CompareLessThanTransformer.java         | 17 +++++-
 .../binary/CompareNonEqualTransformer.java         | 26 +++++-----
 .../transformer/binary/LogicBinaryTransformer.java | 10 ++--
 9 files changed, 141 insertions(+), 59 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
index 29a17a1ee1..751fc534d6 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
@@ -35,11 +35,12 @@ public abstract class ArithmeticBinaryTransformer extends BinaryTransformer {
 
   @Override
   protected void checkType() {
-    if (leftPointReaderDataType == TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(leftPointReader.getDataType().toString());
+    if (leftPointReaderDataType == TSDataType.BOOLEAN
+        || rightPointReaderDataType == TSDataType.BOOLEAN) {
+      throw new UnSupportedDataTypeException(TSDataType.BOOLEAN.name());
     }
-    if (rightPointReaderDataType == TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(rightPointReader.getDataType().toString());
+    if (leftPointReaderDataType == TSDataType.TEXT || rightPointReaderDataType == TSDataType.TEXT) {
+      throw new UnSupportedDataTypeException(TSDataType.TEXT.name());
     }
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
index 90f506ddd7..42b42e1058 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
@@ -25,35 +25,73 @@ import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.IOException;
+import java.util.Objects;
 
 public abstract class CompareBinaryTransformer extends BinaryTransformer {
 
+  @FunctionalInterface
+  protected interface Evaluator {
+
+    boolean evaluate() throws QueryProcessException, IOException;
+  }
+
+  protected final Evaluator evaluator;
+
   protected CompareBinaryTransformer(
       LayerPointReader leftPointReader, LayerPointReader rightPointReader)
       throws UnSupportedDataTypeException {
     super(leftPointReader, rightPointReader);
+    evaluator =
+        TSDataType.TEXT.equals(leftPointReaderDataType)
+            ? constructTextEvaluator()
+            : constructNumberEvaluator();
+  }
+
+  protected abstract Evaluator constructNumberEvaluator();
+
+  protected abstract Evaluator constructTextEvaluator();
+
+  protected static int compare(CharSequence cs1, CharSequence cs2) {
+    if (Objects.requireNonNull(cs1) == Objects.requireNonNull(cs2)) {
+      return 0;
+    }
+
+    if (cs1.getClass() == cs2.getClass() && cs1 instanceof Comparable) {
+      return ((Comparable<Object>) cs1).compareTo(cs2);
+    }
+
+    for (int i = 0, len = Math.min(cs1.length(), cs2.length()); i < len; i++) {
+      char a = cs1.charAt(i);
+      char b = cs2.charAt(i);
+      if (a != b) {
+        return a - b;
+      }
+    }
+
+    return cs1.length() - cs2.length();
   }
 
   @Override
-  protected void checkType() {
-    if (leftPointReaderDataType == TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(leftPointReader.getDataType().toString());
+  protected final void checkType() {
+    if (leftPointReaderDataType.equals(rightPointReaderDataType)) {
+      return;
+    }
+
+    if (leftPointReaderDataType.equals(TSDataType.BOOLEAN)
+        || rightPointReaderDataType.equals(TSDataType.BOOLEAN)) {
+      throw new UnSupportedDataTypeException(TSDataType.BOOLEAN.toString());
     }
-    if (rightPointReaderDataType == TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(rightPointReader.getDataType().toString());
+    if (leftPointReaderDataType.equals(TSDataType.TEXT)
+        || rightPointReaderDataType.equals(TSDataType.TEXT)) {
+      throw new UnSupportedDataTypeException(TSDataType.TEXT.toString());
     }
   }
 
   @Override
   protected final void transformAndCache() throws QueryProcessException, IOException {
-    cachedBoolean =
-        evaluate(
-            castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
-            castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType));
+    cachedBoolean = evaluator.evaluate();
   }
 
-  abstract boolean evaluate(double leftOperand, double rightOperand);
-
   @Override
   public TSDataType getDataType() {
     return TSDataType.BOOLEAN;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
index 8484df276c..af6b2c8d65 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
@@ -20,8 +20,6 @@
 package org.apache.iotdb.db.query.udf.core.transformer.binary;
 
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
-import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 public class CompareEqualToTransformer extends CompareBinaryTransformer {
 
@@ -31,21 +29,20 @@ public class CompareEqualToTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected void checkType() {
-    if ((leftPointReaderDataType == TSDataType.BOOLEAN
-            && rightPointReaderDataType != TSDataType.BOOLEAN)
-        || (leftPointReaderDataType != TSDataType.BOOLEAN
-            && rightPointReaderDataType == TSDataType.BOOLEAN)) {
-      throw new UnSupportedDataTypeException(
-          "left: "
-              + leftPointReaderDataType.toString()
-              + ", right: "
-              + rightPointReaderDataType.toString());
-    }
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            == 0;
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) == 0;
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            == 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
index 7854143cff..1e98bfe423 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
@@ -29,7 +29,20 @@ public class CompareGreaterEqualTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) >= 0;
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            >= 0;
+  }
+
+  @Override
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            >= 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
index 627c4b17bf..9e7a5ea3ba 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
@@ -29,7 +29,20 @@ public class CompareGreaterThanTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) > 0;
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            > 0;
+  }
+
+  @Override
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            > 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
index 2b00dca3fb..0c53e86949 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
@@ -29,7 +29,20 @@ public class CompareLessEqualTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) <= 0;
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            <= 0;
+  }
+
+  @Override
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            <= 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
index ea2ebeded5..9e77e2aa21 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
@@ -29,7 +29,20 @@ public class CompareLessThanTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) < 0;
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            < 0;
+  }
+
+  @Override
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            < 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
index 795b011bdc..024c54deb5 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
@@ -21,7 +21,6 @@ package org.apache.iotdb.db.query.udf.core.transformer.binary;
 
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 public class CompareNonEqualTransformer extends CompareBinaryTransformer {
 
@@ -32,21 +31,20 @@ public class CompareNonEqualTransformer extends CompareBinaryTransformer {
   }
 
   @Override
-  protected void checkType() {
-    if ((leftPointReaderDataType == TSDataType.BOOLEAN
-            && rightPointReaderDataType != TSDataType.BOOLEAN)
-        || (leftPointReaderDataType != TSDataType.BOOLEAN
-            && rightPointReaderDataType == TSDataType.BOOLEAN)) {
-      throw new UnSupportedDataTypeException(
-          "left: "
-              + leftPointReaderDataType.toString()
-              + ", right: "
-              + rightPointReaderDataType.toString());
-    }
+  protected Evaluator constructNumberEvaluator() {
+    return () ->
+        Double.compare(
+                castCurrentValueToDoubleOperand(leftPointReader, leftPointReaderDataType),
+                castCurrentValueToDoubleOperand(rightPointReader, rightPointReaderDataType))
+            != 0;
   }
 
   @Override
-  protected boolean evaluate(double leftOperand, double rightOperand) {
-    return Double.compare(leftOperand, rightOperand) != 0;
+  protected Evaluator constructTextEvaluator() {
+    return () ->
+        compare(
+                leftPointReader.currentBinary().getStringValue(),
+                rightPointReader.currentBinary().getStringValue())
+            != 0;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
index d8e1a36012..7eee752775 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
@@ -35,13 +35,9 @@ public abstract class LogicBinaryTransformer extends BinaryTransformer {
 
   @Override
   protected void checkType() {
-    if (leftPointReaderDataType != TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(
-          "Unsupported data type: " + leftPointReader.getDataType().toString());
-    }
-    if (rightPointReaderDataType != TSDataType.BOOLEAN) {
-      throw new UnSupportedDataTypeException(
-          "Unsupported data type: " + rightPointReader.getDataType().toString());
+    if (leftPointReaderDataType != TSDataType.BOOLEAN
+        || rightPointReaderDataType != TSDataType.BOOLEAN) {
+      throw new UnSupportedDataTypeException("Unsupported data type: " + TSDataType.BOOLEAN);
     }
   }
 


[iotdb] 01/02: support type inferring

Posted by ro...@apache.org.
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 <ro...@apache.org>
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);
+    }
+  }
+}