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

hui pushed a commit to branch lmh/SupportQueryWithView
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 46ce80bd7c3f4621117cbcadff9ccaf7d18cace8
Author: Minghui Liu <[email protected]>
AuthorDate: Sat May 27 21:55:43 2023 +0800

    tmp save
---
 .../visitor/GetSourcePathsVisitor.java             |   4 +
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java |  11 ++
 .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java  | 100 ++++++++-------
 .../db/mpp/plan/analyze/ExpressionAnalyzer.java    |  14 +--
 .../iotdb/db/mpp/plan/analyze/ExpressionUtils.java | 137 ++++-----------------
 .../visitor/ExpressionAnalyzeVisitor.java          |   2 +-
 .../visitor/GetMeasurementExpressionVisitor.java   |  16 ++-
 .../expression/visitor/ReconstructVisitor.java     |   3 +-
 .../RemoveWildcardAndViewInExpressionVisitor.java  |  95 --------------
 .../{ => cartesian}/CartesianProductVisitor.java   |   5 +-
 .../ConcatDeviceAndRemoveWildcardVisitor.java      |  28 ++++-
 .../ConcatExpressionWithSuffixPathsVisitor.java    |   2 +-
 .../RemoveWildcardAndViewInFilterVisitor.java      |   9 +-
 .../RemoveWildcardInExpressionVisitor.java         |  59 ++++++---
 .../RemoveWildcardInFilterByDeviceVisitor.java     |   2 +-
 .../RemoveWildcardInFilterVisitor.java             |  25 +++-
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    |   4 +-
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    |   1 +
 .../plan/planner/distribution/SourceRewriter.java  |  59 ++++++---
 19 files changed, 261 insertions(+), 315 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
index 321742fdf4c..1874234a39f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java
@@ -36,6 +36,10 @@ import java.util.List;
 /** Use this visitor to find all the paths of time series used in one 
expression. */
 public class GetSourcePathsVisitor extends 
