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

caogaofei pushed a commit to branch beyyes/template_value_filter
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/beyyes/template_value_filter 
by this push:
     new 84729c1bcc7 try to fit ColumnTransformer
84729c1bcc7 is described below

commit 84729c1bcc78a5620b20ec54ddd497bf4fba5092
Author: Beyyes <[email protected]>
AuthorDate: Wed Jan 3 11:56:01 2024 +0800

    try to fit ColumnTransformer
---
 .../plan/analyze/ExpressionTypeAnalyzer.java       |  10 ++
 .../db/queryengine/plan/analyze/TemplatedInfo.java | 101 +++++++++++++-
 .../queryengine/plan/execution/QueryExecution.java |  13 +-
 .../visitor/ColumnTransformerVisitor.java          |   8 +-
 .../plan/planner/LocalExecutionPlanner.java        |   2 +
 .../plan/planner/OperatorTreeGenerator.java        | 155 ++++++++++++---------
 .../planner/distribution/DistributionPlanner.java  |  20 +++
 .../dag/column/CaseWhenThenColumnTransformer.java  |   5 +
 .../transformation/dag/column/ColumnCache.java     |   8 ++
 .../dag/column/ColumnTransformer.java              |  10 ++
 .../ArithmeticAdditionColumnTransformer.java       |   6 +
 .../ArithmeticDivisionColumnTransformer.java       |   6 +
 .../binary/ArithmeticModuloColumnTransformer.java  |   6 +
 .../ArithmeticMultiplicationColumnTransformer.java |   6 +
 .../ArithmeticSubtractionColumnTransformer.java    |   6 +
 .../binary/CompareEqualToColumnTransformer.java    |   6 +
 .../CompareGreaterEqualColumnTransformer.java      |   6 +
 .../CompareGreaterThanColumnTransformer.java       |   9 ++
 .../binary/CompareLessEqualColumnTransformer.java  |   6 +
 .../binary/CompareLessThanColumnTransformer.java   |   6 +
 .../binary/CompareNonEqualColumnTransformer.java   |   6 +
 .../column/binary/LogicAndColumnTransformer.java   |   9 ++
 .../column/binary/LogicOrColumnTransformer.java    |   6 +
 .../dag/column/leaf/ConstantColumnTransformer.java |  15 ++
 .../dag/column/leaf/IdentityColumnTransformer.java |  15 ++
 .../dag/column/leaf/LeafColumnTransformer.java     |   2 +
 .../dag/column/leaf/NullColumnTransformer.java     |  15 ++
 .../dag/column/leaf/TimeColumnTransformer.java     |  15 ++
 .../column/multi/MappableUDFColumnTransformer.java |   5 +
 .../column/ternary/BetweenColumnTransformer.java   |  10 ++
 .../unary/ArithmeticNegationColumnTransformer.java |   6 +
 .../dag/column/unary/InColumnTransformer.java      |  12 ++
 .../dag/column/unary/IsNullColumnTransformer.java  |   5 +
 .../column/unary/LogicNotColumnTransformer.java    |   5 +
 .../dag/column/unary/RegularColumnTransformer.java |   5 +
 .../scalar/CastFunctionColumnTransformer.java      |   5 +
 .../scalar/DiffFunctionColumnTransformer.java      |   6 +
 .../scalar/ReplaceFunctionColumnTransformer.java   |   5 +
 .../scalar/RoundFunctionColumnTransformer.java     |   6 +
 .../scalar/SubStringFunctionColumnTransformer.java |   6 +
 40 files changed, 480 insertions(+), 74 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java
index 68a96b29bf8..bedea25100e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java
@@ -88,6 +88,16 @@ public class ExpressionTypeAnalyzer {
     types.putAll(analyzer.getExpressionTypes());
   }
 
