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/23 10:36:12 UTC

[iotdb] branch master updated: [IOTDB-2989] Expression Serialize & Deserialize (#5649)

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 d47339793f [IOTDB-2989] Expression Serialize & Deserialize (#5649)
d47339793f is described below

commit d47339793f1a1c9055f9f80a05ddd61083aae29f
Author: Steve Yurong Su <ro...@apache.org>
AuthorDate: Sat Apr 23 18:36:07 2022 +0800

    [IOTDB-2989] Expression Serialize & Deserialize (#5649)
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |   3 +
 .../apache/iotdb/db/mpp/sql/parser/ASTVisitor.java | 118 ++++++++++++++-----
 .../statement/component/FilterNullComponent.java   |   5 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  76 +++++++-----
 .../iotdb/db/query/expression/Expression.java      | 114 +++++++++++++++++-
 .../iotdb/db/query/expression/ExpressionType.java  | 107 ++++-------------
 .../iotdb/db/query/expression/ResultColumn.java    |  21 ++--
 .../expression/binary/AdditionExpression.java      |  19 +--
 .../query/expression/binary/BinaryExpression.java  |  12 +-
 .../expression/binary/DivisionExpression.java      |  19 +--
 .../query/expression/binary/EqualToExpression.java |  20 ++--
 .../expression/binary/GreaterEqualExpression.java  |  19 +--
 .../expression/binary/GreaterThanExpression.java   |  20 ++--
 .../expression/binary/LessEqualExpression.java     |  19 +--
 .../expression/binary/LessThanExpression.java      |  19 +--
 .../expression/binary/LogicAndExpression.java      |  20 ++--
 .../query/expression/binary/LogicOrExpression.java |  20 ++--
 .../query/expression/binary/ModuloExpression.java  |  19 +--
 .../binary/MultiplicationExpression.java           |  19 +--
 .../expression/binary/NonEqualExpression.java      |  19 +--
 .../expression/binary/SubtractionExpression.java   |  19 +--
 .../db/query/expression/unary/ConstantOperand.java |  25 ++--
 .../query/expression/unary/FunctionExpression.java |  45 ++++---
 .../query/expression/unary/LogicNotExpression.java |  23 ++--
 .../query/expression/unary/NegationExpression.java |  22 ++--
 ...ationExpression.java => RegularExpression.java} | 130 +++++++++------------
 .../query/expression/unary/TimeSeriesOperand.java  |  21 ++--
 27 files changed, 498 insertions(+), 475 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 fc0234fb29..24c8dfb88c 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
@@ -845,9 +845,12 @@ 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
+    | unaryBeforeInExpression=expression OPERATOR_IN LR_BRACKET constant (COMMA constant)* RR_BRACKET
     | leftExpression=expression (OPERATOR_AND | OPERATOR_OR) rightExpression=expression
     | functionName LR_BRACKET expression (COMMA expression)* functionAttribute* RR_BRACKET
     | suffixPathCanInExpr
+    | time=(TIME | TIMESTAMP)
     | constant
     ;
 
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 e445961919..69b1439040 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
@@ -65,6 +65,8 @@ import org.apache.iotdb.db.mpp.sql.statement.sys.AuthorStatement;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
 import org.apache.iotdb.db.qp.sql.IoTDBSqlParser;
+import org.apache.iotdb.db.qp.sql.IoTDBSqlParser.ConstantContext;
+import org.apache.iotdb.db.qp.sql.IoTDBSqlParser.ExpressionContext;
 import org.apache.iotdb.db.qp.sql.IoTDBSqlParserBaseVisitor;
 import org.apache.iotdb.db.qp.utils.DatetimeUtils;
 import org.apache.iotdb.db.query.executor.fill.IFill;
@@ -74,11 +76,20 @@ import org.apache.iotdb.db.query.executor.fill.ValueFill;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.binary.AdditionExpression;
 import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
+import org.apache.iotdb.db.query.expression.binary.EqualToExpression;
+import org.apache.iotdb.db.query.expression.binary.GreaterEqualExpression;
+import org.apache.iotdb.db.query.expression.binary.GreaterThanExpression;
+import org.apache.iotdb.db.query.expression.binary.LessEqualExpression;
+import org.apache.iotdb.db.query.expression.binary.LessThanExpression;
+import org.apache.iotdb.db.query.expression.binary.LogicAndExpression;
+import org.apache.iotdb.db.query.expression.binary.LogicOrExpression;
 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.unary.LogicNotExpression;
 import org.apache.iotdb.db.query.expression.unary.NegationExpression;
 import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -1605,6 +1616,11 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
           : parseExpression(context.unaryAfterSign);
     }
 
+    // OPERATOR_NOT unaryAfterNot=expression
+    if (context.OPERATOR_NOT() != null) {
+      return new LogicNotExpression(parseExpression(context.unaryAfterNot));
+    }
+
     // leftExpression=expression (STAR | DIV | MOD) rightExpression=expression
     // leftExpression=expression (PLUS | MINUS) rightExpression=expression
     if (context.leftExpression != null && context.rightExpression != null) {
@@ -1625,6 +1641,30 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
       if (context.MINUS() != null) {
         return new SubtractionExpression(leftExpression, rightExpression);
       }
+      if (context.OPERATOR_GT() != null) {
+        return new GreaterThanExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_GTE() != null) {
+        return new GreaterEqualExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_LT() != null) {
+        return new LessThanExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_LTE() != null) {
+        return new LessEqualExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_DEQ() != null) {
+        return new EqualToExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_NEQ() != null) {
+        return new NonEqualExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_AND() != null) {
+        return new LogicAndExpression(leftExpression, rightExpression);
+      }
+      if (context.OPERATOR_OR() != null) {
+        return new LogicOrExpression(leftExpression, rightExpression);
+      }
     }
 
     // functionName=suffixPath LR_BRACKET expression (COMMA expression)* functionAttribute*
@@ -1633,37 +1673,25 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
       return parseFunctionExpression(context);
     }
 