ViewExpressionVisitor<List<PartialPath>, Void> {
 
+  public static List<PartialPath> getSourcePaths(ViewExpression 
viewExpression) {
+    return new GetSourcePathsVisitor().process(viewExpression, null);
+  }
+
   @Override
   public List<PartialPath> visitExpression(ViewExpression expression, Void 
context) {
     return new ArrayList<>();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
index db2ae86e9d6..dc2adf437f0 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
@@ -154,6 +154,8 @@ public class Analysis {
   // not 0 because device is the first column
   private Map<String, List<Integer>> deviceViewInputIndexesMap;
 
+  private Map<String, List<String>> outputDeviceToQueryDeviceMap;
+
   private Set<Expression> deviceViewOutputExpressions;
 
   // indicates whether DeviceView need special process when rewriteSource in 
DistributionPlan,
@@ -435,6 +437,15 @@ public class Analysis {
     return deviceViewInputIndexesMap;
   }
 
+  public Map<String, List<String>> getOutputDeviceToQueryDeviceMap() {
+    return outputDeviceToQueryDeviceMap;
+  }
+
+  public void setOutputDeviceToQueryDeviceMap(
+      Map<String, List<String>> outputDeviceToQueryDeviceMap) {
+    this.outputDeviceToQueryDeviceMap = outputDeviceToQueryDeviceMap;
+  }
+
   public Set<Expression> getSourceExpressions() {
     return sourceExpressions;
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index 909b3e24685..f4329bfd8bf 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -50,7 +50,6 @@ import 
org.apache.iotdb.db.exception.sql.MeasurementNotExistException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.metadata.template.Template;
-import 
org.apache.iotdb.db.metadata.view.viewExpression.visitor.GetSourcePathsVisitor;
 import org.apache.iotdb.db.mpp.common.MPPQueryContext;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
@@ -189,6 +188,7 @@ import static 
org.apache.iotdb.commons.conf.IoTDBConstant.ALLOWED_SCHEMA_PROPS;
 import static org.apache.iotdb.commons.conf.IoTDBConstant.DEADBAND;
 import static org.apache.iotdb.commons.conf.IoTDBConstant.LOSS;
 import static 
org.apache.iotdb.commons.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
+import static 
org.apache.iotdb.db.metadata.view.viewExpression.visitor.GetSourcePathsVisitor.getSourcePaths;
 import static 
org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant.DEVICE;
 import static 
org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant.ENDTIME;
 import static 
org.apache.iotdb.db.mpp.metric.QueryPlanCostMetricSet.PARTITION_FETCHER;
@@ -322,6 +322,7 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
 
         outputExpressions = new ArrayList<>();
         outputExpressionMap.values().forEach(outputExpressions::addAll);
+        analysis.setOutputExpressions(outputExpressions);
         if (outputExpressions.isEmpty()) {
           return finishQuery(queryStatement, analysis);
         }
@@ -351,7 +352,6 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
 
         analyzeInto(analysis, queryStatement, outputExpressions);
       }
-      analysis.setOutputExpressions(outputExpressions);
 
       analyzeGroupByTime(analysis, queryStatement);
 
@@ -452,39 +452,38 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
     analysis.setSourceExpressions(sourceExpressions);
   }
 
-  private ISchemaTree findAllViewsInTreeThenReFetchAndMerge(ISchemaTree 
originSchemaTree) {
-    if (originSchemaTree.hasLogicalViewMeasurement()) {
-      PathPatternTree patternTree = new PathPatternTree();
-      GetSourcePathsVisitor getSourcePathsVisitor = new 
GetSourcePathsVisitor();
-      boolean needToReFetch = false;
-      try {
-        Pair<List<MeasurementPath>, Integer> tempPair =
-            originSchemaTree.searchMeasurementPaths(new 
PartialPath("root.**"));
-        for (MeasurementPath measurementPath : tempPair.left) {
-          if (measurementPath.getMeasurementSchema().isLogicalView()) {
-            LogicalViewSchema logicalViewSchema =
-                (LogicalViewSchema) measurementPath.getMeasurementSchema();
-            ViewExpression viewExpression = logicalViewSchema.getExpression();
-            List<PartialPath> pathsNeedToReFetch =
-                getSourcePathsVisitor.process(viewExpression, null);
-            for (PartialPath path : pathsNeedToReFetch) {
-              patternTree.appendFullPath(path);
-              needToReFetch = true;
-            }
+  private void findAllViewsInTreeThenReFetchAndMerge(ISchemaTree 
originSchemaTree) {
+    if (!originSchemaTree.hasLogicalViewMeasurement()) {
+      return;
+    }
+
+    PathPatternTree patternTree = new PathPatternTree();
+    boolean needToReFetch = false;
+    try {
+      Pair<List<MeasurementPath>, Integer> tempPair =
+          originSchemaTree.searchMeasurementPaths(new PartialPath("root.**"));
+      for (MeasurementPath measurementPath : tempPair.left) {
+        if (measurementPath.getMeasurementSchema().isLogicalView()) {
+          LogicalViewSchema logicalViewSchema =
+              (LogicalViewSchema) measurementPath.getMeasurementSchema();
+          ViewExpression viewExpression = logicalViewSchema.getExpression();
+          List<PartialPath> pathsNeedToReFetch = 
getSourcePaths(viewExpression);
+          for (PartialPath path : pathsNeedToReFetch) {
+            patternTree.appendFullPath(path);
+            needToReFetch = true;
           }
         }
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-      if (needToReFetch) {
-        ISchemaTree viewSchemaTree = 
this.schemaFetcher.fetchSchema(patternTree, null);
-        originSchemaTree.mergeSchemaTree(viewSchemaTree);
-        Set<String> allDatabases = viewSchemaTree.getDatabases();
-        allDatabases.addAll(originSchemaTree.getDatabases());
-        originSchemaTree.setDatabases(allDatabases);
       }
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    if (needToReFetch) {
+      ISchemaTree viewSchemaTree = this.schemaFetcher.fetchSchema(patternTree, 
null);
+      originSchemaTree.mergeSchemaTree(viewSchemaTree);
+      Set<String> allDatabases = viewSchemaTree.getDatabases();
+      allDatabases.addAll(originSchemaTree.getDatabases());
+      originSchemaTree.setDatabases(allDatabases);
     }
-    return originSchemaTree;
   }
 
   private Map<Integer, List<Pair<Expression, String>>> analyzeSelect(
@@ -525,17 +524,18 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
           } else {
             Expression expressionWithoutAlias =
                 ExpressionAnalyzer.removeAliasFromExpression(expression);
-            String alias = expression.getStringWithViewOfThisExpression();
-            alias = hasAlias ? resultColumn.getAlias() : alias;
             if (hasAlias) {
+              String alias = resultColumn.getAlias();
               if (aliasSet.contains(alias)) {
                 throw new SemanticException(
                     String.format("alias '%s' can only be matched with one 
time series", alias));
               }
               aliasSet.add(alias);
             }
+            String outputColumnName =
+                hasAlias ? resultColumn.getAlias() : 
expression.getOutputSymbol();
             analyzeExpression(analysis, expressionWithoutAlias);
-            outputExpressions.add(new Pair<>(expressionWithoutAlias, alias));
+            outputExpressions.add(new Pair<>(expressionWithoutAlias, 
outputColumnName));
           }
           paginationController.consumeLimit();
         } else {
@@ -625,13 +625,10 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
           // add outputExpressions
           Expression measurementExpressionWithoutAlias =
               
ExpressionAnalyzer.removeAliasFromExpression(measurementExpression);
-          String alias =
-              !Objects.equals(measurementExpressionWithoutAlias, 
measurementExpression)
-                  ? measurementExpression.getExpressionString()
-                  : null;
-          alias = hasAlias ? resultColumn.getAlias() : alias;
+          String outputColumnName =
+              hasAlias ? resultColumn.getAlias() : 
measurementExpression.getOutputSymbol();
           analyzeExpression(analysis, measurementExpressionWithoutAlias);
-          outputExpressions.add(new Pair<>(measurementExpressionWithoutAlias, 
alias));
+          outputExpressions.add(new Pair<>(measurementExpressionWithoutAlias, 
outputColumnName));
 
           // add deviceToSelectExpressions
           for (String deviceName : 
deviceToSelectExpressionsOfOneMeasurement.keySet()) {
@@ -1190,7 +1187,7 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
 
     List<String> deviceViewOutputColumns =
         deviceViewOutputExpressions.stream()
-            .map(Expression::getExpressionString)
+            .map(Expression::getOutputSymbol)
             .collect(Collectors.toList());
 
     Map<String, Set<String>> deviceToOutputColumnsMap = new LinkedHashMap<>();
@@ -1205,11 +1202,25 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
         outputColumns.add(ENDTIME);
       }
       for (Expression expression : outputExpressionsUnderDevice) {
-        
outputColumns.add(ExpressionAnalyzer.getMeasurementExpression(expression).toString());
+        outputColumns.add(
+            
ExpressionAnalyzer.getMeasurementExpression(expression).getOutputSymbol());
       }
       deviceToOutputColumnsMap.put(deviceName, outputColumns);
     }
 
+    Map<String, Set<Expression>> deviceToSourceExpressions =
+        analysis.getDeviceToSourceExpressions();
+    Map<String, List<String>> outputDeviceToQueryDeviceMap = new 
LinkedHashMap<>();
+    for (String deviceName : deviceToSourceExpressions.keySet()) {
+      Set<Expression> sourceExpressionsUnderDevice = 
deviceToSourceExpressions.get(deviceName);
+      Set<String> queriedDevices = new HashSet<>();
+      for (Expression expression : sourceExpressionsUnderDevice) {
+        
queriedDevices.add(ExpressionAnalyzer.getDeviceNameInSourceExpression(expression));
+      }
+      outputDeviceToQueryDeviceMap.put(deviceName, new 
ArrayList<>(queriedDevices));
+    }
+    analysis.setOutputDeviceToQueryDeviceMap(outputDeviceToQueryDeviceMap);
+
     Map<String, List<Integer>> deviceViewInputIndexesMap = new HashMap<>();
     for (String deviceName : deviceToOutputColumnsMap.keySet()) {
       List<String> outputsUnderDevice = new 
ArrayList<>(deviceToOutputColumnsMap.get(deviceName));
@@ -1558,7 +1569,10 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
       Analysis analysis, QueryStatement queryStatement, ISchemaTree 
schemaTree) {
     Set<String> deviceSet = new HashSet<>();
     if (queryStatement.isAlignByDevice()) {
-      deviceSet = analysis.getDeviceToSourceExpressions().keySet();
+      deviceSet =
+          analysis.getOutputDeviceToQueryDeviceMap().values().stream()
+              .flatMap(List::stream)
+              .collect(Collectors.toSet());
     } else {
       for (Expression expression : analysis.getSourceExpressions()) {
         
deviceSet.add(ExpressionAnalyzer.getDeviceNameInSourceExpression(expression));
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
index 8525bedf97a..1d050087766 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
@@ -46,16 +46,16 @@ import 
org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.BindTypeForTimeSeriesOperandVisitor;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.CollectAggregationExpressionsVisitor;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.CollectSourceExpressionsVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.ConcatDeviceAndRemoveWildcardVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.ConcatExpressionWithSuffixPathsVisitor;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.GetMeasurementExpressionVisitor;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveAliasFromExpressionVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardAndViewInExpressionVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardAndViewInFilterVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInExpressionVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInFilterByDeviceVisitor;
-import 
org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInFilterVisitor;
 import 
org.apache.iotdb.db.mpp.plan.expression.visitor.ReplaceRawPathWithGroupedPathVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.ConcatDeviceAndRemoveWildcardVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.ConcatExpressionWithSuffixPathsVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardAndViewInExpressionVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardAndViewInFilterVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardInExpressionVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardInFilterByDeviceVisitor;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardInFilterVisitor;
 import org.apache.iotdb.db.mpp.plan.statement.component.ResultColumn;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java
index 921c012d5be..025919d39c3 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java
@@ -22,19 +22,8 @@ package org.apache.iotdb.db.mpp.plan.analyze;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
-import org.apache.iotdb.db.mpp.plan.expression.binary.AdditionExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.DivisionExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.EqualToExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterEqualExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterThanExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.LessEqualExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.LessThanExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.LogicAndExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.LogicOrExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.ModuloExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.MultiplicationExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.NonEqualExpression;
-import org.apache.iotdb.db.mpp.plan.expression.binary.SubtractionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.WhenThenExpression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
@@ -42,12 +31,7 @@ import 
org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.other.CaseWhenThenExpression;
 import org.apache.iotdb.db.mpp.plan.expression.ternary.BetweenExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.InExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.IsNullExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.LikeExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression;
-import org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression;
+import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.filter.TimeFilter;
@@ -63,7 +47,7 @@ public class ExpressionUtils {
       List<? extends PartialPath> actualPaths) {
     List<Expression> resultExpressions = new ArrayList<>();
     for (PartialPath actualPath : actualPaths) {
-      resultExpressions.add(new TimeSeriesOperand(actualPath));
+      resultExpressions.add(reconstructTimeSeriesOperand(actualPath));
     }
     return resultExpressions;
   }
@@ -76,19 +60,16 @@ public class ExpressionUtils {
       FunctionExpression expression, List<List<Expression>> 
childExpressionsList) {
     List<Expression> resultExpressions = new ArrayList<>();
     for (List<Expression> functionExpressions : childExpressionsList) {
-      resultExpressions.add(
-          new FunctionExpression(
-              expression.getFunctionName(),
-              expression.getFunctionAttributes(),
-              functionExpressions));
+      resultExpressions.add(reconstructFunctionExpression(expression, 
functionExpressions));
     }
     return resultExpressions;
   }
 
   public static Expression reconstructFunctionExpression(
       FunctionExpression expression, List<Expression> childExpressions) {
-    return new FunctionExpression(
-        expression.getFunctionName(), expression.getFunctionAttributes(), 
childExpressions);
+    FunctionExpression copiedFunctionExpression = (FunctionExpression) 
expression.copy();
+    copiedFunctionExpression.setExpressions(childExpressions);
+    return copiedFunctionExpression;
   }
 
   public static List<Expression> reconstructUnaryExpressions(
@@ -111,98 +92,34 @@ public class ExpressionUtils {
 
   public static Expression reconstructUnaryExpression(
       UnaryExpression expression, Expression childExpression) {
-    switch (expression.getExpressionType()) {
-      case IS_NULL:
-        return new IsNullExpression(childExpression, ((IsNullExpression) 
expression).isNot());
-      case IN:
-        return new InExpression(
-            childExpression,
-            ((InExpression) expression).isNotIn(),
-            ((InExpression) expression).getValues());
-      case LIKE:
-        return new LikeExpression(
-            childExpression,
-            ((LikeExpression) expression).getPatternString(),
-            ((LikeExpression) expression).getPattern());
-      case LOGIC_NOT:
-        return new LogicNotExpression(childExpression);
-
-      case NEGATION:
-        return new NegationExpression(childExpression);
-
-      case REGEXP:
-        return new RegularExpression(
-            childExpression,
-            ((RegularExpression) expression).getPatternString(),
-            ((RegularExpression) expression).getPattern());
-
-      default:
-        throw new IllegalArgumentException(
-            "unsupported expression type: " + expression.getExpressionType());
-    }
+    UnaryExpression copiedUnaryExpression = (UnaryExpression) 
expression.copy();
+    copiedUnaryExpression.setExpression(childExpression);
+    return copiedUnaryExpression;
   }
 
   public static List<Expression> reconstructBinaryExpressions(
-      ExpressionType expressionType,
+      BinaryExpression expression,
       List<Expression> leftExpressions,
       List<Expression> rightExpressions) {
     List<Expression> resultExpressions = new ArrayList<>();
     for (Expression le : leftExpressions) {
       for (Expression re : rightExpressions) {
-        resultExpressions.add(reconstructBinaryExpression(expressionType, le, 
re));
+        resultExpressions.add(reconstructBinaryExpression(expression, le, re));
       }
     }
     return resultExpressions;
   }
 
   public static Expression reconstructBinaryExpression(
-      ExpressionType expressionType, Expression leftExpression, Expression 
rightExpression) {
-    switch (expressionType) {
-      case ADDITION:
-        return new AdditionExpression(leftExpression, rightExpression);
-
-      case SUBTRACTION:
-        return new SubtractionExpression(leftExpression, rightExpression);
-      case MULTIPLICATION:
-        return new MultiplicationExpression(leftExpression, rightExpression);
-      case DIVISION:
-        return new DivisionExpression(leftExpression, rightExpression);
-      case MODULO:
-        return new ModuloExpression(leftExpression, rightExpression);
-
-      case LESS_THAN:
-        return new LessThanExpression(leftExpression, rightExpression);
-      case LESS_EQUAL:
-        return new LessEqualExpression(leftExpression, rightExpression);
-
-      case GREATER_THAN:
-        return new GreaterThanExpression(leftExpression, rightExpression);
-
-      case GREATER_EQUAL:
-        return new GreaterEqualExpression(leftExpression, rightExpression);
-
-      case EQUAL_TO:
-        return new EqualToExpression(leftExpression, rightExpression);
-
-      case NON_EQUAL:
-        return new NonEqualExpression(leftExpression, rightExpression);
-
-      case LOGIC_AND:
-        return new LogicAndExpression(leftExpression, rightExpression);
-
-      case LOGIC_OR:
-        return new LogicOrExpression(leftExpression, rightExpression);
-
-      case WHEN_THEN:
-        return new WhenThenExpression(leftExpression, rightExpression);
-
-      default:
-        throw new IllegalArgumentException("unsupported expression type: " + 
expressionType);
-    }
+      BinaryExpression expression, Expression leftExpression, Expression 
rightExpression) {
+    BinaryExpression copiedBinaryExpression = (BinaryExpression) 
expression.copy();
+    copiedBinaryExpression.setLeftExpression(leftExpression);
+    copiedBinaryExpression.setRightExpression(rightExpression);
+    return copiedBinaryExpression;
   }
 
   public static List<Expression> reconstructTernaryExpressions(
-      Expression expression,
+      TernaryExpression expression,
       List<Expression> firstExpressions,
       List<Expression> secondExpressions,
       List<Expression> thirdExpressions) {
@@ -217,21 +134,15 @@ public class ExpressionUtils {
   }
 
   public static Expression reconstructTernaryExpression(
-      Expression expression,
+      TernaryExpression expression,
       Expression firstExpression,
       Expression secondExpression,
       Expression thirdExpression) {
-    switch (expression.getExpressionType()) {
-      case BETWEEN:
-        return new BetweenExpression(
-            firstExpression,
-            secondExpression,
-            thirdExpression,
-            ((BetweenExpression) expression).isNotBetween());
-      default:
-        throw new IllegalArgumentException(
-            "unsupported expression type: " + expression.getExpressionType());
-    }
+    TernaryExpression copiedTernaryExpression = (TernaryExpression) 
expression.copy();
+    copiedTernaryExpression.setFirstExpression(firstExpression);
+    copiedTernaryExpression.setFirstExpression(secondExpression);
+    copiedTernaryExpression.setThirdExpression(thirdExpression);
+    return copiedTernaryExpression;
   }
 
   /**
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java
index fdb5f34df30..8f9b346fa6b 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java
@@ -31,7 +31,7 @@ public abstract class ExpressionAnalyzeVisitor<R, C> extends 
ExpressionVisitor<R
         "unsupported expression type: " + expression.getExpressionType());
   }
 
-  List<R> getResultsFromChild(Expression expression, C context) {
+  protected List<R> getResultsFromChild(Expression expression, C context) {
     return expression.getExpressions().stream()
         .map(child -> this.process(child, context))
         .collect(Collectors.toList());
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java
index a47c88a2742..60f346163d0 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java
@@ -29,6 +29,18 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class GetMeasurementExpressionVisitor extends ReconstructVisitor<Void> {
+
+  @Override
+  public Expression process(Expression expression, Void context) {
+    Expression newExpression = expression.accept(this, context);
+
+    if (expression.getViewPath() != null) {
+      PartialPath viewPath = expression.getViewPath();
+      newExpression.setViewPath(new PartialPath(viewPath.getMeasurement(), 
false));
+    }
+    return newExpression;
+  }
+
   @Override
   public Expression visitFunctionExpression(FunctionExpression 
functionExpression, Void context) {
     List<Expression> childExpressions = new ArrayList<>();
@@ -36,8 +48,8 @@ public class GetMeasurementExpressionVisitor extends 
ReconstructVisitor<Void> {
       childExpressions.add(process(suffixExpression, null));
     }
     return new FunctionExpression(
-        ((FunctionExpression) functionExpression).getFunctionName(),
-        ((FunctionExpression) functionExpression).getFunctionAttributes(),
+        functionExpression.getFunctionName(),
+        functionExpression.getFunctionAttributes(),
         childExpressions);
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java
index 83f2ad01d87..52e96f770e9 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java
@@ -48,8 +48,7 @@ public abstract class ReconstructVisitor<C> extends 
ExpressionAnalyzeVisitor<Exp
   @Override
   public Expression visitBinaryExpression(BinaryExpression binaryExpression, C 
context) {
     List<Expression> childResults = getResultsFromChild(binaryExpression, 
context);
-    return reconstructBinaryExpression(
-        binaryExpression.getExpressionType(), childResults.get(0), 
childResults.get(1));
+    return reconstructBinaryExpression(binaryExpression, childResults.get(0), 
childResults.get(1));
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java
deleted file mode 100644
index 303df8ce695..00000000000
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
-
-import org.apache.iotdb.commons.path.MeasurementPath;
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
-import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
-import 
org.apache.iotdb.db.metadata.view.viewExpression.visitor.TransformToExpressionVisitor;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
-import org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils;
-import org.apache.iotdb.db.mpp.plan.expression.Expression;
-import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class RemoveWildcardAndViewInExpressionVisitor extends 
RemoveWildcardInExpressionVisitor {
-  private final TransformToExpressionVisitor transformToExpressionVisitor;
-
-  private final CompleteMeasurementSchemaVisitor 
completeMeasurementSchemaVisitor;
-
-  boolean hasProcessedLogicalView;
-
-  public RemoveWildcardAndViewInExpressionVisitor() {
-    super();
-    this.transformToExpressionVisitor = new TransformToExpressionVisitor();
-    this.completeMeasurementSchemaVisitor = new 
CompleteMeasurementSchemaVisitor();
-    this.hasProcessedLogicalView = false;
-  }
-
-  public boolean isHasProcessedLogicalView() {
-    return this.hasProcessedLogicalView;
-  }
-
-  private Expression transformViewPath(MeasurementPath measurementPath, 
ISchemaTree schemaTree) {
-    IMeasurementSchema measurementSchema = 
measurementPath.getMeasurementSchema();
-    if (measurementSchema.isLogicalView()) {
-      ViewExpression viewExpression = ((LogicalViewSchema) 
measurementSchema).getExpression();
-      // complete measurementPaths in expressions.
-      Expression expression = 
this.transformToExpressionVisitor.process(viewExpression, null);
-      expression = this.completeMeasurementSchemaVisitor.process(expression, 
schemaTree);
-      return expression;
-    } else {
-      throw new RuntimeException(
-          new UnsupportedOperationException(
-              "Can not construct expression using non view path in 
transformViewPath!"));
-    }
-  }
-
-  @Override
-  public List<Expression> visitTimeSeriesOperand(
-      TimeSeriesOperand timeSeriesOperand, ISchemaTree schemaTree) {
-    PartialPath timeSeriesOperandPath = timeSeriesOperand.getPath();
-    List<MeasurementPath> actualPaths =
-        schemaTree.searchMeasurementPaths(timeSeriesOperandPath).left;
-    // process logical view
-    List<MeasurementPath> nonViewActualPaths = new ArrayList<>();
-    List<MeasurementPath> viewPaths = new ArrayList<>();
-    for (MeasurementPath measurementPath : actualPaths) {
-      if (measurementPath.getMeasurementSchema().isLogicalView()) {
-        this.hasProcessedLogicalView = true;
-        viewPaths.add(measurementPath);
-      } else {
-        nonViewActualPaths.add(measurementPath);
-      }
-    }
-    List<Expression> reconstructTimeSeriesOperands =
-        ExpressionUtils.reconstructTimeSeriesOperands(nonViewActualPaths);
-    // handle logical views
-    for (MeasurementPath measurementPath : viewPaths) {
-      Expression replacedExpression = this.transformViewPath(measurementPath, 
schemaTree);
-      replacedExpression.setViewPathOfThisExpression(measurementPath);
-      reconstructTimeSeriesOperands.add(replacedExpression);
-    }
-    return reconstructTimeSeriesOperands;
-  }
-}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java
similarity index 94%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java
index 7d824b0e25d..6830b8cf2e8 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression;
@@ -25,6 +25,7 @@ import 
org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand;
 import org.apache.iotdb.db.mpp.plan.expression.other.CaseWhenThenExpression;
 import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionAnalyzeVisitor;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -52,7 +53,7 @@ public abstract class CartesianProductVisitor<C>
   public List<Expression> visitBinaryExpression(BinaryExpression 
binaryExpression, C context) {
     List<List<Expression>> childResultsList = 
getResultsFromChild(binaryExpression, context);
     return reconstructBinaryExpressions(
-        binaryExpression.getExpressionType(), childResultsList.get(0), 
childResultsList.get(1));
+        binaryExpression, childResultsList.get(0), childResultsList.get(1));
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndRemoveWildcardVisitor.java
similarity index 78%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndRemoveWildcardVisitor.java
index a9f1b50ad2b..92b0b73a51d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndRemoveWildcardVisitor.java
@@ -17,11 +17,12 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
+import org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
@@ -34,7 +35,7 @@ import java.util.List;
 
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProduct;
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions;
-import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands;
+import static 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardInExpressionVisitor.transformViewPath;
 import static 
org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions;
 
 public class ConcatDeviceAndRemoveWildcardVisitor
@@ -77,8 +78,27 @@ public class ConcatDeviceAndRemoveWildcardVisitor
     if (actualPaths.isEmpty()) {
       return Collections.emptyList();
     }
-    List<PartialPath> noStarPaths = new ArrayList<>(actualPaths);
-    return reconstructTimeSeriesOperands(noStarPaths);
+
+    // process logical view
+    List<MeasurementPath> nonViewActualPaths = new ArrayList<>();
+    List<MeasurementPath> viewPaths = new ArrayList<>();
+    for (MeasurementPath measurementPath : actualPaths) {
+      if (measurementPath.getMeasurementSchema().isLogicalView()) {
+        // this.hasProcessedLogicalView = true;
+        viewPaths.add(measurementPath);
+      } else {
+        nonViewActualPaths.add(measurementPath);
+      }
+    }
+    List<Expression> reconstructTimeSeriesOperands =
+        ExpressionUtils.reconstructTimeSeriesOperands(nonViewActualPaths);
+    // handle logical views
+    for (MeasurementPath measurementPath : viewPaths) {
+      Expression replacedExpression = transformViewPath(measurementPath, 
context.getSchemaTree());
+      replacedExpression.setViewPath(measurementPath);
+      reconstructTimeSeriesOperands.add(replacedExpression);
+    }
+    return reconstructTimeSeriesOperands;
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java
similarity index 98%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java
index a8e565e7dae..1bfdaebf1ac 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardAndViewInFilterVisitor.java
similarity index 95%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardAndViewInFilterVisitor.java
index 550f5ac7299..f2b8efd31b2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardAndViewInFilterVisitor.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
@@ -28,6 +28,7 @@ import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.CompleteMeasurementSchemaVisitor;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
 import java.util.ArrayList;
@@ -51,10 +52,6 @@ public class RemoveWildcardAndViewInFilterVisitor extends 
RemoveWildcardInFilter
     this.hasProcessedLogicalView = false;
   }
 
-  public boolean isHasProcessedLogicalView() {
-    return this.hasProcessedLogicalView;
-  }
-
   private Expression transformViewPath(MeasurementPath measurementPath, 
ISchemaTree schemaTree) {
     IMeasurementSchema measurementSchema = 
measurementPath.getMeasurementSchema();
     if (measurementSchema.isLogicalView()) {
@@ -101,7 +98,7 @@ public class RemoveWildcardAndViewInFilterVisitor extends 
RemoveWildcardInFilter
     for (MeasurementPath measurementPath : viewPathList) {
       Expression replacedExpression =
           this.transformViewPath(measurementPath, context.getSchemaTree());
-      replacedExpression.setViewPathOfThisExpression(measurementPath);
+      replacedExpression.setViewPath(measurementPath);
       reconstructTimeSeriesOperands.add(replacedExpression);
     }
     return reconstructTimeSeriesOperands;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInExpressionVisitor.java
similarity index 63%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInExpressionVisitor.java
index 353c567bc84..52def910af5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInExpressionVisitor.java
@@ -17,16 +17,21 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
+import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
+import 
org.apache.iotdb.db.metadata.view.viewExpression.visitor.TransformToExpressionVisitor;
 import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import 
org.apache.iotdb.db.mpp.plan.expression.visitor.CompleteMeasurementSchemaVisitor;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -37,16 +42,18 @@ import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFu
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands;
 import static 
org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions;
 
-public class RemoveWildcardInExpressionVisitor extends 
CartesianProductVisitor<ISchemaTree> {
+public class RemoveWildcardInExpressionVisitor
+    extends CartesianProductVisitor<RemoveWildcardInExpressionVisitor.Context> 
{
+
   @Override
   public List<Expression> visitFunctionExpression(
-      FunctionExpression functionExpression, ISchemaTree schemaTree) {
+      FunctionExpression functionExpression, Context context) {
     // One by one, remove the wildcards from the input expressions. In most 
cases, an expression
     // will produce multiple expressions after removing the wildcards. We use 
extendedExpressions
     // to collect the produced expressions.
     List<List<Expression>> extendedExpressions = new ArrayList<>();
     for (Expression originExpression : functionExpression.getExpressions()) {
-      List<Expression> actualExpressions = process(originExpression, 
schemaTree);
+      List<Expression> actualExpressions = process(originExpression, context);
       if (actualExpressions.isEmpty()) {
         // Let's ignore the eval of the function which has at least one 
non-existence series as
         // input. See IOTDB-1212: https://github.com/apache/iotdb/pull/3101
@@ -61,9 +68,7 @@ public class RemoveWildcardInExpressionVisitor extends 
CartesianProductVisitor<I
       if (functionExpression.isBuiltInAggregationFunctionExpression()) {
         List<Expression> children = functionExpression.getExpressions();
         bindTypeForAggregationNonSeriesInputExpressions(
-            ((FunctionExpression) functionExpression).getFunctionName(),
-            children,
-            extendedExpressions);
+            functionExpression.getFunctionName(), children, 
extendedExpressions);
         break;
       }
     }
@@ -73,27 +78,53 @@ public class RemoveWildcardInExpressionVisitor extends 
CartesianProductVisitor<I
     List<List<Expression>> childExpressionsList = new ArrayList<>();
     cartesianProduct(extendedExpressions, childExpressionsList, 0, new 
ArrayList<>());
 
-    return reconstructFunctionExpressions(
-        (FunctionExpression) functionExpression, childExpressionsList);
+    return reconstructFunctionExpressions(functionExpression, 
childExpressionsList);
   }
 
   @Override
   public List<Expression> visitTimeSeriesOperand(
-      TimeSeriesOperand timeSeriesOperand, ISchemaTree schemaTree) {
+      TimeSeriesOperand timeSeriesOperand, Context context) {
     PartialPath path = timeSeriesOperand.getPath();
-    List<MeasurementPath> actualPaths = 
schemaTree.searchMeasurementPaths(path).left;
+    List<MeasurementPath> actualPaths = 
context.getSchemaTree().searchMeasurementPaths(path).left;
     return reconstructTimeSeriesOperands(actualPaths);
   }
 
   @Override
   public List<Expression> visitTimeStampOperand(
-      TimestampOperand timestampOperand, ISchemaTree context) {
+      TimestampOperand timestampOperand, Context context) {
     return Collections.singletonList(timestampOperand);
   }
 
   @Override
-  public List<Expression> visitConstantOperand(
-      ConstantOperand constantOperand, ISchemaTree context) {
+  public List<Expression> visitConstantOperand(ConstantOperand 
constantOperand, Context context) {
     return Collections.singletonList(constantOperand);
   }
+
+  public static Expression transformViewPath(
+      MeasurementPath measurementPath, ISchemaTree schemaTree) {
+    IMeasurementSchema measurementSchema = 
measurementPath.getMeasurementSchema();
+    if (measurementSchema.isLogicalView()) {
+      ViewExpression viewExpression = ((LogicalViewSchema) 
measurementSchema).getExpression();
+      // complete measurementPaths in expressions.
+      Expression expression = new 
TransformToExpressionVisitor().process(viewExpression, null);
+      expression = new CompleteMeasurementSchemaVisitor().process(expression, 
schemaTree);
+      return expression;
+    } else {
+      throw new RuntimeException(
+          new UnsupportedOperationException(
+              "Can not construct expression using non view path in 
transformViewPath!"));
+    }
+  }
+
+  public static class Context {
+    private final ISchemaTree schemaTree;
+
+    public Context(ISchemaTree schemaTree) {
+      this.schemaTree = schemaTree;
+    }
+
+    public ISchemaTree getSchemaTree() {
+      return schemaTree;
+    }
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterByDeviceVisitor.java
similarity index 98%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterByDeviceVisitor.java
index 4dfb8c1617a..0d3e7665a69 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterByDeviceVisitor.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterVisitor.java
similarity index 84%
rename from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java
rename to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterVisitor.java
index 5d7d3bdb31d..4e816d6b91d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/RemoveWildcardInFilterVisitor.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.expression.visitor;
+package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian;
 
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
@@ -40,6 +40,7 @@ import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProd
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructBinaryExpressions;
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions;
 import static 
org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands;
+import static 
org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.RemoveWildcardInExpressionVisitor.transformViewPath;
 import static 
org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions;
 
 public class RemoveWildcardInFilterVisitor
@@ -56,8 +57,7 @@ public class RemoveWildcardInFilterVisitor
       resultExpressions.addAll(rightExpressions);
       return resultExpressions;
     }
-    return reconstructBinaryExpressions(
-        binaryExpression.getExpressionType(), leftExpressions, 
rightExpressions);
+    return reconstructBinaryExpressions(binaryExpression, leftExpressions, 
rightExpressions);
   }
 
   @Override
@@ -96,16 +96,29 @@ public class RemoveWildcardInFilterVisitor
       concatPaths.add(filterPath);
     }
 
-    List<PartialPath> noStarPaths = new ArrayList<>();
+    List<MeasurementPath> nonViewPathList = new ArrayList<>();
+    List<MeasurementPath> viewPathList = new ArrayList<>();
     for (PartialPath concatPath : concatPaths) {
       List<MeasurementPath> actualPaths =
           context.getSchemaTree().searchMeasurementPaths(concatPath).left;
       if (actualPaths.isEmpty()) {
         return Collections.singletonList(new NullOperand());
       }
-      noStarPaths.addAll(actualPaths);
+      for (MeasurementPath measurementPath : actualPaths) {
+        if (measurementPath.getMeasurementSchema().isLogicalView()) {
+          viewPathList.add(measurementPath);
+        } else {
+          nonViewPathList.add(measurementPath);
+        }
+      }
+    }
+    List<Expression> reconstructTimeSeriesOperands = 
reconstructTimeSeriesOperands(nonViewPathList);
+    for (MeasurementPath measurementPath : viewPathList) {
+      Expression replacedExpression = transformViewPath(measurementPath, 
context.getSchemaTree());
+      replacedExpression.setViewPath(measurementPath);
+      reconstructTimeSeriesOperands.add(replacedExpression);
     }
-    return reconstructTimeSeriesOperands(noStarPaths);
+    return reconstructTimeSeriesOperands;
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index b191f3f2a1c..1aa9b38e7bc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -537,6 +537,7 @@ public class LogicalPlanBuilder {
       Map<String, PlanNode> deviceNameToSourceNodesMap,
       Set<Expression> deviceViewOutputExpressions,
       Map<String, List<Integer>> deviceToMeasurementIndexesMap,
+      Map<String, List<String>> outputDeviceToQueryDeviceMap,
       Set<Expression> selectExpression,
       QueryStatement queryStatement) {
     List<String> outputColumnNames =
@@ -582,7 +583,8 @@ public class LogicalPlanBuilder {
               context.getQueryId().genPlanNodeId(),
               orderByParameter,
               outputColumnNames,
-              deviceToMeasurementIndexesMap);
+              deviceToMeasurementIndexesMap,
+              outputDeviceToQueryDeviceMap);
 
       for (Map.Entry<String, PlanNode> entry : 
deviceNameToSourceNodesMap.entrySet()) {
         String deviceName = entry.getKey();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index ed82734b768..37b8d9ea9ae 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -163,6 +163,7 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
               deviceToSubPlanMap,
               analysis.getDeviceViewOutputExpressions(),
               analysis.getDeviceViewInputIndexesMap(),
+              analysis.getOutputDeviceToQueryDeviceMap(),
               analysis.getSelectExpressions(),
               queryStatement);
     } else {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
index 03cc0fba950..bd4eb70941d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
@@ -72,6 +72,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -165,31 +166,54 @@ public class SourceRewriter extends 
SimplePlanNodeRewriter<DistributionPlanConte
 
     List<DeviceViewSplit> deviceViewSplits = new ArrayList<>();
     // Step 1: constructs DeviceViewSplit
+    Map<String, List<String>> outputDeviceToQueryDeviceMap =
+        analysis.getOutputDeviceToQueryDeviceMap();
     for (int i = 0; i < node.getDevices().size(); i++) {
-      String device = node.getDevices().get(i);
+      String outputDevice = node.getDevices().get(i);
       PlanNode child = node.getChildren().get(i);
-      List<TRegionReplicaSet> regionReplicaSets =
-          analysis.getPartitionInfo(device, analysis.getGlobalTimeFilter());
-      deviceViewSplits.add(new DeviceViewSplit(device, child, 
regionReplicaSets));
+      List<TRegionReplicaSet> regionReplicaSets = new ArrayList<>();
+      for (String queriedDevice : 
outputDeviceToQueryDeviceMap.get(outputDevice)) {
+        regionReplicaSets.addAll(
+            analysis.getPartitionInfo(queriedDevice, 
analysis.getGlobalTimeFilter()));
+      }
+      deviceViewSplits.add(new DeviceViewSplit(outputDevice, child, 
regionReplicaSets));
       relatedDataRegions.addAll(regionReplicaSets);
     }
 
     // Step 2: Iterate all partition and create DeviceViewNode for each region
     List<PlanNode> deviceViewNodeList = new ArrayList<>();
-    for (TRegionReplicaSet regionReplicaSet : relatedDataRegions) {
-      List<String> devices = new ArrayList<>();
-      List<PlanNode> children = new ArrayList<>();
-      for (DeviceViewSplit split : deviceViewSplits) {
-        if (split.needDistributeTo(regionReplicaSet)) {
-          devices.add(split.device);
-          children.add(split.buildPlanNodeInRegion(regionReplicaSet, 
context.queryContext));
-        }
+    Iterator<DeviceViewSplit> deviceViewSplitIterator = 
deviceViewSplits.listIterator();
+    while (deviceViewSplitIterator.hasNext()) {
+      DeviceViewSplit deviceViewSplit = deviceViewSplitIterator.next();
+      String outputDevice = deviceViewSplit.device;
+
+      if (outputDeviceToQueryDeviceMap.get(outputDevice).size() > 1) {
+        DeviceViewNode deviceViewNode = cloneDeviceViewNodeWithoutChild(node, 
context);
+        deviceViewNode.addChildDeviceNode(
+            outputDevice, process(deviceViewSplit.root, context).get(0));
+        deviceViewNodeList.add(deviceViewNode);
+        deviceViewSplitIterator.remove();
       }
-      DeviceViewNode regionDeviceViewNode = 
cloneDeviceViewNodeWithoutChild(node, context);
-      for (int i = 0; i < devices.size(); i++) {
-        regionDeviceViewNode.addChildDeviceNode(devices.get(i), 
children.get(i));
+    }
+
+    if (deviceViewSplits.size() > 0) {
+      for (TRegionReplicaSet regionReplicaSet : relatedDataRegions) {
+        List<String> devices = new ArrayList<>();
+        List<PlanNode> children = new ArrayList<>();
+        for (DeviceViewSplit split : deviceViewSplits) {
+          if (split.needDistributeTo(regionReplicaSet)) {
+            devices.add(split.device);
+            children.add(split.buildPlanNodeInRegion(regionReplicaSet, 
context.queryContext));
+          }
+        }
+        DeviceViewNode regionDeviceViewNode = 
cloneDeviceViewNodeWithoutChild(node, context);
+        for (int i = 0; i < devices.size(); i++) {
+          regionDeviceViewNode.addChildDeviceNode(devices.get(i), 
children.get(i));
+        }
+        if (regionDeviceViewNode.getChildren().size() > 0) {
+          deviceViewNodeList.add(regionDeviceViewNode);
+        }
       }
-      deviceViewNodeList.add(regionDeviceViewNode);
     }
 
     if (deviceViewNodeList.size() == 1) {
@@ -229,7 +253,8 @@ public class SourceRewriter extends 
SimplePlanNodeRewriter<DistributionPlanConte
         context.queryContext.getQueryId().genPlanNodeId(),
         node.getMergeOrderParameter(),
         node.getOutputColumnNames(),
-        node.getDeviceToMeasurementIndexesMap());
+        node.getDeviceToMeasurementIndexesMap(),
+        node.getOutputDeviceToQueryDeviceMap());
   }
 
   private static class DeviceViewSplit {

Reply via email to