+  public static void analyzeExpression(
+      Map<NodeRef<Expression>, TSDataType> types,
+      Expression expression,
+      Map<String, IMeasurementSchema> schemaMap) {
+    ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
+    analyzer.analyze(expression, schemaMap);
+
+    types.putAll(analyzer.getExpressionTypes());
+  }
+
   private static void addExpressionTypes(Analysis analysis, 
ExpressionTypeAnalyzer analyzer) {
     analysis.addTypes(analyzer.getExpressionTypes());
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedInfo.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedInfo.java
index 48da26c1f37..56d1d6b7440 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedInfo.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedInfo.java
@@ -19,9 +19,15 @@
 
 package org.apache.iotdb.db.queryengine.plan.analyze;
 
+import org.apache.iotdb.commons.path.MeasurementPath;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.queryengine.common.NodeRef;
 import org.apache.iotdb.db.queryengine.plan.expression.Expression;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.LeafColumnTransformer;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
@@ -39,6 +45,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static 
org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand.TIMESTAMP_EXPRESSION_STRING;
 
@@ -57,14 +64,82 @@ public class TemplatedInfo {
   private List<Integer> deviceToMeasurementIndexes;
   private final long offsetValue;
   private long limitValue;
-  // these variables below are use in value filter condition
+
+  
/////////////////////////////////////////////////////////////////////////////////////////////////
+  // These variables below are use in value filter condition
+  
/////////////////////////////////////////////////////////////////////////////////////////////////
   private final Expression predicate;
   private ZoneId zoneId;
   private boolean keepNull;
-  // not serialize
+  // this variable is no need to serialize
   private Map<String, IMeasurementSchema> schemaMap;
-  // not serialize
+  // this variable is no need to serialize
   private Map<String, List<InputLocation>> layoutMap;
+  // this variable is no need to serialize
+  private Expression[] projectExpressions;
+
+  public Map<NodeRef<Expression>, TSDataType> expressionTypes;
+
+  private ColumnInfo columnInfo;
+
+  public static class ColumnInfo {
+    public List<LeafColumnTransformer> filterLeafColumnTransformerList;
+    public ColumnTransformer filterOutputTransformer;
+    public List<ColumnTransformer> commonTransformerList;
+    public List<LeafColumnTransformer> projectLeafColumnTransformerList;
+    public List<ColumnTransformer> projectOutputTransformerList;
+
+    public ColumnInfo(
+        List<LeafColumnTransformer> filterLeafColumnTransformerList,
+        ColumnTransformer filterOutputTransformer,
+        List<ColumnTransformer> commonTransformerList,
+        List<LeafColumnTransformer> projectLeafColumnTransformerList,
+        List<ColumnTransformer> projectOutputTransformerList) {
+
+      this.filterLeafColumnTransformerList = filterLeafColumnTransformerList;
+      this.filterOutputTransformer = filterOutputTransformer;
+      this.commonTransformerList = commonTransformerList;
+      this.projectLeafColumnTransformerList = projectLeafColumnTransformerList;
+      this.projectOutputTransformerList = projectOutputTransformerList;
+    }
+  }
+
+  public synchronized void setColumn(
+      List<LeafColumnTransformer> filterLeafColumnTransformerList,
+      ColumnTransformer filterOutputTransformer,
+      List<ColumnTransformer> commonTransformerList,
+      List<LeafColumnTransformer> projectLeafColumnTransformerList,
+      List<ColumnTransformer> projectOutputTransformerList) {
+
+    this.columnInfo =
+        new ColumnInfo(
+            filterLeafColumnTransformerList,
+            filterOutputTransformer,
+            commonTransformerList,
+            projectLeafColumnTransformerList,
+            projectOutputTransformerList);
+  }
+
+  public synchronized ColumnInfo getColumnInfo() {
+    if (this.columnInfo == null) {
+      return null;
+    }
+
+    return new ColumnInfo(
+        this.columnInfo.filterLeafColumnTransformerList.stream()
+            .map(LeafColumnTransformer::cloneLeaf)
+            .collect(Collectors.toList()),
+        this.columnInfo.filterOutputTransformer.cloneObject(),
+        this.columnInfo.commonTransformerList.stream()
+            .map(ColumnTransformer::cloneObject)
+            .collect(Collectors.toList()),
+        this.columnInfo.projectLeafColumnTransformerList.stream()
+            .map(LeafColumnTransformer::cloneLeaf)
+            .collect(Collectors.toList()),
+        this.columnInfo.projectOutputTransformerList.stream()
+            .map(ColumnTransformer::cloneObject)
+            .collect(Collectors.toList()));
+  }
 
   public TemplatedInfo(
       List<String> measurementList,
@@ -96,9 +171,25 @@ public class TemplatedInfo {
       this.zoneId = zoneId;
       this.schemaMap = schemaMap;
       this.layoutMap = layoutMap;
+
+      projectExpressions = new Expression[measurementList.size()];
+      for (int i = 0; i < measurementList.size(); i++) {
+        projectExpressions[i] =
+            new TimeSeriesOperand(
+                new MeasurementPath(
+                    new PartialPath(new String[] {measurementList.get(i)}), 
schemaList.get(i)));
+      }
+
+      expressionTypes = new HashMap<>();
+      ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, predicate, 
schemaMap);
+      for (Expression projectExpression : projectExpressions) {
+        ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, 
projectExpression, schemaMap);
+      }
     }
   }
 
+  private void init() {}
+
   public void setMeasurementList(List<String> measurementList) {
     this.measurementList = measurementList;
   }
@@ -195,6 +286,10 @@ public class TemplatedInfo {
     return this.layoutMap;
   }
 