+    // unaryBeforeRegularExpression=expression (REGEXP | LIKE) STRING_LITERAL
+    if (context.unaryBeforeRegularExpression != null) {
+      return parseRegularExpression(context);
+    }
+
+    // unaryBeforeInExpression=expression OPERATOR_IN LR_BRACKET constant (COMMA constant)*
+    // RR_BRACKET
+    if (context.unaryBeforeInExpression != null) {
+      return parseInExpression(context);
+    }
+
     // suffixPath
     if (context.suffixPathCanInExpr() != null) {
       return new TimeSeriesOperand(parseSuffixPathCanInExpr(context.suffixPathCanInExpr()));
     }
 
-    if (context.constant() != null) {
-      try {
-        IoTDBSqlParser.ConstantContext constantContext = context.constant();
-        if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_13)) {
-          if (constantContext.BOOLEAN_LITERAL() != null) {
-            return new ConstantOperand(
-                TSDataType.BOOLEAN, constantContext.BOOLEAN_LITERAL().getText());
-          } else if (constantContext.STRING_LITERAL() != null) {
-            String text = constantContext.STRING_LITERAL().getText();
-            return new ConstantOperand(TSDataType.TEXT, parseStringLiteral(text));
-          } else if (constantContext.INTEGER_LITERAL() != null) {
-            return new ConstantOperand(
-                TSDataType.INT64, constantContext.INTEGER_LITERAL().getText());
-          } else if (constantContext.realLiteral() != null) {
-            return new ConstantOperand(TSDataType.DOUBLE, constantContext.realLiteral().getText());
-          } else {
-            throw new SemanticException(
-                "Unsupported constant operand: " + constantContext.getText());
-          }
-        } else if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_12)) {
-          // if client version is before 0.13, node name in expression may be a constant
-          return new TimeSeriesOperand(convertConstantToPath(context.constant().getText()));
-        }
-      } catch (IllegalPathException e) {
-        throw new SQLParserException(e.getMessage());
-      }
+    // constant
+    if (context.constant() != null && !context.constant().isEmpty()) {
+      return parseConstantOperand(context.constant(0));
     }
 
     throw new UnsupportedOperationException();
@@ -1686,7 +1714,7 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
     // It is not allowed to have function expressions like F(1, 1.0). There should be at least one
     // non-pure-constant sub-expression, otherwise the timestamp of the row cannot be inferred.
     if (!hasNonPureConstantSubExpression) {
-      throw new SemanticException(
+      throw new SQLParserException(
           "Invalid function expression, all the arguments are constant operands: "
               + functionClause.getText());
     }
@@ -1702,6 +1730,42 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
     return functionExpression;
   }
 
+  private Expression parseRegularExpression(ExpressionContext context) {
+    return null;
+  }
+
+  private Expression parseInExpression(ExpressionContext context) {
+    return null;
+  }
+
+  private Expression parseConstantOperand(ConstantContext constantContext) {
+    try {
+      if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_13)) {
+        if (constantContext.BOOLEAN_LITERAL() != null) {
+          return new ConstantOperand(
+              TSDataType.BOOLEAN, constantContext.BOOLEAN_LITERAL().getText());
+        } else if (constantContext.STRING_LITERAL() != null) {
+          String text = constantContext.STRING_LITERAL().getText();
+          return new ConstantOperand(TSDataType.TEXT, parseStringLiteral(text));
+        } else if (constantContext.INTEGER_LITERAL() != null) {
+          return new ConstantOperand(TSDataType.INT64, constantContext.INTEGER_LITERAL().getText());
+        } else if (constantContext.realLiteral() != null) {
+          return new ConstantOperand(TSDataType.DOUBLE, constantContext.realLiteral().getText());
+        } else {
+          throw new SQLParserException(
+              "Unsupported constant operand: " + constantContext.getText());
+        }
+      } else if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_12)) {
+        // if client version is before 0.13, node name in expression may be a constant
+        return new TimeSeriesOperand(convertConstantToPath(constantContext.getText()));
+      } else {
+        throw new UnsupportedOperationException();
+      }
+    } catch (IllegalPathException e) {
+      throw new SQLParserException(e.getMessage());
+    }
+  }
+
   private QueryFilter parseOrExpression(IoTDBSqlParser.OrExpressionContext ctx) {
     if (ctx.andExpression().size() == 1) {
       return parseAndExpression(ctx.andExpression(0));
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/FilterNullComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/FilterNullComponent.java
index 77c6bd0f70..55c248f563 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/FilterNullComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/component/FilterNullComponent.java
@@ -21,7 +21,6 @@ package org.apache.iotdb.db.mpp.sql.statement.component;
 
 import org.apache.iotdb.db.mpp.sql.statement.StatementNode;
 import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.ExpressionType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
@@ -78,7 +77,7 @@ public class FilterNullComponent extends StatementNode {
     ReadWriteIOUtils.write(filterNullPolicy.ordinal(), byteBuffer);
     ReadWriteIOUtils.write(withoutNullColumns.size(), byteBuffer);
     for (Expression expression : withoutNullColumns) {
-      expression.serialize(byteBuffer);
+      Expression.serialize(expression, byteBuffer);
     }
   }
 
@@ -88,7 +87,7 @@ public class FilterNullComponent extends StatementNode {
     int withoutNullSize = ReadWriteIOUtils.readInt(byteBuffer);
     List<Expression> withoutNullColumns = new ArrayList<>();
     for (int i = 0; i < withoutNullSize; i++) {
-      withoutNullColumns.add(ExpressionType.deserialize(byteBuffer));
+      withoutNullColumns.add(Expression.deserialize(byteBuffer));
     }
     FilterNullComponent filterNullComponent = new FilterNullComponent();
     filterNullComponent.withoutNullColumns = withoutNullColumns;
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 c1dd241ef7..4c1c8319ab 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
@@ -2577,37 +2577,25 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
       return parseFunctionExpression(context);
     }
 
+    // unaryBeforeRegularExpression=expression (REGEXP | LIKE) STRING_LITERAL
+    if (context.unaryBeforeRegularExpression != null) {
+      return parseRegularExpression(context);
+    }
+
+    // unaryBeforeInExpression=expression OPERATOR_IN LR_BRACKET constant (COMMA constant)*
+    // RR_BRACKET
+    if (context.unaryBeforeInExpression != null) {
+      return parseInExpression(context);
+    }
+
     // suffixPath
     if (context.suffixPathCanInExpr() != null) {
       return new TimeSeriesOperand(parseSuffixPathCanInExpr(context.suffixPathCanInExpr()));
     }
 
-    if (context.constant() != null) {
-      try {
-        ConstantContext constantContext = context.constant();
-        if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_13)) {
-          if (constantContext.BOOLEAN_LITERAL() != null) {
-            return new ConstantOperand(
-                TSDataType.BOOLEAN, constantContext.BOOLEAN_LITERAL().getText());
-          } else if (constantContext.STRING_LITERAL() != null) {
-            String text = constantContext.STRING_LITERAL().getText();
-            return new ConstantOperand(TSDataType.TEXT, parseStringLiteral(text));
-          } else if (constantContext.INTEGER_LITERAL() != null) {
-            return new ConstantOperand(
-                TSDataType.INT64, constantContext.INTEGER_LITERAL().getText());
-          } else if (constantContext.realLiteral() != null) {
-            return new ConstantOperand(TSDataType.DOUBLE, constantContext.realLiteral().getText());
-          } else {
-            throw new SQLParserException(
-                "Unsupported constant operand: " + constantContext.getText());
-          }
-        } else if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_12)) {
-          // if client version is before 0.13, node name in expression may be a constant
-          return new TimeSeriesOperand(convertConstantToPath(context.constant().getText()));
-        }
-      } catch (IllegalPathException e) {
-        throw new SQLParserException(e.getMessage());
-      }
+    // constant
+    if (context.constant() != null && !context.constant().isEmpty()) {
+      return parseConstantOperand(context.constant(0));
     }
 
     throw new UnsupportedOperationException();
