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/04/28 05:48:29 UTC

[iotdb] branch master updated: [IOTDB-2933] Implement expression classes for IN, LIKE, and REGEXP expressions (#5706)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new ca4f3cfc81 [IOTDB-2933] Implement expression classes for IN, LIKE, and REGEXP expressions (#5706)
ca4f3cfc81 is described below

commit ca4f3cfc81b7f3923a192b776094f34d7ec0d964
Author: Steve Yurong Su <ro...@apache.org>
AuthorDate: Thu Apr 28 13:48:23 2022 +0800

    [IOTDB-2933] Implement expression classes for IN, LIKE, and REGEXP expressions (#5706)
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |   2 +-
 .../query/ClusterPhysicalGeneratorTest.java        |   2 +-
 .../iotdb/db/integration/IoTDBSelectSchemaIT.java  |   7 +-
 .../apache/iotdb/db/mpp/sql/parser/ASTVisitor.java |  36 +++--
 .../db/mpp/sql/parser/StatementGenerator.java      |   2 +-
 .../db/mpp/sql/rewriter/ConcatPathRewriter.java    |   2 +-
 .../db/mpp/sql/rewriter/WildcardsRemover.java      |   2 +-
 .../component/GroupByLevelController.java          |   2 +-
 .../mpp/sql/statement/component/ResultColumn.java  |   2 +-
 .../sql/statement/component/SelectComponent.java   |   4 +-
 .../statement/crud/AggregationQueryStatement.java  |   4 +-
 .../mpp/sql/statement/crud/LastQueryStatement.java |   2 +-
 .../db/mpp/sql/statement/crud/QueryStatement.java  |   4 +-
 .../mpp/sql/statement/crud/UDAFQueryStatement.java |   2 +-
 .../protocol/influxdb/function/InfluxFunction.java |   2 +-
 .../db/protocol/influxdb/handler/QueryHandler.java |   4 +-
 .../influxdb/operator/InfluxSelectComponent.java   |   4 +-
 .../protocol/influxdb/sql/InfluxDBSqlVisitor.java  |   4 +-
 .../qp/logical/crud/AggregationQueryOperator.java  |   4 +-
 .../db/qp/logical/crud/LastQueryOperator.java      |   2 +-
 .../iotdb/db/qp/logical/crud/QueryOperator.java    |   4 +-
 .../iotdb/db/qp/logical/crud/SelectComponent.java  |   4 +-
 .../db/qp/logical/crud/UDAFQueryOperator.java      |   4 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  37 +++--
 .../iotdb/db/qp/strategy/LogicalGenerator.java     |   2 +-
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |   2 +-
 .../iotdb/db/qp/utils/GroupByLevelController.java  |   2 +-
 .../iotdb/db/query/expression/Expression.java      |  70 +++++----
 .../{unary => leaf}/ConstantOperand.java           |  18 +--
 .../db/query/expression/leaf/LeafOperand.java      |  42 ++++++
 .../{unary => leaf}/TimeSeriesOperand.java         |  18 +--
 .../{unary => multi}/FunctionExpression.java       |   6 +-
 .../db/query/expression/unary/InExpression.java    |  86 +++++++++++
 .../db/query/expression/unary/LikeExpression.java  |  69 +++++++++
 .../query/expression/unary/LogicNotExpression.java | 167 ++-------------------
 .../query/expression/unary/NegationExpression.java | 167 ++-------------------
 .../query/expression/unary/RegularExpression.java  | 131 ++--------------
 ...ogicNotExpression.java => UnaryExpression.java} | 129 +++++++---------
 .../api/customizer/parameter/UDFParameters.java    |   2 +-
 .../db/query/udf/core/executor/UDTFContext.java    |   2 +-
 .../db/query/udf/core/executor/UDTFExecutor.java   |   2 +-
 .../udf/core/layer/ConstantIntermediateLayer.java  |   2 +-
 .../query/udf/core/layer/LayerMemoryAssigner.java  |   2 +-
 .../udf/core/reader/ConstantLayerPointReader.java  |   2 +-
 .../query/udf/service/UDFRegistrationService.java  |   2 +-
 .../influxdb/sql/InfluxDBLogicalGeneratorTest.java |   2 +-
 46 files changed, 433 insertions(+), 634 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index e5f1ea3e62..04ff27d438 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -848,7 +848,7 @@ expression
     | leftExpression=expression (STAR | DIV | MOD) rightExpression=expression
     | leftExpression=expression (PLUS | MINUS) rightExpression=expression
     | leftExpression=expression (OPERATOR_GT | OPERATOR_GTE | OPERATOR_LT | OPERATOR_LTE | OPERATOR_DEQ | OPERATOR_NEQ) rightExpression=expression
-    | unaryBeforeRegularExpression=expression (REGEXP | LIKE) STRING_LITERAL
+    | unaryBeforeRegularOrLikeExpression=expression (REGEXP | LIKE) STRING_LITERAL
     | unaryBeforeInExpression=expression OPERATOR_IN LR_BRACKET constant (COMMA constant)* RR_BRACKET
     | leftExpression=expression OPERATOR_AND rightExpression=expression
     | leftExpression=expression OPERATOR_OR rightExpression=expression
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
index fcea0516c2..e9de8b6778 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
@@ -28,7 +28,7 @@ import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectSchemaIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectSchemaIT.java
index efbcf2db3e..a4920d6d96 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectSchemaIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSelectSchemaIT.java
@@ -87,6 +87,7 @@ public class IoTDBSelectSchemaIT {
       "!true||s1>0",
       "-(-1)+s1",
       "sin(s1)+s1",
+      "((s1+1)*2-1)%2+1.5+s2"
     };
     String[] completeExpressions = {
       "root.sg.d1.s1+root.sg.d1.s2",
@@ -99,13 +100,14 @@ public class IoTDBSelectSchemaIT {
       "!true|root.sg.d1.s1>0",
       "-(-1)+root.sg.d1.s1",
       "sin(root.sg.d1.s1)+root.sg.d1.s1",
+      "((root.sg.d1.s1+1)*2-1)%2+1.5+root.sg.d1.s2",
     };
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
       ResultSet resultSet =
           statement.executeQuery(
               String.format(
-                  "select %s, %s, %s, %s, %s, %s, %s, %s, %s, %s from root.sg.d1",
+                  "select %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s from root.sg.d1",
                   expressions[0],
                   expressions[1],
                   expressions[2],
@@ -115,7 +117,8 @@ public class IoTDBSelectSchemaIT {
                   expressions[6],
                   expressions[7],
                   expressions[8],
-                  expressions[9]));
+                  expressions[9],
+                  expressions[10]));
       int columnCount = resultSet.getMetaData().getColumnCount();
       assertEquals(1 + expressions.length, columnCount);
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/ASTVisitor.java
index 57d1066391..886aa67f3c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/ASTVisitor.java
@@ -96,11 +96,12 @@ import org.apache.iotdb.db.query.expression.binary.ModuloExpression;
 import org.apache.iotdb.db.query.expression.binary.MultiplicationExpression;
 import org.apache.iotdb.db.query.expression.binary.NonEqualExpression;
 import org.apache.iotdb.db.query.expression.binary.SubtractionExpression;
-import org.apache.iotdb.db.query.expression.unary.ConstantOperand;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.expression.unary.LogicNotExpression;
 import org.apache.iotdb.db.query.expression.unary.NegationExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.unary.RegularExpression;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -1683,6 +1684,10 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
       return new TimeSeriesOperand(parseSuffixPathCanInExpr(context.suffixPathCanInExpr()));
     }
 