+  public Expression[] getProjectExpressions() {
+    return this.projectExpressions;
+  }
+
   public static Map<String, List<InputLocation>> makeLayout(List<String> 
measurementList) {
     Map<String, List<InputLocation>> outputMappings = new LinkedHashMap<>();
     int tsBlockIndex = 0;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
index a2678200780..f8980de0772 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
@@ -217,10 +217,19 @@ public class QueryExecution implements IQueryExecution {
       return;
     }
 
+    long currentTime = System.nanoTime();
     // check timeout for query first
     checkTimeOutForQuery();
     doLogicalPlan();
+    logger.warn(
+        "============== coordinator doLogicalPlan: {}ms", (System.nanoTime() - 
currentTime) / 1e6);
+
+    currentTime = System.nanoTime();
     doDistributedPlan();
+    logger.warn(
+        "============== coordinator doDistributedPlan: {}ms",
+        (System.nanoTime() - currentTime) / 1e6);
+    currentTime = System.nanoTime();
 
     // update timeout after finishing plan stage
     context.setTimeOut(
@@ -232,7 +241,8 @@ public class QueryExecution implements IQueryExecution {
     }
     PERFORMANCE_OVERVIEW_METRICS.recordPlanCost(System.nanoTime() - startTime);
     schedule();
-
+    logger.warn(
+        "============== coordinator schedule: {}ms", (System.nanoTime() - 
currentTime) / 1e6);
     // set partial insert error message
     // When some columns in one insert failed, other column will continue 
executing insertion.
     // The error message should be return to client, therefore we need to set 
it after the insertion
@@ -240,6 +250,7 @@ public class QueryExecution implements IQueryExecution {
     if (context.getQueryType() == QueryType.WRITE && analysis.isFailed()) {
       stateMachine.transitionToFailed(analysis.getFailStatus());
     }
+    logger.warn("============== coordinator fe time: {}ms", (System.nanoTime() 
- startTime) / 1e6);
   }
 
   private void checkTimeOutForQuery() {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java
index f867e7b5779..bf862a23dc8 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java
@@ -564,7 +564,13 @@ public class ColumnTransformerVisitor
 
     public TSDataType getType(Expression expression) {
       if (typeProvider != null) {
-        return typeProvider.getType(expression.getOutputSymbol());
+        //        System.out.println(
+        //            expression.getOutputSymbol()
+        //                + "  --- "
+        //                +
+        // 
typeProvider.getTemplatedInfo().expressionTypes.get(NodeRef.of(expression)));
+        //        return typeProvider.getType(expression.getOutputSymbol());
+        return 
typeProvider.getTemplatedInfo().expressionTypes.get(NodeRef.of(expression));
       }
       return expressionTypes.get(NodeRef.of(expression));
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java
index d4d51195607..2154c415513 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java
@@ -69,7 +69,9 @@ public class LocalExecutionPlanner {
 
     // Generate pipelines, return the last pipeline data structure
     // TODO Replace operator with operatorFactory to build multiple driver for 
one pipeline
+    long startTime = System.currentTimeMillis();
     Operator root = plan.accept(new OperatorTreeGenerator(), context);
+    LOGGER.warn("----- LocalExecutionPlanner plan {}ms", 
System.currentTimeMillis() - startTime);
 
     // check whether current free memory is enough to execute current query
     long estimatedMemorySize = checkMemory(root, 
instanceContext.getStateMachine());
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
index ec83015ba0f..2ab525bad2b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
@@ -139,6 +139,7 @@ import 
org.apache.iotdb.db.queryengine.execution.operator.window.WindowParameter
 import org.apache.iotdb.db.queryengine.execution.operator.window.WindowType;
 import org.apache.iotdb.db.queryengine.plan.Coordinator;
 import org.apache.iotdb.db.queryengine.plan.analyze.ExpressionTypeAnalyzer;
+import org.apache.iotdb.db.queryengine.plan.analyze.TemplatedInfo;
 import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider;
 import 
org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.DataNodeSchemaCache;
 import org.apache.iotdb.db.queryengine.plan.expression.Expression;
@@ -237,7 +238,6 @@ import 
org.apache.iotdb.tsfile.read.filter.operator.TimeFilterOperators.TimeGtEq
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.utils.TimeDuration;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -1325,18 +1325,9 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
       throw new UnsupportedOperationException("Filter can not contain 
Non-Mappable UDF");
     }
 
-    List<String> measurementList = 
typeProvider.getTemplatedInfo().getMeasurementList();
-    List<IMeasurementSchema> schemaList = 
typeProvider.getTemplatedInfo().getSchemaList();
-    Expression[] projectExpressions = new Expression[measurementList.size()];
-    for (int i = 0; i < measurementList.size(); i++) {
-      projectExpressions[i] =
-          new TimeSeriesOperand(
-              new MeasurementPath(
-                  new PartialPath(new String[] {measurementList.get(i)}), 
schemaList.get(i)));
-    }
+    Expression[] projectExpressions = 
typeProvider.getTemplatedInfo().getProjectExpressions();
     final Operator inputOperator = generateOnlyChildOperator(node, context);
     final List<TSDataType> inputDataTypes = 
typeProvider.getTemplatedInfo().getDataTypes();
-    final List<TSDataType> filterOutputDataTypes = new 
ArrayList<>(inputDataTypes);
     final OperatorContext operatorContext =
         context
             .getDriverContext()
@@ -1357,77 +1348,103 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
     UDTFContext filterContext = new UDTFContext(node.getZoneId());
     filterContext.constructUdfExecutors(new Expression[] {filterExpression});
 
-    // records LeafColumnTransformer of filter
-    List<LeafColumnTransformer> filterLeafColumnTransformerList = new 
ArrayList<>();
-
-    // records common ColumnTransformer between filter and project expressions
-    List<ColumnTransformer> commonTransformerList = new ArrayList<>();
-
-    // records LeafColumnTransformer of project expressions
-    List<LeafColumnTransformer> projectLeafColumnTransformerList = new 
ArrayList<>();
-
-    // records subexpression -> ColumnTransformer for filter
-    Map<Expression, ColumnTransformer> filterExpressionColumnTransformerMap = 
new HashMap<>();
-
-    ColumnTransformerVisitor visitor = new ColumnTransformerVisitor();
-
-    ColumnTransformerVisitor.ColumnTransformerVisitorContext 
filterColumnTransformerContext =
-        new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
-            filterContext,
-            expressionTypes,
-            filterLeafColumnTransformerList,
-            inputLocations,
-            filterExpressionColumnTransformerMap,
-            ImmutableMap.of(),
-            ImmutableList.of(),
-            ImmutableList.of(),
-            0,
-            context.getTypeProvider());
+    Operator filter = null;
+    if (typeProvider.getTemplatedInfo().getColumnInfo() != null) {
+      TemplatedInfo.ColumnInfo columnInfo = 
typeProvider.getTemplatedInfo().getColumnInfo();
+      filter =
+          new FilterAndProjectOperator(
+              operatorContext,
+              inputOperator,
+              inputDataTypes,
+              columnInfo.filterLeafColumnTransformerList,
+              columnInfo.filterOutputTransformer,
+              columnInfo.commonTransformerList,
+              columnInfo.projectLeafColumnTransformerList,
+              columnInfo.projectOutputTransformerList,
+              hasNonMappableUdf,
+              true);
+    } else {
+      // records LeafColumnTransformer of filter
+      List<LeafColumnTransformer> filterLeafColumnTransformerList = new 
ArrayList<>();
 
-    ColumnTransformer filterOutputTransformer =
-        visitor.process(filterExpression, filterColumnTransformerContext);
+      // records common ColumnTransformer between filter and project 
expressions
+      List<ColumnTransformer> commonTransformerList = new ArrayList<>();
 
-    List<ColumnTransformer> projectOutputTransformerList = new ArrayList<>();
+      // records LeafColumnTransformer of project expressions
+      List<LeafColumnTransformer> projectLeafColumnTransformerList = new 
ArrayList<>();
 
-    Map<Expression, ColumnTransformer> projectExpressionColumnTransformerMap = 
new HashMap<>();
+      // records subexpression -> ColumnTransformer for filter
+      Map<Expression, ColumnTransformer> filterExpressionColumnTransformerMap 
= new HashMap<>();
 
-    // init project transformer when project expressions are all mappable
-    if (!hasNonMappableUdf) {
-      // init project UDTFContext
-      UDTFContext projectContext = new UDTFContext(node.getZoneId());
-      projectContext.constructUdfExecutors(projectExpressions);
+      ColumnTransformerVisitor visitor = new ColumnTransformerVisitor();
 
-      ColumnTransformerVisitor.ColumnTransformerVisitorContext 
projectColumnTransformerContext =
+      ColumnTransformerVisitor.ColumnTransformerVisitorContext 
filterColumnTransformerContext =
           new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
-              projectContext,
+              filterContext,
               expressionTypes,
-              projectLeafColumnTransformerList,
+              filterLeafColumnTransformerList,
               inputLocations,
-              projectExpressionColumnTransformerMap,
               filterExpressionColumnTransformerMap,
-              commonTransformerList,
-              filterOutputDataTypes,
-              inputLocations.size() - 1,
+              ImmutableMap.of(),
+              ImmutableList.of(),
+              ImmutableList.of(),
+              0,
               context.getTypeProvider());
 
-      for (Expression expression : projectExpressions) {
-        projectOutputTransformerList.add(
-            visitor.process(expression, projectColumnTransformerContext));
+      ColumnTransformer filterOutputTransformer =
+          visitor.process(filterExpression, filterColumnTransformerContext);
+
+      List<ColumnTransformer> projectOutputTransformerList = new ArrayList<>();
+
+      Map<Expression, ColumnTransformer> projectExpressionColumnTransformerMap 
= new HashMap<>();
+
+      // init project transformer when project expressions are all mappable
+      if (!hasNonMappableUdf) {
+        // init project UDTFContext
+        UDTFContext projectContext = new UDTFContext(node.getZoneId());
+        projectContext.constructUdfExecutors(projectExpressions);
+
+        ColumnTransformerVisitor.ColumnTransformerVisitorContext 
projectColumnTransformerContext =
+            new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
+                projectContext,
+                expressionTypes,
+                projectLeafColumnTransformerList,
+                inputLocations,
+                projectExpressionColumnTransformerMap,
+                filterExpressionColumnTransformerMap,
+                commonTransformerList,
+                inputDataTypes,
+                inputLocations.size() - 1,
+                context.getTypeProvider());
+
+        for (Expression expression : projectExpressions) {
+          projectOutputTransformerList.add(
+              visitor.process(expression, projectColumnTransformerContext));
+        }
       }
-    }
 
-    Operator filter =
-        new FilterAndProjectOperator(
-            operatorContext,
-            inputOperator,
-            filterOutputDataTypes,
-            filterLeafColumnTransformerList,
-            filterOutputTransformer,
-            commonTransformerList,
-            projectLeafColumnTransformerList,
-            projectOutputTransformerList,
-            hasNonMappableUdf,
-            true);
+      typeProvider
+          .getTemplatedInfo()
+          .setColumn(
+              filterLeafColumnTransformerList,
+              filterOutputTransformer,
+              commonTransformerList,
+              projectLeafColumnTransformerList,
+              projectOutputTransformerList);
+
+      filter =
+          new FilterAndProjectOperator(
+              operatorContext,
+              inputOperator,
+              inputDataTypes,
+              filterLeafColumnTransformerList,
+              filterOutputTransformer,
+              commonTransformerList,
+              projectLeafColumnTransformerList,
+              projectOutputTransformerList,
+              hasNonMappableUdf,
+              true);
+    }
 
     // Project expressions don't contain Non-Mappable UDF, TransformOperator 
is not needed
     if (!hasNonMappableUdf) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/DistributionPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/DistributionPlanner.java
index a0ba04cba5f..f3e8460f544 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/DistributionPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/DistributionPlanner.java
@@ -44,6 +44,8 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.component.OrderByComponent
 import org.apache.iotdb.db.queryengine.plan.statement.crud.QueryStatement;
 
 import org.apache.commons.lang3.Validate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -191,8 +193,14 @@ public class DistributionPlanner {
     return fragmentBuilder.splitToSubPlan(root);
   }
 
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(DistributionPlanner.class);
+
   public DistributedQueryPlan planFragments() {
+    long startTime = System.currentTimeMillis();
     PlanNode rootAfterRewrite = rewriteSource();
+    LOGGER.warn(
+        "----- doDistributePlan rewriteSource {}ms", 
System.currentTimeMillis() - startTime);
+    startTime = System.currentTimeMillis();
 
     PlanNode rootWithExchange = addExchangeNode(rootAfterRewrite);
     PlanNode optimizedRootWithExchange = optimize(rootWithExchange);
@@ -201,10 +209,22 @@ public class DistributionPlanner {
           .getRespDatasetHeader()
           
.setColumnToTsBlockIndexMap(optimizedRootWithExchange.getOutputColumnNames());
     }
+    LOGGER.warn(
+        "----- doDistributePlan addExchangeNode {}ms", 
System.currentTimeMillis() - startTime);
+    startTime = System.currentTimeMillis();
+
     SubPlan subPlan = splitFragment(optimizedRootWithExchange);
     // Mark the root Fragment of root SubPlan as `root`
     subPlan.getPlanFragment().setRoot(true);
+    LOGGER.warn(
+        "----- doDistributePlan splitFragment {}ms", 
System.currentTimeMillis() - startTime);
+    startTime = System.currentTimeMillis();
+
     List<FragmentInstance> fragmentInstances = planFragmentInstances(subPlan);
+    LOGGER.warn(
+        "----- doDistributePlan planFragmentInstances {}ms",
+        System.currentTimeMillis() - startTime);
+
     // Only execute this step for READ operation
     if (context.getQueryType() == QueryType.READ) {
       setSinkForRootInstance(subPlan, fragmentInstances);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/CaseWhenThenColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/CaseWhenThenColumnTransformer.java
index bb359f5252c..73051f05d29 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/CaseWhenThenColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/CaseWhenThenColumnTransformer.java
@@ -129,4 +129,9 @@ public class CaseWhenThenColumnTransformer extends 
ColumnTransformer {
   protected void checkType() {
     // do nothing
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new CaseWhenThenColumnTransformer(returnType, null, null, null);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnCache.java
index b7227720dd5..82425bebd1f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnCache.java
@@ -20,11 +20,14 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column;
 
 import org.apache.iotdb.tsfile.read.common.block.column.Column;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
 public class ColumnCache {
 
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(ColumnCache.class);
   private int referenceCount;
   private Column column;
 
@@ -34,6 +37,11 @@ public class ColumnCache {
 
   public Column getColumn() {
     referenceCount--;
+    if (column != null) {
+      LOGGER.warn("referenceCount: {}, column: {}, {}", referenceCount, 
column, column.getTsPrimitiveType(0));
+    } else {
+      LOGGER.warn("referenceCount: {}, column is null!", referenceCount);
+    }
     checkArgument(referenceCount >= 0, "Exceed max call times of getColumn");
     Column res = this.column;
     // set column to null for memory control
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnTransformer.java
index c6feea24bc7..c85fa381984 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ColumnTransformer.java
@@ -107,6 +107,16 @@ public abstract class ColumnTransformer {
 
   protected abstract void checkType();
 
+  public int getReferenceCount() {
+    return this.referenceCount;
+  }
+
+  public void setReferenceCount(int referenceCount) {
+    this.referenceCount = referenceCount;
+  }
+
+  public abstract ColumnTransformer cloneObject();
+
   public void close() {
     // do nothing
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticAdditionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticAdditionColumnTransformer.java
index 36b66710daf..17506284a39 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticAdditionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticAdditionColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class ArithmeticAdditionColumnTransformer extends 
ArithmeticBinaryColumnTransformer {
@@ -32,4 +33,9 @@ public class ArithmeticAdditionColumnTransformer extends 
ArithmeticBinaryColumnT
   protected double transform(double d1, double d2) {
     return d1 + d2;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticDivisionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticDivisionColumnTransformer.java
index e62cc78c5a2..a2de50bd7c4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticDivisionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticDivisionColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class ArithmeticDivisionColumnTransformer extends 
ArithmeticBinaryColumnTransformer {
@@ -32,4 +33,9 @@ public class ArithmeticDivisionColumnTransformer extends 
ArithmeticBinaryColumnT
   protected double transform(double d1, double d2) {
     return d1 / d2;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticModuloColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticModuloColumnTransformer.java
index 008d99664e4..40ff060e588 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticModuloColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticModuloColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class ArithmeticModuloColumnTransformer extends 
ArithmeticBinaryColumnTransformer {
@@ -32,4 +33,9 @@ public class ArithmeticModuloColumnTransformer extends 
ArithmeticBinaryColumnTra
   protected double transform(double d1, double d2) {
     return d1 % d2;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticMultiplicationColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticMultiplicationColumnTransformer.java
index fa0e34440e8..dfd2aaaf044 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticMultiplicationColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticMultiplicationColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class ArithmeticMultiplicationColumnTransformer extends 
ArithmeticBinaryColumnTransformer {
@@ -33,4 +34,9 @@ public class ArithmeticMultiplicationColumnTransformer 
extends ArithmeticBinaryC
   protected double transform(double d1, double d2) {
     return d1 * d2;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticSubtractionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticSubtractionColumnTransformer.java
index 9eff2a518de..46badb963fc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticSubtractionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticSubtractionColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class ArithmeticSubtractionColumnTransformer extends 
ArithmeticBinaryColumnTransformer {
@@ -32,4 +33,9 @@ public class ArithmeticSubtractionColumnTransformer extends 
ArithmeticBinaryColu
   protected double transform(double d1, double d2) {
     return d1 - d2;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareEqualToColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareEqualToColumnTransformer.java
index 9b4db7d6803..49e4857987f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareEqualToColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareEqualToColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class CompareEqualToColumnTransformer extends 
CompareBinaryColumnTransformer {
@@ -44,4 +45,9 @@ public class CompareEqualToColumnTransformer extends 
CompareBinaryColumnTransfor
   protected boolean transform(int flag) {
     return flag == 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterEqualColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterEqualColumnTransformer.java
index 672d946fb2e..00e212c78fc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterEqualColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterEqualColumnTransformer.java
@@ -32,4 +32,10 @@ public class CompareGreaterEqualColumnTransformer extends 
CompareBinaryColumnTra
   protected boolean transform(int flag) {
     return flag >= 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new CompareGreaterEqualColumnTransformer(
+        returnType, leftTransformer.cloneObject(), 
rightTransformer.cloneObject());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterThanColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterThanColumnTransformer.java
index 5e46c27ec17..c1da20f1e72 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterThanColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareGreaterThanColumnTransformer.java
@@ -32,4 +32,13 @@ public class CompareGreaterThanColumnTransformer extends 
CompareBinaryColumnTran
   protected boolean transform(int flag) {
     return flag > 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    CompareGreaterThanColumnTransformer ret =
+        new CompareGreaterThanColumnTransformer(
+            returnType, leftTransformer.cloneObject(), 
rightTransformer.cloneObject());
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessEqualColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessEqualColumnTransformer.java
index dbb0cf3b325..cb959db23ea 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessEqualColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessEqualColumnTransformer.java
@@ -32,4 +32,10 @@ public class CompareLessEqualColumnTransformer extends 
CompareBinaryColumnTransf
   protected boolean transform(int flag) {
     return flag <= 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new CompareLessEqualColumnTransformer(
+        returnType, leftTransformer.cloneObject(), 
rightTransformer.cloneObject());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessThanColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessThanColumnTransformer.java
index 2ea344dc723..9ba19ba7d78 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessThanColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareLessThanColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class CompareLessThanColumnTransformer extends 
CompareBinaryColumnTransformer {
@@ -32,4 +33,9 @@ public class CompareLessThanColumnTransformer extends 
CompareBinaryColumnTransfo
   protected boolean transform(int flag) {
     return flag < 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareNonEqualColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareNonEqualColumnTransformer.java
index 61027447f8a..ad1ea8a38a0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareNonEqualColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareNonEqualColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 public class CompareNonEqualColumnTransformer extends 
CompareBinaryColumnTransformer {
@@ -44,4 +45,9 @@ public class CompareNonEqualColumnTransformer extends 
CompareBinaryColumnTransfo
   protected boolean transform(int flag) {
     return flag != 0;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicAndColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicAndColumnTransformer.java
index 19a8f6b8083..0616295cf98 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicAndColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicAndColumnTransformer.java
@@ -62,4 +62,13 @@ public class LogicAndColumnTransformer extends 
LogicBinaryColumnTransformer {
   protected boolean transform(boolean left, boolean right) {
     return left && right;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    LogicAndColumnTransformer ret =
+        new LogicAndColumnTransformer(
+            returnType, leftTransformer.cloneObject(), 
rightTransformer.cloneObject());
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicOrColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicOrColumnTransformer.java
index 87a1346ae39..f93b013ad33 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicOrColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/LogicOrColumnTransformer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
 
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.column.Column;
 import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
 import org.apache.iotdb.tsfile.read.common.type.Type;
@@ -62,4 +63,9 @@ public class LogicOrColumnTransformer extends 
LogicBinaryColumnTransformer {
   protected boolean transform(boolean left, boolean right) {
     return left || right;
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new NullColumnTransformer();
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/ConstantColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/ConstantColumnTransformer.java
index cfa6fd9edc5..a3ea4b24497 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/ConstantColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/ConstantColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.leaf;
 
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.TsBlock;
 import org.apache.iotdb.tsfile.read.common.block.column.Column;
 import org.apache.iotdb.tsfile.read.common.block.column.RunLengthEncodedColumn;
@@ -37,4 +38,18 @@ public class ConstantColumnTransformer extends 
LeafColumnTransformer {
   public void initFromTsBlock(TsBlock input) {
     initializeColumnCache(new RunLengthEncodedColumn(value, 
input.getPositionCount()));
   }
+
+  @Override
+  public LeafColumnTransformer cloneLeaf() {
+    ConstantColumnTransformer ret = new ConstantColumnTransformer(returnType, 
value);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    ConstantColumnTransformer ret = new ConstantColumnTransformer(returnType, 
value);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/IdentityColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/IdentityColumnTransformer.java
index 0987b46288e..6d195787c33 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/IdentityColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/IdentityColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.leaf;
 
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.TsBlock;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
@@ -40,4 +41,18 @@ public class IdentityColumnTransformer extends 
LeafColumnTransformer {
   public void initFromTsBlock(TsBlock input) {
     initializeColumnCache(input.getColumn(inputIndex));
   }
+
+  @Override
+  public LeafColumnTransformer cloneLeaf() {
+    IdentityColumnTransformer ret = new IdentityColumnTransformer(returnType, 
inputIndex);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    IdentityColumnTransformer ret = new IdentityColumnTransformer(returnType, 
inputIndex);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/LeafColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/LeafColumnTransformer.java
index 5a1e59daa36..e915503b119 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/LeafColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/LeafColumnTransformer.java
@@ -39,4 +39,6 @@ public abstract class LeafColumnTransformer extends 
ColumnTransformer {
   }
 
   public abstract void initFromTsBlock(TsBlock input);
+
+  public abstract LeafColumnTransformer cloneLeaf();
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java
index 256a056323b..cfcb2f1792b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.leaf;
 
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.TsBlock;
 import org.apache.iotdb.tsfile.read.common.block.column.NullColumn;
 
@@ -37,4 +38,18 @@ public class NullColumnTransformer extends 
LeafColumnTransformer {
   public void initFromTsBlock(TsBlock input) {
     initializeColumnCache(new NullColumn(input.getPositionCount()));
   }
+
+  @Override
+  public LeafColumnTransformer cloneLeaf() {
+    NullColumnTransformer ret = new NullColumnTransformer();
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    NullColumnTransformer ret = new NullColumnTransformer();
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/TimeColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/TimeColumnTransformer.java
index 03f5cc88d49..c140a16308b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/TimeColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/TimeColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.leaf;
 
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.TsBlock;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
@@ -31,4 +32,18 @@ public class TimeColumnTransformer extends 
LeafColumnTransformer {
   public void initFromTsBlock(TsBlock input) {
     initializeColumnCache(input.getTimeColumn());
   }
+
+  @Override
+  public LeafColumnTransformer cloneLeaf() {
+    TimeColumnTransformer ret = new TimeColumnTransformer(returnType);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    TimeColumnTransformer ret = new TimeColumnTransformer(returnType);
+    ret.setReferenceCount(this.referenceCount);
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/MappableUDFColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/MappableUDFColumnTransformer.java
index f3cb46ed152..c8cdeff0c5c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/MappableUDFColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/MappableUDFColumnTransformer.java
@@ -72,4 +72,9 @@ public class MappableUDFColumnTransformer extends 
ColumnTransformer {
     // finalize executor
     executor.beforeDestroy();
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new MappableUDFColumnTransformer(returnType, 
inputColumnTransformers, executor);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ternary/BetweenColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ternary/BetweenColumnTransformer.java
index fc30f03a584..e2eb774f68e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ternary/BetweenColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/ternary/BetweenColumnTransformer.java
@@ -78,4 +78,14 @@ public class BetweenColumnTransformer extends 
CompareTernaryColumnTransformer {
       }
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new BetweenColumnTransformer(
+        returnType,
+        firstColumnTransformer.cloneObject(),
+        secondColumnTransformer.cloneObject(),
+        thirdColumnTransformer.cloneObject(),
+        isNotBetween);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/ArithmeticNegationColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/ArithmeticNegationColumnTransformer.java
index 6e15dabb46d..7468e99d4c9 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/ArithmeticNegationColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/ArithmeticNegationColumnTransformer.java
@@ -48,4 +48,10 @@ public class ArithmeticNegationColumnTransformer extends 
UnaryColumnTransformer
       throw new UnsupportedOperationException("Unsupported Type: " + 
returnType.toString());
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new ArithmeticNegationColumnTransformer(
+        returnType, childColumnTransformer.cloneObject());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
index 23c7e6a5298..2cb14023f4d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
@@ -239,4 +239,16 @@ public class InColumnTransformer extends 
UnaryColumnTransformer {
       return !stringSet.contains(stringValue);
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    InColumnTransformer ret =
+        new InColumnTransformer(
+            returnType,
+            childColumnTransformer.cloneObject(),
+            satisfy instanceof NotInSatisfy,
+            null);
+
+    return ret;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/IsNullColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/IsNullColumnTransformer.java
index 8af53c7f114..e940c460e82 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/IsNullColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/IsNullColumnTransformer.java
@@ -40,4 +40,9 @@ public class IsNullColumnTransformer extends 
UnaryColumnTransformer {
       returnType.writeBoolean(columnBuilder, column.isNull(i) ^ isNot);
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new IsNullColumnTransformer(returnType, 
childColumnTransformer.cloneObject(), isNot);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/LogicNotColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/LogicNotColumnTransformer.java
index 43481136f96..a1c88f20cf5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/LogicNotColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/LogicNotColumnTransformer.java
@@ -49,4 +49,9 @@ public class LogicNotColumnTransformer extends 
UnaryColumnTransformer {
           "Unsupported Type: " + 
childColumnTransformer.getType().getTypeEnum());
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new LogicNotColumnTransformer(returnType, 
childColumnTransformer.cloneObject());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/RegularColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/RegularColumnTransformer.java
index eb48fa3ef79..df93ba7067e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/RegularColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/RegularColumnTransformer.java
@@ -63,4 +63,9 @@ public class RegularColumnTransformer extends 
UnaryColumnTransformer {
           "Unsupported Type: " + 
childColumnTransformer.getType().getTypeEnum());
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new RegularColumnTransformer(returnType, 
childColumnTransformer.cloneObject(), pattern);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
index b1b9dac06fc..0771980cda1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
@@ -225,4 +225,9 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
         throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new CastFunctionColumnTransformer(returnType, 
childColumnTransformer.cloneObject());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/DiffFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/DiffFunctionColumnTransformer.java
index 06aef97223f..9d7c56469ca 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/DiffFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/DiffFunctionColumnTransformer.java
@@ -65,4 +65,10 @@ public class DiffFunctionColumnTransformer extends 
UnaryColumnTransformer {
       }
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new DiffFunctionColumnTransformer(
+        returnType, childColumnTransformer.cloneObject(), ignoreNull);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ReplaceFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ReplaceFunctionColumnTransformer.java
index 2da765b9b0f..2bf9e8b0782 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ReplaceFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ReplaceFunctionColumnTransformer.java
@@ -55,4 +55,9 @@ public class ReplaceFunctionColumnTransformer extends 
UnaryColumnTransformer {
       }
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new ReplaceFunctionColumnTransformer(returnType, 
childColumnTransformer, from, to);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RoundFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RoundFunctionColumnTransformer.java
index a50509ff4a3..bf8fb024e07 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RoundFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RoundFunctionColumnTransformer.java
@@ -69,4 +69,10 @@ public class RoundFunctionColumnTransformer extends 
UnaryColumnTransformer {
       }
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new RoundFunctionColumnTransformer(
+        returnType, childColumnTransformer.cloneObject(), places);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SubStringFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SubStringFunctionColumnTransformer.java
index 4a8c7fa881b..c38d9f7eb46 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SubStringFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SubStringFunctionColumnTransformer.java
@@ -61,4 +61,10 @@ public class SubStringFunctionColumnTransformer extends 
UnaryColumnTransformer {
       }
     }
   }
+
+  @Override
+  public ColumnTransformer cloneObject() {
+    return new SubStringFunctionColumnTransformer(
+        returnType, childColumnTransformer.cloneObject(), beginPosition, 0);
+  }
 }

Reply via email to