@@ -2646,6 +2634,42 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
     return functionExpression;
   }
 
+  private Expression parseRegularExpression(ExpressionContext context) {
+    return null;
+  }
+
+  private Expression parseInExpression(ExpressionContext context) {
+    return null;
+  }
+
+  private Expression parseConstantOperand(ConstantContext constantContext) {
+    try {
+      if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_13)) {
+        if (constantContext.BOOLEAN_LITERAL() != null) {
+          return new ConstantOperand(
+              TSDataType.BOOLEAN, constantContext.BOOLEAN_LITERAL().getText());
+        } else if (constantContext.STRING_LITERAL() != null) {
+          String text = constantContext.STRING_LITERAL().getText();
+          return new ConstantOperand(TSDataType.TEXT, parseStringLiteral(text));
+        } else if (constantContext.INTEGER_LITERAL() != null) {
+          return new ConstantOperand(TSDataType.INT64, constantContext.INTEGER_LITERAL().getText());
+        } else if (constantContext.realLiteral() != null) {
+          return new ConstantOperand(TSDataType.DOUBLE, constantContext.realLiteral().getText());
+        } else {
+          throw new SQLParserException(
+              "Unsupported constant operand: " + constantContext.getText());
+        }
+      } else if (clientVersion.equals(IoTDBConstant.ClientVersion.V_0_12)) {
+        // if client version is before 0.13, node name in expression may be a constant
+        return new TimeSeriesOperand(convertConstantToPath(constantContext.getText()));
+      } else {
+        throw new UnsupportedOperationException();
+      }
+    } catch (IllegalPathException e) {
+      throw new SQLParserException(e.getMessage());
+    }
+  }
+
   private FilterOperator parseOrExpression(IoTDBSqlParser.OrExpressionContext ctx) {
     if (ctx.andExpression().size() == 1) {
       return parseAndExpression(ctx.andExpression(0));
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 1e481c2db5..8f202932e7 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
@@ -26,7 +26,25 @@ 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.binary.AdditionExpression;
+import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
+import org.apache.iotdb.db.query.expression.binary.EqualToExpression;
+import org.apache.iotdb.db.query.expression.binary.GreaterEqualExpression;
+import org.apache.iotdb.db.query.expression.binary.GreaterThanExpression;
+import org.apache.iotdb.db.query.expression.binary.LessEqualExpression;
+import org.apache.iotdb.db.query.expression.binary.LessThanExpression;
+import org.apache.iotdb.db.query.expression.binary.LogicAndExpression;
+import org.apache.iotdb.db.query.expression.binary.LogicOrExpression;
+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.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;
@@ -66,10 +84,6 @@ public abstract class Expression {
     return false;
   }
 
-  public void bindInputColumnIndex(int inputColumnIndex) {
-    this.inputColumnIndex = inputColumnIndex;
-  }
-
   public abstract void concat(
       List<PartialPath> prefixPaths,
       List<Expression> resultExpressions,
@@ -201,7 +215,95 @@ public abstract class Expression {
     }
   }
 
-  public void serialize(ByteBuffer byteBuffer) {
-    ReadWriteIOUtils.write(isConstantOperandCache, byteBuffer);
+  protected abstract short getExpressionType();
+
+  public static void serialize(Expression expression, ByteBuffer byteBuffer) {
+    ReadWriteIOUtils.write(expression.getExpressionType(), byteBuffer);
+
+    expression.serialize(byteBuffer);
+
+    ReadWriteIOUtils.write(expression.inputColumnIndex != null, byteBuffer);
+    if (expression.inputColumnIndex != null) {
+      ReadWriteIOUtils.write(expression.inputColumnIndex, byteBuffer);
+    }
+  }
+
+  protected abstract void serialize(ByteBuffer byteBuffer);
+
+  public static Expression deserialize(ByteBuffer byteBuffer) {
+    short type = ReadWriteIOUtils.readShort(byteBuffer);
+
+    Expression expression;
+    switch (type) {
+      case 0:
+        expression = new AdditionExpression(byteBuffer);
+        break;
+      case 1:
+        expression = new DivisionExpression(byteBuffer);
+        break;
+      case 2:
+        expression = new EqualToExpression(byteBuffer);
+        break;
+      case 3:
+        expression = new GreaterEqualExpression(byteBuffer);
+        break;
+      case 4:
+        expression = new GreaterThanExpression(byteBuffer);
+        break;
+      case 5:
+        expression = new LessEqualExpression(byteBuffer);
+        break;
+      case 6:
+        expression = new LessThanExpression(byteBuffer);
+        break;
+      case 7:
+        expression = new LogicAndExpression(byteBuffer);
+        break;
+      case 8:
+        expression = new LogicOrExpression(byteBuffer);
+        break;
+      case 9:
+        expression = new ModuloExpression(byteBuffer);
+        break;
+      case 10:
+        expression = new MultiplicationExpression(byteBuffer);
+        break;
+      case 11:
+        expression = new NonEqualExpression(byteBuffer);
+        break;
+      case 12:
+        expression = new SubtractionExpression(byteBuffer);
+        break;
+      case 13:
+        expression = new FunctionExpression(byteBuffer);
+        break;
+      case 14:
+        expression = new LogicNotExpression(byteBuffer);
+        break;
+      case 15:
+        expression = new NegationExpression(byteBuffer);
+        break;
+      case 16:
+        expression = new TimeSeriesOperand(byteBuffer);
+        break;
+      case 17:
+        expression = new ConstantOperand(byteBuffer);
+        break;
+      case 18:
+        expression = null;
+        break;
+      case 19:
+        expression = new RegularExpression(byteBuffer);
+        break;
+      default:
+        throw new IllegalArgumentException("Invalid expression type: " + type);
+    }
+
+    boolean hasInputColumnIndex = ReadWriteIOUtils.readBool(byteBuffer);
+    if (hasInputColumnIndex) {
+      expression.inputColumnIndex = ReadWriteIOUtils.readInt(byteBuffer);
+    }
+
+    return expression;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/ExpressionType.java b/server/src/main/java/org/apache/iotdb/db/query/expression/ExpressionType.java
index 67cc35d32f..4510f4a4a1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/ExpressionType.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/ExpressionType.java
@@ -18,46 +18,27 @@
  */
 package org.apache.iotdb.db.query.expression;
 
-import org.apache.iotdb.db.query.expression.binary.AdditionExpression;
-import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
-import org.apache.iotdb.db.query.expression.binary.EqualToExpression;
-import org.apache.iotdb.db.query.expression.binary.GreaterEqualExpression;
-import org.apache.iotdb.db.query.expression.binary.GreaterThanExpression;
-import org.apache.iotdb.db.query.expression.binary.LessEqualExpression;
-import org.apache.iotdb.db.query.expression.binary.LessThanExpression;
-import org.apache.iotdb.db.query.expression.binary.LogicAndExpression;
-import org.apache.iotdb.db.query.expression.binary.LogicOrExpression;
-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.unary.LogicNotExpression;
-import org.apache.iotdb.db.query.expression.unary.NegationExpression;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
-
-import java.nio.ByteBuffer;
-
 public enum ExpressionType {
-  Addition((short) 0),
-  Division((short) 1),
-  EqualTo((short) 2),
-  Greater_Equal((short) 3),
-  Greater_Than((short) 4),
-  Less_Equal((short) 5),
-  Less_Than((short) 6),
-  Logic_And((short) 7),
-  Logic_Or((short) 8),
-  Modulo((short) 9),
-  Multiplication((short) 10),
-  Non_Equal((short) 11),
-  Subtraction((short) 12),
-  Function((short) 13),
-  Logic_Not((short) 14),
-  Negation((short) 15),
-  TimeSeries((short) 16),
-  Constant((short) 17);
+  ADDITION((short) 0),
+  DIVISION((short) 1),
+  EQUAL_TO((short) 2),
+  GREATER_EQUAL((short) 3),
+  GREATER_THAN((short) 4),
+  LESS_EQUAL((short) 5),
+  LESS_THAN((short) 6),
+  LOGIC_AND((short) 7),
+  LOGIC_OR((short) 8),
+  MODULO((short) 9),
+  MULTIPLICATION((short) 10),
+  NON_EQUAL((short) 11),
+  SUBTRACTION((short) 12),
+  FUNCTION((short) 13),
+  LOGIC_NOT((short) 14),
+  NEGATION((short) 15),
+  TIME_SERIES((short) 16),
+  CONSTANT((short) 17),
+  IN((short) 18),
+  REGULAR((short) 19);
 
   private final short expressionType;
 
@@ -65,51 +46,7 @@ public enum ExpressionType {
     this.expressionType = expressionType;
   }
 
-  public void serialize(ByteBuffer buffer) {
-    buffer.putShort(expressionType);
-  }
-
-  public static Expression deserialize(ByteBuffer byteBuffer) {
-    short type = byteBuffer.getShort();
-    switch (type) {
-      case 0:
-        return AdditionExpression.deserialize(byteBuffer);
-      case 1:
-        return DivisionExpression.deserialize(byteBuffer);
-      case 2:
-        return EqualToExpression.deserialize(byteBuffer);
-      case 3:
-        return GreaterEqualExpression.deserialize(byteBuffer);
-      case 4:
-        return GreaterThanExpression.deserialize(byteBuffer);
-      case 5:
-        return LessEqualExpression.deserialize(byteBuffer);
-      case 6:
-        return LessThanExpression.deserialize(byteBuffer);
-      case 7:
-        return LogicAndExpression.deserialize(byteBuffer);
-      case 8:
-        return LogicOrExpression.deserialize(byteBuffer);
-      case 9:
-        return ModuloExpression.deserialize(byteBuffer);
-      case 10:
-        return MultiplicationExpression.deserialize(byteBuffer);
-      case 11:
-        return NonEqualExpression.deserialize(byteBuffer);
-      case 12:
-        return SubtractionExpression.deserialize(byteBuffer);
-      case 13:
-        return FunctionExpression.deserialize(byteBuffer);
-      case 14:
-        return LogicNotExpression.deserialize(byteBuffer);
-      case 15:
-        return NegationExpression.deserialize(byteBuffer);
-      case 16:
-        return TimeSeriesOperand.deserialize(byteBuffer);
-      case 17:
-        return ConstantOperand.deserialize(byteBuffer);
-      default:
-        throw new IllegalArgumentException("Invalid expression type: " + type);
-    }
+  public short getExpressionType() {
+    return expressionType;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/ResultColumn.java b/server/src/main/java/org/apache/iotdb/db/query/expression/ResultColumn.java
index 7dc4d570a1..c2bc314b06 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/ResultColumn.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/ResultColumn.java
@@ -87,6 +87,12 @@ public class ResultColumn {
     alias = null;
   }
 
+  public ResultColumn(ByteBuffer byteBuffer) {
+    expression = Expression.deserialize(byteBuffer);
+    alias = ReadWriteIOUtils.readString(byteBuffer);
+    dataType = TSDataType.deserializeFrom(byteBuffer);
+  }
+
   /**
    * @param prefixPaths prefix paths in the from clause
    * @param resultColumns used to collect the result columns
@@ -189,18 +195,13 @@ public class ResultColumn {
     return getResultColumnName().equals(((ResultColumn) o).getResultColumnName());
   }
 
-  public void serialize(ByteBuffer byteBuffer) {
-    expression.serialize(byteBuffer);
-    ReadWriteIOUtils.write(alias, byteBuffer);
-    dataType.serializeTo(byteBuffer);
+  public static void serialize(ResultColumn resultColumn, ByteBuffer byteBuffer) {
+    Expression.serialize(resultColumn.expression, byteBuffer);
+    ReadWriteIOUtils.write(resultColumn.alias, byteBuffer);
+    resultColumn.dataType.serializeTo(byteBuffer);
   }
 
   public static ResultColumn deserialize(ByteBuffer byteBuffer) {
-    Expression expression = ExpressionType.deserialize(byteBuffer);
-    String alias = ReadWriteIOUtils.readString(byteBuffer);
-    TSDataType tsDataType = TSDataType.deserializeFrom(byteBuffer);
-    ResultColumn resultColumn = new ResultColumn(expression, alias);
-    resultColumn.dataType = tsDataType;
-    return resultColumn;
+    return new ResultColumn(byteBuffer);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
index 32ec1e6c59..9ad079daf1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
@@ -24,7 +24,6 @@ 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.ArithmeticAdditionTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.ArithmeticBinaryTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class AdditionExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public AdditionExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected ArithmeticBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -46,18 +49,8 @@ public class AdditionExpression extends BinaryExpression {
     return "+";
   }
 
-  public static AdditionExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    AdditionExpression additionExpression =
-        new AdditionExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    additionExpression.isConstantOperandCache = isConstantOperandCache;
-    return additionExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Addition.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.ADDITION.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
index cbc6539635..d822a00801 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
@@ -58,6 +58,11 @@ public abstract class BinaryExpression extends Expression {
     this.rightExpression = rightExpression;
   }
 
+  protected BinaryExpression(ByteBuffer byteBuffer) {
+    this.leftExpression = Expression.deserialize(byteBuffer);
+    this.rightExpression = Expression.deserialize(byteBuffer);
+  }
+
   public Expression getLeftExpression() {
     return leftExpression;
   }
@@ -294,9 +299,8 @@ public abstract class BinaryExpression extends Expression {
   protected abstract String operator();
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    super.serialize(byteBuffer);
-    leftExpression.serialize(byteBuffer);
-    rightExpression.serialize(byteBuffer);
+  protected void serialize(ByteBuffer byteBuffer) {
+    Expression.serialize(leftExpression, byteBuffer);
+    Expression.serialize(rightExpression, byteBuffer);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
index b905e1f6be..e72fe7ea86 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
@@ -24,7 +24,6 @@ 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.ArithmeticBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.ArithmeticDivisionTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class DivisionExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public DivisionExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected ArithmeticBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -46,18 +49,8 @@ public class DivisionExpression extends BinaryExpression {
     return "/";
   }
 
-  public static DivisionExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    DivisionExpression divisionExpression =
-        new DivisionExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    divisionExpression.isConstantOperandCache = isConstantOperandCache;
-    return divisionExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Division.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.DIVISION.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
index f6f487dfb8..d506f15ae6 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
@@ -24,15 +24,19 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareEqualToTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
 public class EqualToExpression extends BinaryExpression {
+
   public EqualToExpression(Expression leftExpression, Expression rightExpression) {
     super(leftExpression, rightExpression);
   }
 
+  public EqualToExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -44,18 +48,8 @@ public class EqualToExpression extends BinaryExpression {
     return "=";
   }
 
-  public static EqualToExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    EqualToExpression equalToExpression =
-        new EqualToExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    equalToExpression.isConstantOperandCache = isConstantOperandCache;
-    return equalToExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.EqualTo.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.EQUAL_TO.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
index 134763f6b5..2a7944dfb1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
@@ -24,7 +24,6 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareGreaterEqualTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class GreaterEqualExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public GreaterEqualExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -46,18 +49,8 @@ public class GreaterEqualExpression extends BinaryExpression {
     return ">=";
   }
 
-  public static GreaterEqualExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    GreaterEqualExpression greaterEqualExpression =
-        new GreaterEqualExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    greaterEqualExpression.isConstantOperandCache = isConstantOperandCache;
-    return greaterEqualExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Greater_Equal.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.GREATER_EQUAL.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
index ab2d51e329..40e3c26ae0 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
@@ -24,15 +24,19 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareGreaterThanTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
 public class GreaterThanExpression extends BinaryExpression {
+
   public GreaterThanExpression(Expression leftExpression, Expression rightExpression) {
     super(leftExpression, rightExpression);
   }
 
+  public GreaterThanExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -45,18 +49,8 @@ public class GreaterThanExpression extends BinaryExpression {
     return ">";
   }
 
-  public static GreaterThanExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    GreaterThanExpression greaterThanExpression =
-        new GreaterThanExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    greaterThanExpression.isConstantOperandCache = isConstantOperandCache;
-    return greaterThanExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Greater_Than.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.GREATER_THAN.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
index c12b860e31..9fe0213afa 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
@@ -24,7 +24,6 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareLessEqualTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class LessEqualExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public LessEqualExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -45,18 +48,8 @@ public class LessEqualExpression extends BinaryExpression {
     return "<=";
   }
 
-  public static LessEqualExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    LessEqualExpression lessEqualExpression =
-        new LessEqualExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    lessEqualExpression.isConstantOperandCache = isConstantOperandCache;
-    return lessEqualExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Less_Equal.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.LESS_EQUAL.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
index a94fb180cc..e0a9e2e4f5 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
@@ -24,7 +24,6 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareLessThanTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class LessThanExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public LessThanExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -45,18 +48,8 @@ public class LessThanExpression extends BinaryExpression {
     return "<";
   }
 
-  public static LessThanExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    LessThanExpression lessThanExpression =
-        new LessThanExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    lessThanExpression.isConstantOperandCache = isConstantOperandCache;
-    return lessThanExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Less_Than.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.LESS_THAN.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
index 817c3e64b1..a35ef9cf8c 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
@@ -24,15 +24,19 @@ 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.LogicAndTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.LogicBinaryTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
 public class LogicAndExpression extends BinaryExpression {
+
   public LogicAndExpression(Expression leftExpression, Expression rightExpression) {
     super(leftExpression, rightExpression);
   }
 
+  public LogicAndExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected LogicBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -44,18 +48,8 @@ public class LogicAndExpression extends BinaryExpression {
     return "&";
   }
 
-  public static LogicAndExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    LogicAndExpression logicAndExpression =
-        new LogicAndExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    logicAndExpression.isConstantOperandCache = isConstantOperandCache;
-    return logicAndExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Logic_And.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.LOGIC_AND.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
index 9a77e3ff2c..2c031fb746 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
@@ -24,15 +24,19 @@ 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.LogicBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.LogicOrTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
 public class LogicOrExpression extends BinaryExpression {
+
   public LogicOrExpression(Expression leftExpression, Expression rightExpression) {
     super(leftExpression, rightExpression);
   }
 
+  public LogicOrExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected LogicBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -44,18 +48,8 @@ public class LogicOrExpression extends BinaryExpression {
     return "|";
   }
 
-  public static LogicOrExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    LogicOrExpression logicOrExpression =
-        new LogicOrExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    logicOrExpression.isConstantOperandCache = isConstantOperandCache;
-    return logicOrExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Logic_Or.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.LOGIC_OR.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
index 04832c0ab1..39f1b90a3f 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
@@ -24,7 +24,6 @@ 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.ArithmeticBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.ArithmeticModuloTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class ModuloExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public ModuloExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected ArithmeticBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -45,18 +48,8 @@ public class ModuloExpression extends BinaryExpression {
     return "%";
   }
 
-  public static ModuloExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    ModuloExpression moduloExpression =
-        new ModuloExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    moduloExpression.isConstantOperandCache = isConstantOperandCache;
-    return moduloExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Modulo.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.MODULO.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
index 1336382923..86a3539c10 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
@@ -24,7 +24,6 @@ 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.ArithmeticBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.ArithmeticMultiplicationTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class MultiplicationExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public MultiplicationExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected ArithmeticBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -46,18 +49,8 @@ public class MultiplicationExpression extends BinaryExpression {
     return "*";
   }
 
-  public static MultiplicationExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    MultiplicationExpression multiplicationExpression =
-        new MultiplicationExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    multiplicationExpression.isConstantOperandCache = isConstantOperandCache;
-    return multiplicationExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Multiplication.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.MULTIPLICATION.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
index ef9e5bbd15..159ff11522 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
@@ -24,7 +24,6 @@ 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.CompareBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.CompareNonEqualTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class NonEqualExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public NonEqualExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected CompareBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -45,18 +48,8 @@ public class NonEqualExpression extends BinaryExpression {
     return "!=";
   }
 
-  public static NonEqualExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    NonEqualExpression nonEqualExpression =
-        new NonEqualExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    nonEqualExpression.isConstantOperandCache = isConstantOperandCache;
-    return nonEqualExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Non_Equal.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.NON_EQUAL.getExpressionType();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
index 05194fadae..dd91f9e7d5 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
@@ -24,7 +24,6 @@ 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.ArithmeticBinaryTransformer;
 import org.apache.iotdb.db.query.udf.core.transformer.ArithmeticSubtractionTransformer;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 
@@ -34,6 +33,10 @@ public class SubtractionExpression extends BinaryExpression {
     super(leftExpression, rightExpression);
   }
 
+  public SubtractionExpression(ByteBuffer byteBuffer) {
+    super(byteBuffer);
+  }
+
   @Override
   protected ArithmeticBinaryTransformer constructTransformer(
       LayerPointReader leftParentLayerPointReader, LayerPointReader rightParentLayerPointReader) {
@@ -46,18 +49,8 @@ public class SubtractionExpression extends BinaryExpression {
     return "-";
   }
 
-  public static SubtractionExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    SubtractionExpression subtractionExpression =
-        new SubtractionExpression(
-            ExpressionType.deserialize(buffer), ExpressionType.deserialize(buffer));
-    subtractionExpression.isConstantOperandCache = isConstantOperandCache;
-    return subtractionExpression;
-  }
-
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Subtraction.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.SUBTRACTION.getExpressionType();
   }
 }
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/unary/ConstantOperand.java
index 93e0c947e5..8da3c75ee7 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/unary/ConstantOperand.java
@@ -50,9 +50,14 @@ public class ConstantOperand extends Expression {
   private final String valueString;
   private final TSDataType dataType;
 
-  public ConstantOperand(TSDataType dataType, String str) {
+  public ConstantOperand(TSDataType dataType, String valueString) {
     this.dataType = Validate.notNull(dataType);
-    this.valueString = Validate.notNull(str);
+    this.valueString = Validate.notNull(valueString);
+  }
+
+  public ConstantOperand(ByteBuffer byteBuffer) {
+    dataType = TSDataType.deserializeFrom(byteBuffer);
+    valueString = ReadWriteIOUtils.readString(byteBuffer);
   }
 
   public TSDataType getDataType() {
@@ -140,20 +145,14 @@ public class ConstantOperand extends Expression {
     return valueString;
   }
 
-  public static ConstantOperand deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    String valueStr = ReadWriteIOUtils.readString(buffer);
-    TSDataType tsDataType = TSDataType.deserializeFrom(buffer);
-    ConstantOperand constantOperand = new ConstantOperand(tsDataType, valueStr);
-    constantOperand.isConstantOperandCache = isConstantOperandCache;
-    return constantOperand;
+  @Override
+  protected short getExpressionType() {
+    return ExpressionType.CONSTANT.getExpressionType();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Constant.serialize(byteBuffer);
-    super.serialize(byteBuffer);
-    ReadWriteIOUtils.write(valueString, byteBuffer);
+  protected void serialize(ByteBuffer byteBuffer) {
     dataType.serializeTo(byteBuffer);
+    ReadWriteIOUtils.write(valueString, byteBuffer);
   }
 }
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/unary/FunctionExpression.java
index 35da48e4b4..43ff8c5162 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/unary/FunctionExpression.java
@@ -91,6 +91,7 @@ public class FunctionExpression extends Expression {
     this.functionName = functionName;
     functionAttributes = new LinkedHashMap<>();
     expressions = new ArrayList<>();
+
     isBuiltInAggregationFunctionExpression =
         SQLConstant.getNativeFunctionNames().contains(functionName.toLowerCase());
     isConstantOperandCache = true;
@@ -101,6 +102,7 @@ public class FunctionExpression extends Expression {
     this.functionName = functionName;
     this.functionAttributes = functionAttributes;
     this.expressions = expressions;
+
     isBuiltInAggregationFunctionExpression =
         SQLConstant.getNativeFunctionNames().contains(functionName.toLowerCase());
     isConstantOperandCache = expressions.stream().anyMatch(Expression::isConstantOperand);
@@ -112,6 +114,26 @@ public class FunctionExpression extends Expression {
                         || v.isBuiltInAggregationFunctionExpression());
   }
 
+  public FunctionExpression(ByteBuffer byteBuffer) {
+    functionName = ReadWriteIOUtils.readString(byteBuffer);
+    functionAttributes = ReadWriteIOUtils.readMap(byteBuffer);
+    int expressionSize = ReadWriteIOUtils.readInt(byteBuffer);
+    List<Expression> expressions = new ArrayList<>();
+    for (int i = 0; i < expressionSize; i++) {
+      expressions.add(Expression.deserialize(byteBuffer));
+    }
+
+    isBuiltInAggregationFunctionExpression =
+        SQLConstant.getNativeFunctionNames().contains(functionName);
+    isConstantOperandCache = expressions.stream().anyMatch(Expression::isConstantOperand);
+    isUserDefinedAggregationFunctionExpression =
+        expressions.stream()
+            .anyMatch(
+                v ->
+                    v.isUserDefinedAggregationFunctionExpression()
+                        || v.isBuiltInAggregationFunctionExpression());
+  }
+
   @Override
   public boolean isBuiltInAggregationFunctionExpression() {
     return isBuiltInAggregationFunctionExpression;
@@ -435,31 +457,18 @@ public class FunctionExpression extends Expression {
     return parametersString;
   }
 
-  public static FunctionExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    String functionName = ReadWriteIOUtils.readString(buffer);
-    Map<String, String> functionAttributes = ReadWriteIOUtils.readMap(buffer);
-    int expressionSize = ReadWriteIOUtils.readInt(buffer);
-    List<Expression> expressions = new ArrayList<>();
-    for (int i = 0; i < expressionSize; i++) {
-      expressions.add(ExpressionType.deserialize(buffer));
-    }
-
-    FunctionExpression functionExpression =
-        new FunctionExpression(functionName, functionAttributes, expressions);
-    functionExpression.isConstantOperandCache = isConstantOperandCache;
-    return functionExpression;
+  @Override
+  protected short getExpressionType() {
+    return ExpressionType.FUNCTION.getExpressionType();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Function.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected void serialize(ByteBuffer byteBuffer) {
     ReadWriteIOUtils.write(functionName, byteBuffer);
     ReadWriteIOUtils.write(functionAttributes, byteBuffer);
     ReadWriteIOUtils.write(expressions.size(), byteBuffer);
     for (Expression expression : expressions) {
-      expression.serialize(byteBuffer);
+      Expression.serialize(expression, 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 d72aed288b..9c36b3a810 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
@@ -38,7 +38,6 @@ import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReference
 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 org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -50,12 +49,17 @@ import java.util.Map;
 import java.util.Set;
 
 public class LogicNotExpression extends Expression {
-  protected Expression expression;
+
+  private final Expression expression;
 
   public LogicNotExpression(Expression expression) {
     this.expression = expression;
   }
 
+  public LogicNotExpression(ByteBuffer byteBuffer) {
+    expression = Expression.deserialize(byteBuffer);
+  }
+
   public Expression getExpression() {
     return expression;
   }
@@ -197,18 +201,13 @@ public class LogicNotExpression extends Expression {
     }
   }
 
-  public static LogicNotExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    Expression expression = ExpressionType.deserialize(buffer);
-    LogicNotExpression logicNotExpression = new LogicNotExpression(expression);
-    logicNotExpression.isConstantOperandCache = isConstantOperandCache;
-    return logicNotExpression;
+  @Override
+  protected short getExpressionType() {
+    return ExpressionType.LOGIC_NOT.getExpressionType();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Logic_Not.serialize(byteBuffer);
-    super.serialize(byteBuffer);
-    expression.serialize(byteBuffer);
+  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 5eea89d07a..28ed84613e 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
@@ -38,7 +38,6 @@ import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReference
 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 org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -51,12 +50,16 @@ import java.util.Set;
 
 public class NegationExpression extends Expression {
 
-  protected Expression expression;
+  private final Expression expression;
 
   public NegationExpression(Expression expression) {
     this.expression = expression;
   }
 
+  public NegationExpression(ByteBuffer byteBuffer) {
+    expression = Expression.deserialize(byteBuffer);
+  }
+
   public Expression getExpression() {
     return expression;
   }
@@ -198,18 +201,13 @@ public class NegationExpression extends Expression {
     }
   }
 
-  public static NegationExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    Expression expression = ExpressionType.deserialize(buffer);
-    NegationExpression negationExpression = new NegationExpression(expression);
-    negationExpression.isConstantOperandCache = isConstantOperandCache;
-    return negationExpression;
+  @Override
+  protected short getExpressionType() {
+    return ExpressionType.NEGATION.getExpressionType();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Negation.serialize(byteBuffer);
-    super.serialize(byteBuffer);
-    expression.serialize(byteBuffer);
+  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/RegularExpression.java
similarity index 63%
copy from server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
copy to server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
index 5eea89d07a..0ce8f8589f 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/RegularExpression.java
@@ -33,13 +33,11 @@ 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.udf.core.transformer.ArithmeticNegationTransformer;
-import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 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;
@@ -48,38 +46,30 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
-public class NegationExpression extends Expression {
+public class RegularExpression extends Expression {
 
-  protected Expression expression;
+  private final Expression expression;
+  private final String patternString;
+  private final Pattern pattern;
 
-  public NegationExpression(Expression expression) {
+  public RegularExpression(Expression expression, String patternString) {
     this.expression = expression;
+    this.patternString = patternString;
+    pattern = Pattern.compile(patternString);
   }
 
-  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();
+  public RegularExpression(Expression expression, String patternString, Pattern pattern) {
+    this.expression = expression;
+    this.patternString = patternString;
+    this.pattern = pattern;
   }
 
-  @Override
-  public boolean isUserDefinedAggregationFunctionExpression() {
-    return expression.isUserDefinedAggregationFunctionExpression()
-        || expression.isBuiltInAggregationFunctionExpression();
+  public RegularExpression(ByteBuffer byteBuffer) {
+    expression = Expression.deserialize(byteBuffer);
+    patternString = ReadWriteIOUtils.readString(byteBuffer);
+    pattern = Pattern.compile(Validate.notNull(patternString));
   }
 
   @Override
@@ -90,7 +80,7 @@ public class NegationExpression extends Expression {
     List<Expression> resultExpressionsForRecursion = new ArrayList<>();
     expression.concat(prefixPaths, resultExpressionsForRecursion, patternTree);
     for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
+      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
     }
   }
 
@@ -99,7 +89,7 @@ public class NegationExpression extends Expression {
     List<Expression> resultExpressionsForRecursion = new ArrayList<>();
     expression.concat(prefixPaths, resultExpressionsForRecursion);
     for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
+      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
     }
   }
 
@@ -109,7 +99,7 @@ public class NegationExpression extends Expression {
     List<Expression> resultExpressionsForRecursion = new ArrayList<>();
     expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
     for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
+      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
     }
   }
 
@@ -121,7 +111,7 @@ public class NegationExpression extends Expression {
     List<Expression> resultExpressionsForRecursion = new ArrayList<>();
     expression.removeWildcards(wildcardsRemover, resultExpressionsForRecursion);
     for (Expression resultExpression : resultExpressionsForRecursion) {
-      resultExpressions.add(new NegationExpression(resultExpression));
+      resultExpressions.add(new RegularExpression(resultExpression, patternString, pattern));
     }
   }
 
@@ -157,59 +147,45 @@ public class NegationExpression extends Expression {
       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));
-    }
+    // TODO
+    throw new RuntimeException();
+  }
 
-    return expressionIntermediateLayerMap.get(this);
+  @Override
+  protected boolean isConstantOperandInternal() {
+    return expression.isConstantOperand();
   }
 
   @Override
-  public String getExpressionStringInternal() {
-    if (expression instanceof FunctionExpression
-        || expression instanceof ConstantOperand
-        || expression instanceof TimeSeriesOperand) {
-      return "-" + expression.toString();
-    } else {
-      return "-(" + expression.toString() + ")";
-    }
+  public List<Expression> getExpressions() {
+    return Collections.singletonList(expression);
   }
 
-  public static NegationExpression deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    Expression expression = ExpressionType.deserialize(buffer);
-    NegationExpression negationExpression = new NegationExpression(expression);
-    negationExpression.isConstantOperandCache = isConstantOperandCache;
-    return negationExpression;
+  @Override
+  protected String getExpressionStringInternal() {
+    // TODO
+    throw new RuntimeException();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.Negation.serialize(byteBuffer);
-    super.serialize(byteBuffer);
-    expression.serialize(byteBuffer);
+  protected short getExpressionType() {
+    return ExpressionType.REGULAR.getExpressionType();
+  }
+
+  @Override
+  protected void serialize(ByteBuffer byteBuffer) {
+    Expression.serialize(expression, 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/TimeSeriesOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
index 2585107554..e8cf2566d1 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/unary/TimeSeriesOperand.java
@@ -25,7 +25,6 @@ import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
 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.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.query.expression.Expression;
@@ -39,7 +38,6 @@ import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnMultiReferenceI
 import org.apache.iotdb.db.query.udf.core.layer.SingleInputColumnSingleReferenceIntermediateLayer;
 import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
 import java.time.ZoneId;
@@ -52,12 +50,14 @@ public class TimeSeriesOperand extends Expression {
 
   private PartialPath path;
 
-  private InputLocation inputLocation;
-
   public TimeSeriesOperand(PartialPath path) {
     this.path = path;
   }
 
+  public TimeSeriesOperand(ByteBuffer byteBuffer) {
+    path = (PartialPath) PathDeserializeUtil.deserialize(byteBuffer);
+  }
+
   public PartialPath getPath() {
     return path;
   }
@@ -166,18 +166,13 @@ public class TimeSeriesOperand extends Expression {
     return path.isMeasurementAliasExists() ? path.getFullPathWithAlias() : path.getFullPath();
   }
 
-  public static TimeSeriesOperand deserialize(ByteBuffer buffer) {
-    boolean isConstantOperandCache = ReadWriteIOUtils.readBool(buffer);
-    PartialPath partialPath = (PartialPath) PathDeserializeUtil.deserialize(buffer);
-    TimeSeriesOperand timeSeriesOperand = new TimeSeriesOperand(partialPath);
-    timeSeriesOperand.isConstantOperandCache = isConstantOperandCache;
-    return timeSeriesOperand;
+  @Override
+  protected short getExpressionType() {
+    return ExpressionType.TIME_SERIES.getExpressionType();
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    ExpressionType.TimeSeries.serialize(byteBuffer);
-    super.serialize(byteBuffer);
+  protected void serialize(ByteBuffer byteBuffer) {
     path.serialize(byteBuffer);
   }
 }