+    if (context.functionName() != null) {
+      return parseFunctionExpression(context);
+    }
+
     if (context.expressionAfterUnaryOperator != null) {
       if (context.MINUS() != null) {
         return new NegationExpression(parseExpression(context.expressionAfterUnaryOperator));
@@ -1735,14 +1740,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
       if (context.OPERATOR_OR() != null) {
         return new LogicOrExpression(leftExpression, rightExpression);
       }
+      throw new UnsupportedOperationException();
     }
 
-    if (context.functionName() != null) {
-      return parseFunctionExpression(context);
-    }
-
-    if (context.unaryBeforeRegularExpression != null) {
-      return parseRegularExpression(context);
+    if (context.unaryBeforeRegularOrLikeExpression != null) {
+      if (context.REGEXP() != null) {
+        return parseRegularExpression(context);
+      }
+      if (context.LIKE() != null) {
+        return parseLikeExpression(context);
+      }
+      throw new UnsupportedOperationException();
     }
 
     if (context.unaryBeforeInExpression != null) {
@@ -1786,11 +1794,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
   }
 
   private Expression parseRegularExpression(ExpressionContext context) {
-    return null;
+    return new RegularExpression(
+        parseExpression(context.unaryBeforeRegularOrLikeExpression),
+        parseStringLiteral(context.STRING_LITERAL().getText()));
+  }
+
+  private Expression parseLikeExpression(ExpressionContext context) {
+    throw new UnsupportedOperationException();
   }
 
   private Expression parseInExpression(ExpressionContext context) {
-    return null;
+    throw new UnsupportedOperationException();
   }
 
   private Expression parseConstantOperand(ConstantContext constantContext) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/StatementGenerator.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/StatementGenerator.java
index f17ee77c77..5545e169e7 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/StatementGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/parser/StatementGenerator.java
@@ -42,7 +42,7 @@ import org.apache.iotdb.db.mpp.sql.statement.metadata.CreateTimeSeriesStatement;
 import org.apache.iotdb.db.qp.sql.IoTDBSqlParser;
 import org.apache.iotdb.db.qp.sql.SqlLexer;
 import org.apache.iotdb.db.qp.strategy.SQLParseError;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.utils.QueryDataSetUtils;
 import org.apache.iotdb.service.rpc.thrift.TSCreateTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSInsertRecordReq;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/ConcatPathRewriter.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/ConcatPathRewriter.java
index 1ff1934f30..b55232cc15 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/ConcatPathRewriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/ConcatPathRewriter.java
@@ -31,7 +31,7 @@ import org.apache.iotdb.db.mpp.sql.statement.component.ResultColumn;
 import org.apache.iotdb.db.mpp.sql.statement.crud.QueryStatement;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/WildcardsRemover.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/WildcardsRemover.java
index 1dc0b459d8..1391502c2c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/WildcardsRemover.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/rewriter/WildcardsRemover.java
@@ -42,7 +42,7 @@ import org.apache.iotdb.db.mpp.sql.statement.crud.LastQueryStatement;
 import org.apache.iotdb.db.mpp.sql.statement.crud.QueryStatement;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.tsfile.utils.Pair;
 
 import java.util.ArrayList;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/GroupByLevelController.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/GroupByLevelController.java
index 9ba8bd2ece..885960f097 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/GroupByLevelController.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/GroupByLevelController.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.statement.crud.AggregationQueryStatement;
 import org.apache.iotdb.db.mpp.sql.statement.crud.QueryStatement;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/ResultColumn.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/ResultColumn.java
index a9cbcf0edd..d2e9361476 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/ResultColumn.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/ResultColumn.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
 import org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover;
 import org.apache.iotdb.db.mpp.sql.statement.StatementNode;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.util.ArrayList;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/SelectComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/SelectComponent.java
index 450abaae92..9aa2f1af8f 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/SelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/SelectComponent.java
@@ -22,8 +22,8 @@ package org.apache.iotdb.db.mpp.sql.statement.component;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.statement.StatementNode;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.tsfile.read.common.Path;
 
 import java.time.ZoneId;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
index a2336183e7..0e9f408636 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
@@ -29,8 +29,8 @@ import org.apache.iotdb.db.mpp.sql.statement.component.ResultColumn;
 import org.apache.iotdb.db.mpp.sql.statement.component.SelectComponent;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
index 2cf8235889..b62b8f296d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
@@ -25,7 +25,7 @@ import org.apache.iotdb.db.mpp.common.header.DatasetHeader;
 import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
 import org.apache.iotdb.db.mpp.sql.statement.component.ResultColumn;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
index df7b89b680..b7626d1c07 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
@@ -38,8 +38,8 @@ import org.apache.iotdb.db.mpp.sql.statement.component.WhereCondition;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.physical.crud.MeasurementInfo;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.util.ArrayList;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
index 555e15eeec..c8a31f588b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
@@ -24,7 +24,7 @@ import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
 import org.apache.iotdb.db.mpp.sql.statement.component.ResultColumn;
 import org.apache.iotdb.db.mpp.sql.statement.component.SelectComponent;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import java.util.List;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/function/InfluxFunction.java b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/function/InfluxFunction.java
index f6873781a8..3c800af525 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/function/InfluxFunction.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/function/InfluxFunction.java
@@ -19,7 +19,7 @@
 package org.apache.iotdb.db.protocol.influxdb.function;
 
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import java.util.List;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/handler/QueryHandler.java b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/handler/QueryHandler.java
index 69c9ca4970..b6f1a29b55 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/handler/QueryHandler.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/handler/QueryHandler.java
@@ -48,8 +48,8 @@ import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.SessionManager;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.service.basic.ServiceProvider;
 import org.apache.iotdb.protocol.influxdb.rpc.thrift.InfluxQueryResultRsp;
 import org.apache.iotdb.rpc.RpcUtils;
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/operator/InfluxSelectComponent.java b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/operator/InfluxSelectComponent.java
index b5b9113d21..05e5c39fec 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/operator/InfluxSelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/operator/InfluxSelectComponent.java
@@ -21,8 +21,8 @@ package org.apache.iotdb.db.protocol.influxdb.operator;
 import org.apache.iotdb.db.protocol.influxdb.constant.InfluxSQLConstant;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 
 import java.time.ZoneId;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBSqlVisitor.java b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBSqlVisitor.java
index 9e13b9017f..551d12f72c 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBSqlVisitor.java
@@ -38,9 +38,9 @@ import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
 import org.apache.iotdb.db.query.expression.binary.ModuloExpression;
 import org.apache.iotdb.db.query.expression.binary.MultiplicationExpression;
 import org.apache.iotdb.db.query.expression.binary.SubtractionExpression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.expression.unary.NegationExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
 
 public class InfluxDBSqlVisitor extends InfluxDBSqlParserBaseVisitor<Operator> {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
index 11a4202b51..f893e1e2f2 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
@@ -31,8 +31,8 @@ import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.utils.SchemaUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
index e78c75a377..63eddbe346 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
@@ -26,7 +26,7 @@ import org.apache.iotdb.db.qp.physical.crud.LastQueryPlan;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 public class LastQueryOperator extends QueryOperator {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index a11bfa9b73..54bad1c445 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@ -36,8 +36,8 @@ import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
index d4b3c8ed03..fa7c3c5d55 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
@@ -22,8 +22,8 @@ package org.apache.iotdb.db.qp.logical.crud;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 
 import java.time.ZoneId;
 import java.util.ArrayList;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
index 7c0fdab32e..fd9888f36e 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
@@ -26,8 +26,8 @@ import org.apache.iotdb.db.qp.physical.crud.UDAFPlan;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index c384720ed8..35cddefc22 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -142,11 +142,12 @@ import org.apache.iotdb.db.query.expression.binary.ModuloExpression;
 import org.apache.iotdb.db.query.expression.binary.MultiplicationExpression;
 import org.apache.iotdb.db.query.expression.binary.NonEqualExpression;
 import org.apache.iotdb.db.query.expression.binary.SubtractionExpression;
-import org.apache.iotdb.db.query.expression.unary.ConstantOperand;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.expression.unary.LogicNotExpression;
 import org.apache.iotdb.db.query.expression.unary.NegationExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.unary.RegularExpression;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -2506,7 +2507,6 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
     }
   }
 
-  @SuppressWarnings("squid:S3776")
   private Expression parseExpression(IoTDBSqlParser.ExpressionContext context) {
     if (context.unaryInBracket != null) {
       return parseExpression(context.unaryInBracket);
@@ -2524,6 +2524,10 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
       return new TimeSeriesOperand(parseSuffixPathCanInExpr(context.suffixPathCanInExpr()));
     }
 
+    if (context.functionName() != null) {
+      return parseFunctionExpression(context);
+    }
+
     if (context.expressionAfterUnaryOperator != null) {
       if (context.MINUS() != null) {
         return new NegationExpression(parseExpression(context.expressionAfterUnaryOperator));
@@ -2576,14 +2580,17 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
       if (context.OPERATOR_OR() != null) {
         return new LogicOrExpression(leftExpression, rightExpression);
       }
+      throw new UnsupportedOperationException();
     }
 
-    if (context.functionName() != null) {
-      return parseFunctionExpression(context);
-    }
-
-    if (context.unaryBeforeRegularExpression != null) {
-      return parseRegularExpression(context);
+    if (context.unaryBeforeRegularOrLikeExpression != null) {
+      if (context.REGEXP() != null) {
+        return parseRegularExpression(context);
+      }
+      if (context.LIKE() != null) {
+        return parseLikeExpression(context);
+      }
+      throw new UnsupportedOperationException();
     }
 
     if (context.unaryBeforeInExpression != null) {
@@ -2627,11 +2634,17 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
   }
 
   private Expression parseRegularExpression(ExpressionContext context) {
-    return null;
+    return new RegularExpression(
+        parseExpression(context.unaryBeforeRegularOrLikeExpression),
+        parseStringLiteral(context.STRING_LITERAL().getText()));
+  }
+
+  private Expression parseLikeExpression(ExpressionContext context) {
+    throw new UnsupportedOperationException();
   }
 
   private Expression parseInExpression(ExpressionContext context) {
-    return null;
+    throw new UnsupportedOperationException();
   }
 
   private Expression parseConstantOperand(ConstantContext constantContext) {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
index a99c97e65c..4fafeaa963 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
@@ -35,7 +35,7 @@ import org.apache.iotdb.db.qp.sql.IoTDBSqlParser;
 import org.apache.iotdb.db.qp.sql.IoTDBSqlVisitor;
 import org.apache.iotdb.db.qp.sql.SqlLexer;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.service.rpc.thrift.TSLastDataQueryReq;
 import org.apache.iotdb.service.rpc.thrift.TSRawDataQueryReq;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index 383618fd73..242af84df0 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@ -43,7 +43,7 @@ import org.apache.iotdb.db.qp.utils.GroupByLevelController;
 import org.apache.iotdb.db.qp.utils.WildcardsRemover;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.service.IoTDB;
 
 import org.slf4j.Logger;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java b/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
index b536a57b61..224cf00fb2 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
@@ -25,7 +25,7 @@ import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
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 b79c145b62..a98cd7f5bc 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
@@ -39,12 +39,14 @@ import org.apache.iotdb.db.query.expression.binary.ModuloExpression;
 import org.apache.iotdb.db.query.expression.binary.MultiplicationExpression;
 import org.apache.iotdb.db.query.expression.binary.NonEqualExpression;
 import org.apache.iotdb.db.query.expression.binary.SubtractionExpression;
-import org.apache.iotdb.db.query.expression.unary.ConstantOperand;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.query.expression.unary.InExpression;
+import org.apache.iotdb.db.query.expression.unary.LikeExpression;
 import org.apache.iotdb.db.query.expression.unary.LogicNotExpression;
 import org.apache.iotdb.db.query.expression.unary.NegationExpression;
 import org.apache.iotdb.db.query.expression.unary.RegularExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
 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.layer.IntermediateLayer;
@@ -236,66 +238,80 @@ public abstract class Expression {
 
     Expression expression;
     switch (type) {
+      case -4:
+        expression = new ConstantOperand(byteBuffer);
+        break;
+      case -3:
+        throw new UnsupportedOperationException();
+      case -2:
+        expression = new TimeSeriesOperand(byteBuffer);
+        break;
+      case -1:
+        expression = new FunctionExpression(byteBuffer);
+        break;
+
       case 0:
-        expression = new AdditionExpression(byteBuffer);
+        expression = new NegationExpression(byteBuffer);
         break;
       case 1:
-        expression = new DivisionExpression(byteBuffer);
+        expression = new LogicNotExpression(byteBuffer);
         break;
+
       case 2:
-        expression = new EqualToExpression(byteBuffer);
+        expression = new MultiplicationExpression(byteBuffer);
         break;
       case 3:
-        expression = new GreaterEqualExpression(byteBuffer);
+        expression = new DivisionExpression(byteBuffer);
         break;
       case 4:
-        expression = new GreaterThanExpression(byteBuffer);
+        expression = new ModuloExpression(byteBuffer);
         break;
+
       case 5:
-        expression = new LessEqualExpression(byteBuffer);
+        expression = new AdditionExpression(byteBuffer);
         break;
       case 6:
-        expression = new LessThanExpression(byteBuffer);
+        expression = new SubtractionExpression(byteBuffer);
         break;
+
       case 7:
-        expression = new LogicAndExpression(byteBuffer);
+        expression = new EqualToExpression(byteBuffer);
         break;
       case 8:
-        expression = new LogicOrExpression(byteBuffer);
+        expression = new NonEqualExpression(byteBuffer);
         break;
       case 9:
-        expression = new ModuloExpression(byteBuffer);
+        expression = new GreaterEqualExpression(byteBuffer);
         break;
       case 10:
-        expression = new MultiplicationExpression(byteBuffer);
+        expression = new GreaterThanExpression(byteBuffer);
         break;
       case 11:
-        expression = new NonEqualExpression(byteBuffer);
+        expression = new LessEqualExpression(byteBuffer);
         break;
       case 12:
-        expression = new SubtractionExpression(byteBuffer);
+        expression = new LessThanExpression(byteBuffer);
         break;
+
       case 13:
-        expression = new FunctionExpression(byteBuffer);
+        expression = new LikeExpression(byteBuffer);
         break;
       case 14:
-        expression = new LogicNotExpression(byteBuffer);
+        expression = new RegularExpression(byteBuffer);
         break;
+
       case 15:
-        expression = new NegationExpression(byteBuffer);
+        expression = new InExpression(byteBuffer);
         break;
+
       case 16:
-        expression = new TimeSeriesOperand(byteBuffer);
+        expression = new LogicAndExpression(byteBuffer);
         break;
+
       case 17:
-        expression = new ConstantOperand(byteBuffer);
-        break;
-      case 18:
-        expression = null;
-        break;
-      case 19:
-        expression = new RegularExpression(byteBuffer);
+        expression = new LogicOrExpression(byteBuffer);
         break;
+
       default:
         throw new IllegalArgumentException("Invalid expression type: " + type);
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/ConstantOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
similarity index 90%
rename from server/src/main/java/org/apache/iotdb/db/query/expression/unary/ConstantOperand.java
rename to server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
index b50c3c06f9..2e57869a94 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/ConstantOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.query.expression.unary;
+package org.apache.iotdb.db.query.expression.leaf;
 
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.path.PartialPath;
@@ -27,7 +27,6 @@ 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;
 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.layer.ConstantIntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.layer.IntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
@@ -38,14 +37,12 @@ import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.commons.lang3.Validate;
 
 import java.nio.ByteBuffer;
-import java.time.ZoneId;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /** Constant operand */
-public class ConstantOperand extends Expression {
+public class ConstantOperand extends LeafOperand {
 
   private final String valueString;
   private final TSDataType dataType;
@@ -106,17 +103,6 @@ public class ConstantOperand extends Expression {
     // Do nothing
   }
 
-  @Override
-  public List<Expression> getExpressions() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public void constructUdfExecutors(
-      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
-    // Do nothing
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     // Do nothing
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/LeafOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/LeafOperand.java
new file mode 100644
index 0000000000..500ae89520
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/LeafOperand.java
@@ -0,0 +1,42 @@
+/*
+ * 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.leaf;
+
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.db.query.udf.core.executor.UDTFExecutor;
+
+import java.time.ZoneId;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public abstract class LeafOperand extends Expression {
+
+  @Override
+  public final List<Expression> getExpressions() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public final void constructUdfExecutors(
+      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
+    // nothing to do
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
similarity index 92%
rename from server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
rename to server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
index ea83b01c32..0fcf4ab170 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.query.expression.unary;
+package org.apache.iotdb.db.query.expression.leaf;
 
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
@@ -30,7 +30,6 @@ 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;
 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.layer.IntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
 import org.apache.iotdb.db.query.udf.core.layer.RawQueryInputLayer;
@@ -40,13 +39,11 @@ import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
-import java.time.ZoneId;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-public class TimeSeriesOperand extends Expression {
+public class TimeSeriesOperand extends LeafOperand {
 
   private PartialPath path;
 
@@ -71,11 +68,6 @@ public class TimeSeriesOperand extends Expression {
     return false;
   }
 
-  @Override
-  public List<Expression> getExpressions() {
-    return Collections.emptyList();
-  }
-
   @Override
   public void concat(
       List<PartialPath> prefixPaths,
@@ -118,12 +110,6 @@ public class TimeSeriesOperand extends Expression {
     pathSet.add(path);
   }
 
-  @Override
-  public void constructUdfExecutors(
-      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
-    // nothing to do
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
similarity index 99%
rename from server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java
rename to server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
index 892ef2e1ec..972260083d 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.query.expression.unary;
+package org.apache.iotdb.db.query.expression.multi;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
@@ -25,13 +25,13 @@ import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
-import org.apache.iotdb.db.mpp.sql.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover;
 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;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
+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;
@@ -81,8 +81,6 @@ public class FunctionExpression extends Expression {
    */
   private List<Expression> expressions;
 
-  private List<InputLocation> inputLocations;
-
   private List<PartialPath> paths;
 
   private String parametersString;
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
new file mode 100644
index 0000000000..a5a5b97111
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
@@ -0,0 +1,86 @@
+/*
+ * 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.unary;
+
+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.tsfile.utils.ReadWriteIOUtils;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+public class InExpression extends UnaryExpression {
+
+  private final LinkedHashSet<String> values;
+
+  protected InExpression(Expression expression, LinkedHashSet<String> values) {
+    super(expression);
+    this.values = values;
+  }
+
+  public InExpression(ByteBuffer byteBuffer) {
+    super(Expression.deserialize(byteBuffer));
+    final int size = ReadWriteIOUtils.readInt(byteBuffer);
+    values = new LinkedHashSet<>();
+    for (int i = 0; i < size; ++i) {
+      values.add(ReadWriteIOUtils.readString(byteBuffer));
+    }
+  }
+
+  @Override
+  protected String getExpressionStringInternal() {
+    StringBuilder valuesStringBuilder = new StringBuilder();
+    Iterator<String> iterator = values.iterator();
+    if (iterator.hasNext()) {
+      valuesStringBuilder.append(iterator.next());
+    }
+    while (iterator.hasNext()) {
+      valuesStringBuilder.append(", ").append(iterator.next());
+    }
+    return expression + " IN (" + valuesStringBuilder + ")";
+  }
+
+  @Override
+  public ExpressionType getExpressionType() {
+    return ExpressionType.IN;
+  }
+
+  @Override
+  protected Transformer constructTransformer(LayerPointReader pointReader) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  protected Expression constructExpression(Expression childExpression) {
+    return new InExpression(childExpression, values);
+  }
+
+  @Override
+  protected void serialize(ByteBuffer byteBuffer) {
+    super.serialize(byteBuffer);
+    ReadWriteIOUtils.write(values.size(), byteBuffer);
+    for (String value : values) {
+      ReadWriteIOUtils.write(value, byteBuffer);
+    }
+  }
+}
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
new file mode 100644
index 0000000000..a023ad3cfc
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
@@ -0,0 +1,69 @@
+/*
+ * 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.unary;
+
+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.tsfile.utils.ReadWriteIOUtils;
+
+import java.nio.ByteBuffer;
+
+public class LikeExpression extends UnaryExpression {
+
+  private final String pattern;
+
+  public LikeExpression(Expression expression, String pattern) {
+    super(expression);
+    this.pattern = pattern;
+  }
+
+  public LikeExpression(ByteBuffer byteBuffer) {
+    super(Expression.deserialize(byteBuffer));
+    pattern = ReadWriteIOUtils.readString(byteBuffer);
+  }
+
+  @Override
+  protected String getExpressionStringInternal() {
+    return expression + " LIKE " + pattern;
+  }
+
+  @Override
+  public ExpressionType getExpressionType() {
+    return ExpressionType.LIKE;
+  }
+
+  @Override
+  protected Transformer constructTransformer(LayerPointReader pointReader) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  protected Expression constructExpression(Expression childExpression) {
+    return new LikeExpression(childExpression, pattern);
+  }
+
+  @Override
+  protected void serialize(ByteBuffer byteBuffer) {
+    super.serialize(byteBuffer);
+    ReadWriteIOUtils.write(pattern, byteBuffer);
+  }
+}
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 cd657230a9..97a7c5ceb7 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,175 +19,35 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
-import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
-import org.apache.iotdb.db.metadata.path.PartialPath;
-import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
-import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
-import org.apache.iotdb.db.qp.utils.WildcardsRemover;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ExpressionType;
-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.layer.IntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
-import org.apache.iotdb.db.query.udf.core.layer.RawQueryInputLayer;
-import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnMultiReferenceIntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReferenceIntermediateLayer;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+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.LogicNotTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
-public class LogicNotExpression extends Expression {
-
-  private final Expression expression;
+public class LogicNotExpression extends UnaryExpression {
 
   public LogicNotExpression(Expression expression) {
-    this.expression = expression;
+    super(expression);
   }
 
   public LogicNotExpression(ByteBuffer byteBuffer) {
-    expression = Expression.deserialize(byteBuffer);
-  }
-
-  public Expression getExpression() {
-    return expression;
-  }
-
-  @Override
-  public boolean isConstantOperandInternal() {
-    return expression.isConstantOperand();
-  }
-
-  @Override
-  public List<Expression> getExpressions() {
-    return Collections.singletonList(expression);
-  }
-
-  @Override
-  public boolean isTimeSeriesGeneratingFunctionExpression() {
-    return !isUserDefinedAggregationFunctionExpression();
-  }
-
-  @Override
-  public boolean isUserDefinedAggregationFunctionExpression() {
-    return expression.isUserDefinedAggregationFunctionExpression()
-        || expression.isBuiltInAggregationFunctionExpression();
-  }
-
-  @Override
-  public void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void concat(
-      List<PartialPath> prefixPaths,
-      List<Expression> resultExpressions,
-      PathPatternTree patternTree) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
+    super(Expression.deserialize(byteBuffer));
   }
 
   @Override
-  public void removeWildcards(
-      org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover wildcardsRemover,
-      List<Expression> resultExpressions)
-      throws StatementAnalyzeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
+  protected Transformer constructTransformer(LayerPointReader pointReader) {
+    return new LogicNotTransformer(pointReader);
   }
 
   @Override
-  public void removeWildcards(WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
-      throws LogicalOptimizeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void collectPaths(Set<PartialPath> pathSet) {
-    expression.collectPaths(pathSet);
-  }
-
-  @Override
-  public void constructUdfExecutors(
-      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
-    expression.constructUdfExecutors(expressionName2Executor, zoneId);
-  }
-
-  @Override
-  public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
-    expression.bindInputLayerColumnIndexWithExpression(udtfPlan);
-    inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
-  }
-
-  @Override
-  public void updateStatisticsForMemoryAssigner(LayerMemoryAssigner memoryAssigner) {
-    expression.updateStatisticsForMemoryAssigner(memoryAssigner);
-    memoryAssigner.increaseExpressionReference(this);
-  }
-
-  @Override
-  public IntermediateLayer constructIntermediateLayer(
-      long queryId,
-      UDTFContext udtfContext,
-      RawQueryInputLayer rawTimeSeriesInputLayer,
-      Map<Expression, IntermediateLayer> expressionIntermediateLayerMap,
-      Map<Expression, TSDataType> expressionDataTypeMap,
-      LayerMemoryAssigner memoryAssigner)
-      throws QueryProcessException, IOException {
-    if (!expressionIntermediateLayerMap.containsKey(this)) {
-      float memoryBudgetInMB = memoryAssigner.assign();
-
-      IntermediateLayer parentLayerPointReader =
-          expression.constructIntermediateLayer(
-              queryId,
-              udtfContext,
-              rawTimeSeriesInputLayer,
-              expressionIntermediateLayerMap,
-              expressionDataTypeMap,
-              memoryAssigner);
-      Transformer transformer =
-          new LogicNotTransformer(parentLayerPointReader.constructPointReader());
-      expressionDataTypeMap.put(this, transformer.getDataType());
-
-      // SingleInputColumnMultiReferenceIntermediateLayer doesn't support ConstantLayerPointReader
-      // yet. And since a ConstantLayerPointReader won't produce too much IO,
-      // SingleInputColumnSingleReferenceIntermediateLayer could be a better choice.
-      expressionIntermediateLayerMap.put(
-          this,
-          memoryAssigner.getReference(this) == 1 || isConstantOperand()
-              ? new SingleInputColumnSingleReferenceIntermediateLayer(
-                  this, queryId, memoryBudgetInMB, transformer)
-              : new SingleInputColumnMultiReferenceIntermediateLayer(
-                  this, queryId, memoryBudgetInMB, transformer));
-    }
-
-    return expressionIntermediateLayerMap.get(this);
+  protected Expression constructExpression(Expression childExpression) {
+    return new LogicNotExpression(childExpression);
   }
 
   @Override
@@ -203,9 +63,4 @@ public class LogicNotExpression extends Expression {
   public ExpressionType getExpressionType() {
     return ExpressionType.LOGIC_NOT;
   }
-
-  @Override
-  protected void serialize(ByteBuffer byteBuffer) {
-    Expression.serialize(expression, byteBuffer);
-  }
 }
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 101c1b1795..5aaed35f55 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,175 +19,35 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
-import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
-import org.apache.iotdb.db.metadata.path.PartialPath;
-import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
-import org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover;
-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;
-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.layer.IntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
-import org.apache.iotdb.db.query.udf.core.layer.RawQueryInputLayer;
-import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnMultiReferenceIntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReferenceIntermediateLayer;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
+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.ArithmeticNegationTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
-public class NegationExpression extends Expression {
-
-  private final Expression expression;
+public class NegationExpression extends UnaryExpression {
 
   public NegationExpression(Expression expression) {
-    this.expression = expression;
+    super(expression);
   }
 
   public NegationExpression(ByteBuffer byteBuffer) {
-    expression = Expression.deserialize(byteBuffer);
-  }
-
-  public Expression getExpression() {
-    return expression;
-  }
-
-  @Override
-  public boolean isConstantOperandInternal() {
-    return expression.isConstantOperand();
-  }
-
-  @Override
-  public List<Expression> getExpressions() {
-    return Collections.singletonList(expression);
-  }
-
-  @Override
-  public boolean isTimeSeriesGeneratingFunctionExpression() {
-    return !isUserDefinedAggregationFunctionExpression();
-  }
-
-  @Override
-  public boolean isUserDefinedAggregationFunctionExpression() {
-    return expression.isUserDefinedAggregationFunctionExpression()
-        || expression.isBuiltInAggregationFunctionExpression();
-  }
-
-  @Override
-  public void concat(
-      List<PartialPath> prefixPaths,
-      List<Expression> resultExpressions,
-      PathPatternTree patternTree) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
-    }
+    super(Expression.deserialize(byteBuffer));
   }
 
   @Override
-  public void removeWildcards(WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
-      throws StatementAnalyzeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
-    }
+  protected Transformer constructTransformer(LayerPointReader pointReader) {
+    return new ArithmeticNegationTransformer(pointReader);
   }
 
   @Override
-  public void removeWildcards(
-      org.apache.iotdb.db.qp.utils.WildcardsRemover wildcardsRemover,
-      List<Expression> resultExpressions)
-      throws LogicalOptimizeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void collectPaths(Set<PartialPath> pathSet) {
-    expression.collectPaths(pathSet);
-  }
-
-  @Override
-  public void constructUdfExecutors(
-      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
-    expression.constructUdfExecutors(expressionName2Executor, zoneId);
-  }
-
-  @Override
-  public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
-    expression.bindInputLayerColumnIndexWithExpression(udtfPlan);
-    inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
-  }
-
-  @Override
-  public void updateStatisticsForMemoryAssigner(LayerMemoryAssigner memoryAssigner) {
-    expression.updateStatisticsForMemoryAssigner(memoryAssigner);
-    memoryAssigner.increaseExpressionReference(this);
-  }
-
-  @Override
-  public IntermediateLayer constructIntermediateLayer(
-      long queryId,
-      UDTFContext udtfContext,
-      RawQueryInputLayer rawTimeSeriesInputLayer,
-      Map<Expression, IntermediateLayer> expressionIntermediateLayerMap,
-      Map<Expression, TSDataType> expressionDataTypeMap,
-      LayerMemoryAssigner memoryAssigner)
-      throws QueryProcessException, IOException {
-    if (!expressionIntermediateLayerMap.containsKey(this)) {
-      float memoryBudgetInMB = memoryAssigner.assign();
-
-      IntermediateLayer parentLayerPointReader =
-          expression.constructIntermediateLayer(
-              queryId,
-              udtfContext,
-              rawTimeSeriesInputLayer,
-              expressionIntermediateLayerMap,
-              expressionDataTypeMap,
-              memoryAssigner);
-      Transformer transformer =
-          new ArithmeticNegationTransformer(parentLayerPointReader.constructPointReader());
-      expressionDataTypeMap.put(this, transformer.getDataType());
-
-      // SingleInputColumnMultiReferenceIntermediateLayer doesn't support ConstantLayerPointReader
-      // yet. And since a ConstantLayerPointReader won't produce too much IO,
-      // SingleInputColumnSingleReferenceIntermediateLayer could be a better choice.
-      expressionIntermediateLayerMap.put(
-          this,
-          memoryAssigner.getReference(this) == 1 || isConstantOperand()
-              ? new SingleInputColumnSingleReferenceIntermediateLayer(
-                  this, queryId, memoryBudgetInMB, transformer)
-              : new SingleInputColumnMultiReferenceIntermediateLayer(
-                  this, queryId, memoryBudgetInMB, transformer));
-    }
-
-    return expressionIntermediateLayerMap.get(this);
+  protected Expression constructExpression(Expression childExpression) {
+    return new NegationExpression(childExpression);
   }
 
   @Override
@@ -204,9 +64,4 @@ public class NegationExpression extends Expression {
   public ExpressionType getExpressionType() {
     return ExpressionType.NEGATION;
   }
-
-  @Override
-  protected void serialize(ByteBuffer byteBuffer) {
-    Expression.serialize(expression, byteBuffer);
-  }
 }
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 2bdafb1804..f2e74d597a 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,146 +19,48 @@
 
 package org.apache.iotdb.db.query.expression.unary;
 
-import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
-import org.apache.iotdb.db.metadata.path.PartialPath;
-import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
-import org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover;
-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;
-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.layer.IntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
-import org.apache.iotdb.db.query.udf.core.layer.RawQueryInputLayer;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
+import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import org.apache.commons.lang3.Validate;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.regex.Pattern;
 
-public class RegularExpression extends Expression {
+public class RegularExpression extends UnaryExpression {
 
-  private final Expression expression;
   private final String patternString;
   private final Pattern pattern;
 
   public RegularExpression(Expression expression, String patternString) {
-    this.expression = expression;
+    super(expression);
     this.patternString = patternString;
     pattern = Pattern.compile(patternString);
   }
 
   public RegularExpression(Expression expression, String patternString, Pattern pattern) {
-    this.expression = expression;
+    super(expression);
     this.patternString = patternString;
     this.pattern = pattern;
   }
 
   public RegularExpression(ByteBuffer byteBuffer) {
-    expression = Expression.deserialize(byteBuffer);
+    super(Expression.deserialize(byteBuffer));
     patternString = ReadWriteIOUtils.readString(byteBuffer);
     pattern = Pattern.compile(Validate.notNull(patternString));
   }
 
   @Override
-  public void concat(
-      List<PartialPath> prefixPaths,
-      List<Expression> resultExpressions,
-      PathPatternTree patternTree) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
-    }
+  protected Transformer constructTransformer(LayerPointReader pointReader) {
+    throw new UnsupportedOperationException();
   }
 
   @Override
-  public void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
-    }
-  }
-
-  @Override
-  public void removeWildcards(WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
-      throws StatementAnalyzeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
-    }
-  }
-
-  @Override
-  public void removeWildcards(
-      org.apache.iotdb.db.qp.utils.WildcardsRemover wildcardsRemover,
-      List<Expression> resultExpressions)
-      throws LogicalOptimizeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
-    }
-  }
-
-  @Override
-  public void collectPaths(Set<PartialPath> pathSet) {
-    expression.collectPaths(pathSet);
-  }
-
-  @Override
-  public void constructUdfExecutors(
-      Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
-    expression.constructUdfExecutors(expressionName2Executor, zoneId);
-  }
-
-  @Override
-  public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
-    expression.bindInputLayerColumnIndexWithExpression(udtfPlan);
-    inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
-  }
-
-  @Override
-  public void updateStatisticsForMemoryAssigner(LayerMemoryAssigner memoryAssigner) {
-    expression.updateStatisticsForMemoryAssigner(memoryAssigner);
-    memoryAssigner.increaseExpressionReference(this);
-  }
-
-  @Override
-  public IntermediateLayer constructIntermediateLayer(
-      long queryId,
-      UDTFContext udtfContext,
-      RawQueryInputLayer rawTimeSeriesInputLayer,
-      Map<Expression, IntermediateLayer> expressionIntermediateLayerMap,
-      Map<Expression, TSDataType> expressionDataTypeMap,
-      LayerMemoryAssigner memoryAssigner)
-      throws QueryProcessException, IOException {
-    // TODO
-    throw new RuntimeException();
-  }
-
-  @Override
-  protected boolean isConstantOperandInternal() {
-    return expression.isConstantOperand();
-  }
-
-  @Override
-  public List<Expression> getExpressions() {
-    return Collections.singletonList(expression);
+  protected Expression constructExpression(Expression childExpression) {
+    return new RegularExpression(childExpression, patternString, pattern);
   }
 
   @Override
@@ -173,18 +75,7 @@ public class RegularExpression extends Expression {
 
   @Override
   protected void serialize(ByteBuffer byteBuffer) {
-    Expression.serialize(expression, byteBuffer);
+    super.serialize(byteBuffer);
     ReadWriteIOUtils.write(patternString, byteBuffer);
   }
-
-  @Override
-  public boolean isTimeSeriesGeneratingFunctionExpression() {
-    return !isUserDefinedAggregationFunctionExpression();
-  }
-
-  @Override
-  public boolean isUserDefinedAggregationFunctionExpression() {
-    return expression.isUserDefinedAggregationFunctionExpression()
-        || expression.isBuiltInAggregationFunctionExpression();
-  }
 }
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/UnaryExpression.java
similarity index 75%
copy from server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
copy to server/src/main/java/org/apache/iotdb/db/query/expression/unary/UnaryExpression.java
index cd657230a9..4540e80348 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/UnaryExpression.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.qp.utils.WildcardsRemover;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.ExpressionType;
 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.layer.IntermediateLayer;
@@ -35,7 +34,7 @@ import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
 import org.apache.iotdb.db.query.udf.core.layer.RawQueryInputLayer;
 import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnMultiReferenceIntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReferenceIntermediateLayer;
-import org.apache.iotdb.db.query.udf.core.transformer.LogicNotTransformer;
+import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
@@ -48,111 +47,64 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-public class LogicNotExpression extends Expression {
+public abstract class UnaryExpression extends Expression {
 
-  private final Expression expression;
+  protected final Expression expression;
 
-  public LogicNotExpression(Expression expression) {
+  protected UnaryExpression(Expression expression) {
     this.expression = expression;
   }
 
-  public LogicNotExpression(ByteBuffer byteBuffer) {
-    expression = Expression.deserialize(byteBuffer);
-  }
-
-  public Expression getExpression() {
+  public final Expression getExpression() {
     return expression;
   }
 
   @Override
-  public boolean isConstantOperandInternal() {
+  public final boolean isConstantOperandInternal() {
     return expression.isConstantOperand();
   }
 
   @Override
-  public List<Expression> getExpressions() {
+  public final List<Expression> getExpressions() {
     return Collections.singletonList(expression);
   }
 
   @Override
-  public boolean isTimeSeriesGeneratingFunctionExpression() {
+  public final boolean isTimeSeriesGeneratingFunctionExpression() {
     return !isUserDefinedAggregationFunctionExpression();
   }
 
   @Override
-  public boolean isUserDefinedAggregationFunctionExpression() {
+  public final boolean isUserDefinedAggregationFunctionExpression() {
     return expression.isUserDefinedAggregationFunctionExpression()
         || expression.isBuiltInAggregationFunctionExpression();
   }
 
   @Override
-  public void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void concat(
-      List<PartialPath> prefixPaths,
-      List<Expression> resultExpressions,
-      PathPatternTree patternTree) {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void removeWildcards(
-      org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover wildcardsRemover,
-      List<Expression> resultExpressions)
-      throws StatementAnalyzeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void removeWildcards(WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
-      throws LogicalOptimizeException {
-    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
-    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
-    for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new LogicNotExpression(resultExpression));
-    }
-  }
-
-  @Override
-  public void collectPaths(Set<PartialPath> pathSet) {
+  public final void collectPaths(Set<PartialPath> pathSet) {
     expression.collectPaths(pathSet);
   }
 
   @Override
-  public void constructUdfExecutors(
+  public final void constructUdfExecutors(
       Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId) {
     expression.constructUdfExecutors(expressionName2Executor, zoneId);
   }
 
   @Override
-  public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
+  public final void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     expression.bindInputLayerColumnIndexWithExpression(udtfPlan);
     inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
   }
 
   @Override
-  public void updateStatisticsForMemoryAssigner(LayerMemoryAssigner memoryAssigner) {
+  public final void updateStatisticsForMemoryAssigner(LayerMemoryAssigner memoryAssigner) {
     expression.updateStatisticsForMemoryAssigner(memoryAssigner);
     memoryAssigner.increaseExpressionReference(this);
   }
 
   @Override
-  public IntermediateLayer constructIntermediateLayer(
+  public final IntermediateLayer constructIntermediateLayer(
       long queryId,
       UDTFContext udtfContext,
       RawQueryInputLayer rawTimeSeriesInputLayer,
@@ -171,8 +123,7 @@ public class LogicNotExpression extends Expression {
               expressionIntermediateLayerMap,
               expressionDataTypeMap,
               memoryAssigner);
-      Transformer transformer =
-          new LogicNotTransformer(parentLayerPointReader.constructPointReader());
+      Transformer transformer = constructTransformer(parentLayerPointReader.constructPointReader());
       expressionDataTypeMap.put(this, transformer.getDataType());
 
       // SingleInputColumnMultiReferenceIntermediateLayer doesn't support ConstantLayerPointReader
@@ -190,20 +141,54 @@ public class LogicNotExpression extends Expression {
     return expressionIntermediateLayerMap.get(this);
   }
 
+  protected abstract Transformer constructTransformer(LayerPointReader pointReader);
+
+  @Override
+  public final void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
+    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
+    expression.concat(prefixPaths, resultExpressionsForRecursion);
+    for (Expression resultExpression : resultExpressionsForRecursion) {
+      resultExpressions.add(constructExpression(resultExpression));
+    }
+  }
+
+  @Override
+  public final void concat(
+      List<PartialPath> prefixPaths,
+      List<Expression> resultExpressions,
+      PathPatternTree patternTree) {
+    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
+    expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
+    for (Expression resultExpression : resultExpressionsForRecursion) {
+      resultExpressions.add(constructExpression(resultExpression));
+    }
+  }
+
   @Override
-  public String getExpressionStringInternal() {
-    return expression instanceof FunctionExpression
-            || expression instanceof ConstantOperand
-            || expression instanceof TimeSeriesOperand
-        ? "!" + expression
-        : "!(" + expression + ")";
+  public final void removeWildcards(
+      org.apache.iotdb.db.mpp.sql.rewriter.WildcardsRemover wildcardsRemover,
+      List<Expression> resultExpressions)
+      throws StatementAnalyzeException {
+    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
+    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
+    for (Expression resultExpression : resultExpressionsForRecursion) {
+      resultExpressions.add(constructExpression(resultExpression));
+    }
   }
 
   @Override
-  public ExpressionType getExpressionType() {
-    return ExpressionType.LOGIC_NOT;
+  public final void removeWildcards(
+      WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
+      throws LogicalOptimizeException {
+    List<Expression> resultExpressionsForRecursion = new ArrayList<>();
+    expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
+    for (Expression resultExpression : resultExpressionsForRecursion) {
+      resultExpressions.add(constructExpression(resultExpression));
+    }
   }
 
+  protected abstract Expression constructExpression(Expression childExpression);
+
   @Override
   protected void serialize(ByteBuffer byteBuffer) {
     Expression.serialize(expression, byteBuffer);
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 b1f4fd90b2..5fcd2aa35a 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
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+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.tsfile.file.metadata.enums.TSDataType;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFContext.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFContext.java
index cb7d467403..2c2e19abd2 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFContext.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFContext.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.query.udf.core.executor;
 
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.udf.service.UDFClassLoaderManager;
 
 import java.time.ZoneId;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFExecutor.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFExecutor.java
index 14517e6979..83cb5990a0 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFExecutor.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.query.udf.core.executor;
 
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+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.access.Row;
 import org.apache.iotdb.db.query.udf.api.access.RowWindow;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/ConstantIntermediateLayer.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/ConstantIntermediateLayer.java
index 70f717eba6..b82b268976 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/ConstantIntermediateLayer.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/ConstantIntermediateLayer.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.query.udf.core.layer;
 
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.query.expression.unary.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.query.udf.api.customizer.strategy.SlidingSizeWindowAccessStrategy;
 import org.apache.iotdb.db.query.udf.api.customizer.strategy.SlidingTimeWindowAccessStrategy;
 import org.apache.iotdb.db.query.udf.core.reader.ConstantLayerPointReader;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/LayerMemoryAssigner.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/LayerMemoryAssigner.java
index f03383b03b..03f6fbe8b2 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/LayerMemoryAssigner.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/layer/LayerMemoryAssigner.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.query.udf.core.layer;
 
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/core/reader/ConstantLayerPointReader.java b/server/src/main/java/org/apache/iotdb/db/query/udf/core/reader/ConstantLayerPointReader.java
index 058d6067a3..c0d99e9189 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/core/reader/ConstantLayerPointReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/core/reader/ConstantLayerPointReader.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.query.udf.core.reader;
 
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.query.expression.unary.ConstantOperand;
+import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.utils.CommonUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java b/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
index db832a39bf..4253ddd1af 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
@@ -28,7 +28,7 @@ import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
 import org.apache.iotdb.db.exception.UDFRegistrationException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
-import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.query.udf.api.UDF;
 import org.apache.iotdb.db.query.udf.builtin.BuiltinFunction;
 import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
diff --git a/server/src/test/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBLogicalGeneratorTest.java b/server/src/test/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBLogicalGeneratorTest.java
index c130edaab3..31c662cdef 100644
--- a/server/src/test/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBLogicalGeneratorTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/protocol/influxdb/sql/InfluxDBLogicalGeneratorTest.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
 import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
 import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+import org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
 
 import org.junit.Test;