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

jackietien pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/ty/TableModelGrammar by this 
push:
     new 9c97463b27f Change tsfile v4 version
9c97463b27f is described below

commit 9c97463b27f98e2f723173556351d30bd412517d
Author: Jackie Tien <[email protected]>
AuthorDate: Thu Aug 8 16:01:55 2024 +0800

    Change tsfile v4 version
---
 .../it/partition/IoTDBPartitionGetterIT.java       |  2 +-
 .../iotdb/confignode/manager/ConfigManager.java    | 49 ++++++-----
 .../queryengine/plan/analyze/AnalyzeVisitor.java   |  6 +-
 .../plan/analyze/ExpressionTypeAnalyzer.java       | 95 ++++++++++++++--------
 .../queryengine/plan/analyze/ExpressionUtils.java  |  8 ++
 .../plan/analyze/TemplatedAggregationAnalyze.java  |  7 +-
 .../queryengine/plan/analyze/TemplatedAnalyze.java |  8 +-
 .../db/queryengine/plan/analyze/TemplatedInfo.java |  4 +-
 .../plan/analyze/schema/ClusterSchemaFetcher.java  |  4 +
 .../plan/expression/leaf/TimeSeriesOperand.java    | 45 ++++++++--
 .../BindTypeForTimeSeriesOperandVisitor.java       |  5 +-
 .../visitor/ExpressionNormalizeVisitor.java        |  2 +-
 .../visitor/GetMeasurementExpressionVisitor.java   | 22 ++---
 .../visitor/RemoveRootPrefixVisitor.java           |  2 +-
 .../visitor/ReplaceLogicalViewVisitor.java         | 17 ++--
 .../visitor/ReplaceSubTreeWithViewVisitor.java     |  3 +-
 .../plan/planner/LogicalPlanBuilder.java           |  5 +-
 .../plan/planner/OperatorTreeGenerator.java        | 39 +++++++--
 .../plan/statement/component/HavingCondition.java  |  8 +-
 .../internal/DeviceSchemaFetchStatement.java       |  1 +
 .../apache/iotdb/db/utils/ErrorHandlingUtils.java  |  3 +-
 .../org/apache/iotdb/db/utils/SchemaUtils.java     |  5 +-
 .../apache/iotdb/db/utils/TypeInferenceUtils.java  |  4 +-
 .../db/queryengine/plan/analyze/AnalyzeTest.java   | 13 +--
 .../plan/analyze/ExpressionAnalyzerTest.java       | 10 ++-
 .../plan/planner/node/PlanGraphPrinterTest.java    |  6 +-
 .../org/apache/iotdb/db/utils/SchemaUtilsTest.java | 10 +--
 .../org/apache/iotdb/commons/path/AlignedPath.java | 24 ++++++
 .../apache/iotdb/commons/path/MeasurementPath.java | 26 ++++++
 .../apache/iotdb/commons/path/PartialPathTest.java | 18 +---
 pom.xml                                            |  2 +-
 31 files changed, 291 insertions(+), 162 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/confignode/it/partition/IoTDBPartitionGetterIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/confignode/it/partition/IoTDBPartitionGetterIT.java
index 5ebe1fe61c2..65ff81cb8b1 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/confignode/it/partition/IoTDBPartitionGetterIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/confignode/it/partition/IoTDBPartitionGetterIT.java
@@ -259,7 +259,7 @@ public class IoTDBPartitionGetterIT {
       Assert.assertEquals(2, schemaPartitionTable.get(sg0).size());
       // Check "root.sg1"
       Assert.assertTrue(schemaPartitionTable.containsKey(sg1));
-      Assert.assertEquals(2, schemaPartitionTable.get(sg1).size());
+      Assert.assertEquals(1, schemaPartitionTable.get(sg1).size());
     }
   }
 
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index 68e605976b8..270fca3ce12 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -39,9 +39,9 @@ import org.apache.iotdb.commons.cluster.NodeType;
 import org.apache.iotdb.commons.conf.CommonConfig;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.ConfigurationFileUtils;
+import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.path.PathPatternUtil;
@@ -685,30 +685,27 @@ public class ConfigManager implements IManager {
   }
 
   private List<TSeriesPartitionSlot> calculateRelatedSlot(PartialPath path, 
PartialPath database) {
-    //    // The path contains `**`
-    //    if 
(path.getFullPath().contains(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD)) {
-    //      return new ArrayList<>();
-    //    }
-    //    // with database = root.sg, path = root.*.d1
-    //    // convert path = root.sg.d1
-    //    List<PartialPath> innerPathList = path.alterPrefixPath(database);
-    //    if (innerPathList.isEmpty()) {
-    //      return new ArrayList<>();
-    //    }
-    //    PartialPath innerPath = innerPathList.get(0);
-    //    // root.sg1.*.d1
-    //    // root.sg1.a1.*
-    //    // The innerPath contains `*` and the only `*` is not in last level
-    //    if 
(innerPath.toString().contains(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD)) {
-    //      return new ArrayList<>();
-    //    }
-    //    return Collections.singletonList(
-    //        
getPartitionManager().getSeriesPartitionSlot(innerPath.getIDeviceID()));
-
-    // the previous code has an issue, it cannot be known that whether "path" 
is a full path,
-    // so it is meaningless to call getIDeviceID()
-    // TODO: how to determine and filter
-    return Collections.emptyList();
+    // The path contains `**`
+    if (path.getFullPath().contains(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD)) {
+      return new ArrayList<>();
+    }
+    // with database = root.sg, path = root.*.d1
+    // convert path = root.sg.d1
+    List<PartialPath> innerPathList = path.alterPrefixPath(database);
+    if (innerPathList.isEmpty()) {
+      return new ArrayList<>();
+    }
+    String[] devicePath =
+        Arrays.copyOf(innerPathList.get(0).getNodes(), 
innerPathList.get(0).getNodeLength() - 1);
+    // root.sg1.*.d1
+    for (String node : devicePath) {
+      if (node.contains(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD)) {
+        return Collections.emptyList();
+      }
+    }
+    return Collections.singletonList(
+        getPartitionManager()
+            
.getSeriesPartitionSlot(IDeviceID.Factory.DEFAULT_FACTORY.create(devicePath)));
   }
 
   @Override
@@ -723,7 +720,7 @@ public class ConfigManager implements IManager {
 
     // Build GetSchemaPartitionPlan
     Map<String, Set<TSeriesPartitionSlot>> partitionSlotsMap = new HashMap<>();
-    List<MeasurementPath> relatedPaths = patternTree.getAllPathPatterns(true);
+    List<PartialPath> relatedPaths = patternTree.getAllPathPatterns();
     List<String> allDatabases = getClusterSchemaManager().getDatabaseNames();
     List<PartialPath> allDatabasePaths = new ArrayList<>();
     for (String database : allDatabases) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
index 2f1eda9dc47..544e9e4e202 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
@@ -1083,8 +1083,7 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
           .add(rawExpression);
 
       Map<String, String> tagMap =
-          ((MeasurementPath)
-                  ((TimeSeriesOperand) 
measurementExpression.getExpressions().get(0)).getPath())
+          ((MeasurementPath) ((TimeSeriesOperand) 
rawExpression.getExpressions().get(0)).getPath())
               .getTagMap();
       List<String> tagValues = new ArrayList<>();
       for (String tagKey : tagKeys) {
@@ -3008,7 +3007,6 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
     context.generateGlobalTimeFilter(analysis);
     PathPatternTree patternTree = new PathPatternTree();
     patternTree.appendPathPattern(pattern);
-    patternTree.constructTree();
     ISchemaTree schemaTree =
         schemaFetcher.fetchRawSchemaInDeviceLevel(patternTree, authorityScope, 
context);
     if (schemaTree.isEmpty()) {
@@ -3106,7 +3104,7 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
 
     PathPatternTree patternTree = new PathPatternTree();
     for (PartialPath path : deviceSchemaFetchStatement.getPaths()) {
-      patternTree.appendPathPattern(path);
+      
patternTree.appendPathPattern(path.concatNode(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD));
     }
     patternTree.constructTree();
     SchemaPartition schemaPartition = 
partitionFetcher.getSchemaPartition(patternTree);
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 f5dbad88a82..41f793d3362 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
@@ -54,6 +54,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 public class ExpressionTypeAnalyzer {
@@ -66,8 +67,10 @@ public class ExpressionTypeAnalyzer {
     if (!analysis.getExpressionTypes().containsKey(NodeRef.of(expression))) {
       ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
 
-      Map<String, IMeasurementSchema> context =
-          analysis.allDevicesInOneTemplate() ? 
analysis.getDeviceTemplate().getSchemaMap() : null;
+      Function<String, TSDataType> context =
+          analysis.allDevicesInOneTemplate()
+              ? new 
TemplateTypeProvider(analysis.getDeviceTemplate().getSchemaMap())
+              : null;
       analyzer.analyze(expression, context);
 
       addExpressionTypes(analysis, analyzer);
@@ -75,11 +78,39 @@ public class ExpressionTypeAnalyzer {
     return analysis.getType(expression);
   }
 
+  public static class TemplateTypeProvider implements Function<String, 
TSDataType> {
+    private final Map<String, IMeasurementSchema> schemaMap;
+
+    public TemplateTypeProvider(Map<String, IMeasurementSchema> schemaMap) {
+      this.schemaMap = schemaMap;
+    }
+
+    @Override
+    public TSDataType apply(String s) {
+      IMeasurementSchema measurementSchema = schemaMap.get(s);
+      return measurementSchema == null ? null : measurementSchema.getType();
+    }
+  }
+
+  public static class TypeProviderWrapper implements Function<String, 
TSDataType> {
+    private final Map<String, TSDataType> typeMap;
+
+    public TypeProviderWrapper(Map<String, TSDataType> typeMap) {
+      this.typeMap = typeMap;
+    }
+
+    @Override
+    public TSDataType apply(String s) {
+      return typeMap.get(s);
+    }
+  }
+
   public static TSDataType analyzeExpressionForTemplatedQuery(
       Analysis analysis, Expression expression) {
     if (!analysis.getExpressionTypes().containsKey(NodeRef.of(expression))) {
       ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
-      analyzer.analyze(expression, 
analysis.getDeviceTemplate().getSchemaMap());
+      analyzer.analyze(
+          expression, new 
TemplateTypeProvider(analysis.getDeviceTemplate().getSchemaMap()));
 
       addExpressionTypes(analysis, analyzer);
     }
@@ -94,13 +125,12 @@ public class ExpressionTypeAnalyzer {
     types.putAll(analyzer.getExpressionTypes());
   }
 
-  public static void analyzeExpressionUsingTemplatedInfo(
+  public static void analyzeExpression(
       Map<NodeRef<Expression>, TSDataType> types,
       Expression expression,
-      TemplatedInfo templatedInfo) {
+      Function<String, TSDataType> schemaMap) {
     ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
 
-    Map<String, IMeasurementSchema> schemaMap = templatedInfo.getSchemaMap();
     analyzer.analyze(expression, schemaMap);
 
     types.putAll(analyzer.getExpressionTypes());
@@ -110,7 +140,7 @@ public class ExpressionTypeAnalyzer {
     analysis.addTypes(analyzer.getExpressionTypes());
   }
 
-  public TSDataType analyze(Expression expression, Map<String, 
IMeasurementSchema> context) {
+  public TSDataType analyze(Expression expression, Function<String, 
TSDataType> context) {
     Visitor visitor = new Visitor();
     return visitor.process(expression, context);
   }
@@ -119,10 +149,10 @@ public class ExpressionTypeAnalyzer {
     return expressionTypes;
   }
 
-  private class Visitor extends ExpressionVisitor<TSDataType, Map<String, 
IMeasurementSchema>> {
+  private class Visitor extends ExpressionVisitor<TSDataType, Function<String, 
TSDataType>> {
 
     @Override
-    public TSDataType process(Expression expression, Map<String, 
IMeasurementSchema> context) {
+    public TSDataType process(Expression expression, Function<String, 
TSDataType> context) {
       // don't double process a expression
       TSDataType dataType = expressionTypes.get(NodeRef.of(expression));
       if (dataType != null) {
@@ -132,29 +162,28 @@ public class ExpressionTypeAnalyzer {
     }
 
     @Override
-    public TSDataType visitExpression(
-        Expression expression, Map<String, IMeasurementSchema> context) {
+    public TSDataType visitExpression(Expression expression, Function<String, 
TSDataType> context) {
       throw new UnsupportedOperationException(
           "Unsupported expression type: " + expression.getClass().getName());
     }
 
     @Override
     public TSDataType visitInExpression(
-        InExpression inExpression, Map<String, IMeasurementSchema> context) {
+        InExpression inExpression, Function<String, TSDataType> context) {
       process(inExpression.getExpression(), context);
       return setExpressionType(inExpression, TSDataType.BOOLEAN);
     }
 
     @Override
     public TSDataType visitIsNullExpression(
-        IsNullExpression isNullExpression, Map<String, IMeasurementSchema> 
context) {
+        IsNullExpression isNullExpression, Function<String, TSDataType> 
context) {
       process(isNullExpression.getExpression(), context);
       return setExpressionType(isNullExpression, TSDataType.BOOLEAN);
     }
 
     @Override
     public TSDataType visitLikeExpression(
-        LikeExpression likeExpression, Map<String, IMeasurementSchema> 
context) {
+        LikeExpression likeExpression, Function<String, TSDataType> context) {
       checkInputExpressionDataType(
           likeExpression.getExpression().getExpressionString(),
           process(likeExpression.getExpression(), context),
@@ -165,7 +194,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitRegularExpression(
-        RegularExpression regularExpression, Map<String, IMeasurementSchema> 
context) {
+        RegularExpression regularExpression, Function<String, TSDataType> 
context) {
       checkInputExpressionDataType(
           regularExpression.getExpression().getExpressionString(),
           process(regularExpression.getExpression(), context),
@@ -176,7 +205,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitLogicNotExpression(
-        LogicNotExpression logicNotExpression, Map<String, IMeasurementSchema> 
context) {
+        LogicNotExpression logicNotExpression, Function<String, TSDataType> 
context) {
       checkInputExpressionDataType(
           logicNotExpression.getExpression().getExpressionString(),
           process(logicNotExpression.getExpression(), context),
@@ -186,7 +215,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitNegationExpression(
-        NegationExpression negationExpression, Map<String, IMeasurementSchema> 
context) {
+        NegationExpression negationExpression, Function<String, TSDataType> 
context) {
       TSDataType inputExpressionType = 
process(negationExpression.getExpression(), context);
       checkInputExpressionDataType(
           negationExpression.getExpression().getExpressionString(),
@@ -201,7 +230,7 @@ public class ExpressionTypeAnalyzer {
     @Override
     public TSDataType visitArithmeticBinaryExpression(
         ArithmeticBinaryExpression arithmeticBinaryExpression,
-        Map<String, IMeasurementSchema> context) {
+        Function<String, TSDataType> context) {
       checkInputExpressionDataType(
           arithmeticBinaryExpression.getLeftExpression().getExpressionString(),
           process(arithmeticBinaryExpression.getLeftExpression(), context),
@@ -221,7 +250,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitLogicBinaryExpression(
-        LogicBinaryExpression logicBinaryExpression, Map<String, 
IMeasurementSchema> context) {
+        LogicBinaryExpression logicBinaryExpression, Function<String, 
TSDataType> context) {
       checkInputExpressionDataType(
           logicBinaryExpression.getLeftExpression().getExpressionString(),
           process(logicBinaryExpression.getLeftExpression(), context),
@@ -235,7 +264,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitCompareBinaryExpression(
-        CompareBinaryExpression compareBinaryExpression, Map<String, 
IMeasurementSchema> context) {
+        CompareBinaryExpression compareBinaryExpression, Function<String, 
TSDataType> context) {
       final TSDataType leftExpressionDataType =
           process(compareBinaryExpression.getLeftExpression(), context);
       final TSDataType rightExpressionDataType =
@@ -305,7 +334,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitBetweenExpression(
-        BetweenExpression betweenExpression, Map<String, IMeasurementSchema> 
context) {
+        BetweenExpression betweenExpression, Function<String, TSDataType> 
context) {
       process(betweenExpression.getFirstExpression(), context);
       process(betweenExpression.getSecondExpression(), context);
       process(betweenExpression.getThirdExpression(), context);
@@ -314,7 +343,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitFunctionExpression(
-        FunctionExpression functionExpression, Map<String, IMeasurementSchema> 
context) {
+        FunctionExpression functionExpression, Function<String, TSDataType> 
context) {
       List<Expression> inputExpressions = functionExpression.getExpressions();
       for (Expression expression : inputExpressions) {
         process(expression, context);
@@ -363,36 +392,38 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitTimeStampOperand(
-        TimestampOperand timestampOperand, Map<String, IMeasurementSchema> 
context) {
+        TimestampOperand timestampOperand, Function<String, TSDataType> 
context) {
       return setExpressionType(timestampOperand, TSDataType.INT64);
     }
 
     @Override
     public TSDataType visitTimeSeriesOperand(
-        TimeSeriesOperand timeSeriesOperand, Map<String, IMeasurementSchema> 
context) {
-      if (context != null && 
(context.containsKey(timeSeriesOperand.getOutputSymbol()))) {
-        return setExpressionType(
-            timeSeriesOperand, 
context.get(timeSeriesOperand.getOutputSymbol()).getType());
+        TimeSeriesOperand timeSeriesOperand, Function<String, TSDataType> 
context) {
+      if (context != null) {
+        TSDataType type = context.apply(timeSeriesOperand.getOutputSymbol());
+        if (type != null) {
+          return setExpressionType(timeSeriesOperand, type);
+        }
       }
 
-      return setExpressionType(timeSeriesOperand, 
timeSeriesOperand.getPath().getSeriesType());
+      return setExpressionType(timeSeriesOperand, 
timeSeriesOperand.getOperandType());
     }
 
     @Override
     public TSDataType visitConstantOperand(
-        ConstantOperand constantOperand, Map<String, IMeasurementSchema> 
context) {
+        ConstantOperand constantOperand, Function<String, TSDataType> context) 
{
       return setExpressionType(constantOperand, constantOperand.getDataType());
     }
 
     @Override
     public TSDataType visitNullOperand(
-        NullOperand nullOperand, Map<String, IMeasurementSchema> context) {
+        NullOperand nullOperand, Function<String, TSDataType> context) {
       return null;
     }
 
     @Override
     public TSDataType visitCaseWhenThenExpression(
-        CaseWhenThenExpression caseWhenThenExpression, Map<String, 
IMeasurementSchema> context) {
+        CaseWhenThenExpression caseWhenThenExpression, Function<String, 
TSDataType> context) {
       Set<TSDataType> typeSet = new HashSet<>();
       for (WhenThenExpression whenThenExpression :
           caseWhenThenExpression.getWhenThenExpressions()) {
@@ -424,7 +455,7 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitWhenThenExpression(
-        WhenThenExpression whenThenExpression, Map<String, IMeasurementSchema> 
context) {
+        WhenThenExpression whenThenExpression, Function<String, TSDataType> 
context) {
       TSDataType whenType = process(whenThenExpression.getWhen(), context);
       if (!whenType.equals(TSDataType.BOOLEAN)) {
         throw new SemanticException(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java
index fc9d3a0aa51..a9ad3fad40b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java
@@ -52,6 +52,8 @@ import 
org.apache.iotdb.db.queryengine.plan.expression.unary.NegationExpression;
 import org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression;
 import org.apache.iotdb.db.queryengine.plan.expression.unary.UnaryExpression;
 
+import org.apache.tsfile.enums.TSDataType;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -82,6 +84,12 @@ public class ExpressionUtils {
     return cloneCommonFields(rawExpression, resultExpression);
   }
 
+  public static Expression reconstructTimeSeriesOperand(
+      TimeSeriesOperand rawExpression, PartialPath actualPath, TSDataType 
dataType) {
+    Expression resultExpression = new TimeSeriesOperand(actualPath, dataType);
+    return cloneCommonFields(rawExpression, resultExpression);
+  }
+
   public static List<Expression> reconstructFunctionExpressionsWithMemoryCheck(
       final FunctionExpression expression,
       final List<List<Expression>> childExpressionsList,
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAggregationAnalyze.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAggregationAnalyze.java
index 79f8ba0a8c1..ba4bdf4255c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAggregationAnalyze.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAggregationAnalyze.java
@@ -41,6 +41,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.ENDTIME;
@@ -167,13 +168,15 @@ public class TemplatedAggregationAnalyze {
             && 
"*".equalsIgnoreCase(selectExpression.getExpressions().get(0).getOutputSymbol()))
 {
           subExpressions = new ArrayList<>();
           FunctionExpression functionExpression = (FunctionExpression) 
selectExpression;
-          for (String measurement : template.getSchemaMap().keySet()) {
+          for (Map.Entry<String, IMeasurementSchema> entry : 
template.getSchemaMap().entrySet()) {
             FunctionExpression subFunctionExpression =
                 new FunctionExpression(
                     functionExpression.getFunctionName(),
                     functionExpression.getFunctionAttributes(),
                     Collections.singletonList(
-                        new TimeSeriesOperand(new PartialPath(new String[] 
{measurement}))));
+                        new TimeSeriesOperand(
+                            new PartialPath(new String[] {entry.getKey()}),
+                            entry.getValue().getType())));
             
subFunctionExpression.setFunctionType(functionExpression.getFunctionType());
             subExpressions.add(subFunctionExpression);
           }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java
index 6014cd572f7..d3bf070d2be 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java
@@ -22,7 +22,6 @@ package org.apache.iotdb.db.queryengine.plan.analyze;
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
 import org.apache.iotdb.commons.partition.DataPartition;
 import org.apache.iotdb.commons.partition.DataPartitionQueryParam;
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
@@ -130,10 +129,9 @@ public class TemplatedAnalyze {
             paginationController.consumeOffset();
           } else if (paginationController.hasCurLimit()) {
             String measurementName = entry.getKey();
-            IMeasurementSchema measurementSchema = entry.getValue();
             TimeSeriesOperand measurementPath =
                 new TimeSeriesOperand(
-                    new MeasurementPath(new String[] {measurementName}, 
measurementSchema));
+                    new PartialPath(new String[] {measurementName}), 
entry.getValue().getType());
             // reserve memory for this expression
             context.reserveMemoryForFrontEnd(measurementPath.ramBytesUsed());
             outputExpressions.add(new Pair<>(measurementPath, null));
@@ -153,10 +151,10 @@ public class TemplatedAnalyze {
           if (paginationController.hasCurOffset()) {
             paginationController.consumeOffset();
           } else if (paginationController.hasCurLimit()) {
-            IMeasurementSchema measurementSchema = 
template.getSchemaMap().get(measurementName);
             TimeSeriesOperand measurementPath =
                 new TimeSeriesOperand(
-                    new MeasurementPath(new String[] {measurementName}, 
measurementSchema));
+                    new PartialPath(new String[] {measurementName}),
+                    template.getSchemaMap().get(measurementName).getType());
             // reserve memory for this expression
             context.reserveMemoryForFrontEnd(measurementPath.ramBytesUsed());
             outputExpressions.add(new Pair<>(measurementPath, 
resultColumn.getAlias()));
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 919efa8970c..5a4beb851ee 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,7 +19,6 @@
 
 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.plan.expression.Expression;
 import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
@@ -199,8 +198,7 @@ public class TemplatedInfo {
     for (int i = 0; i < measurementList.size(); i++) {
       projectExpressions[i] =
           new TimeSeriesOperand(
-              new MeasurementPath(
-                  new PartialPath(new String[] {measurementList.get(i)}), 
schemaList.get(i)));
+              new PartialPath(new String[] {measurementList.get(i)}), 
schemaList.get(i).getType());
     }
     return projectExpressions;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/ClusterSchemaFetcher.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/ClusterSchemaFetcher.java
index 6d4d4a89dc8..eb5fcd1a9be 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/ClusterSchemaFetcher.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/ClusterSchemaFetcher.java
@@ -133,6 +133,10 @@ public class ClusterSchemaFetcher implements 
ISchemaFetcher {
 
       if (isAllCached && !explicitPathList.isEmpty()) {
         for (PartialPath fullPath : explicitPathList) {
+          // no path length <= 2
+          if (fullPath.getNodeLength() <= 2) {
+            continue;
+          }
           cachedSchema =
               schemaCache.getMatchedSchemaWithoutTemplate(new 
MeasurementPath(fullPath.getNodes()));
           if (cachedSchema.isEmpty()) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/leaf/TimeSeriesOperand.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/leaf/TimeSeriesOperand.java
index 22ded4d95d7..4ce4c00fe4c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/leaf/TimeSeriesOperand.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/leaf/TimeSeriesOperand.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.queryengine.plan.expression.leaf;
 
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathDeserializeUtil;
 import org.apache.iotdb.db.queryengine.execution.MemoryEstimationHelper;
@@ -30,6 +29,7 @@ import 
org.apache.iotdb.db.queryengine.transformation.dag.memory.LayerMemoryAssi
 
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -42,29 +42,48 @@ public class TimeSeriesOperand extends LeafOperand {
   private static final long INSTANCE_SIZE =
       RamUsageEstimator.shallowSizeOfInstance(TimeSeriesOperand.class);
 
-  private PartialPath path;
+  private final PartialPath path;
+
+  // if path is MeasurementPath or AlignedPath, this type is null
+  private final TSDataType type;
 
   public TimeSeriesOperand(PartialPath path) {
     this.path = path;
+    this.type = null;
+  }
+
+  public TimeSeriesOperand(PartialPath path, TSDataType dataType) {
+    this.path = path;
+    this.type = dataType;
   }
 
   public TimeSeriesOperand(ByteBuffer byteBuffer) {
     path = (PartialPath) PathDeserializeUtil.deserialize(byteBuffer);
+    boolean hasType = ReadWriteIOUtils.readBool(byteBuffer);
+    if (hasType) {
+      this.type = TSDataType.deserializeFrom(byteBuffer);
+    } else {
+      this.type = null;
+    }
   }
 
   public static TimeSeriesOperand constructColumnHeaderExpression(
       String columnName, TSDataType dataType) {
-    MeasurementPath measurementPath =
-        new MeasurementPath(new PartialPath(columnName, false), dataType);
-    return new TimeSeriesOperand(measurementPath);
+    return new TimeSeriesOperand(new PartialPath(columnName, false), dataType);
   }
 
   public PartialPath getPath() {
     return path;
   }
 
-  public void setPath(PartialPath path) {
-    this.path = path;
+  // get TSDataType of this TimeSeriesOperand returning, it will never return 
null
+  public TSDataType getOperandType() {
+    return type != null ? type : path.getSeriesType();
+  }
+
+  // get the type field of this TimeSeriesOperand, it may return null
+  public TSDataType getType() {
+    return type;
   }
 
   @Override
@@ -105,11 +124,23 @@ public class TimeSeriesOperand extends LeafOperand {
   @Override
   protected void serialize(ByteBuffer byteBuffer) {
     path.serialize(byteBuffer);
+    if (type == null) {
+      ReadWriteIOUtils.write(false, byteBuffer);
+    } else {
+      ReadWriteIOUtils.write(true, byteBuffer);
+      type.serializeTo(byteBuffer);
+    }
   }
 
   @Override
   protected void serialize(DataOutputStream stream) throws IOException {
     path.serialize(stream);
+    if (type == null) {
+      ReadWriteIOUtils.write(false, stream);
+    } else {
+      ReadWriteIOUtils.write(true, stream);
+      type.serializeTo(stream);
+    }
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/BindTypeForTimeSeriesOperandVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/BindTypeForTimeSeriesOperandVisitor.java
index 4aecb34e0bb..662e4b8f54d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/BindTypeForTimeSeriesOperandVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/BindTypeForTimeSeriesOperandVisitor.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.queryengine.plan.expression.visitor;
 
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.path.MeasurementPath;
+import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
 import org.apache.iotdb.db.queryengine.plan.expression.Expression;
@@ -44,7 +44,8 @@ public class BindTypeForTimeSeriesOperandVisitor extends 
ReconstructVisitor<List
         try {
           return reconstructTimeSeriesOperand(
               predicate,
-              new MeasurementPath(columnHeader.getColumnName(), 
columnHeader.getColumnType()));
+              new PartialPath(columnHeader.getColumnName()),
+              columnHeader.getColumnType());
         } catch (IllegalPathException e) {
           throw new SemanticException(e);
         }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ExpressionNormalizeVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ExpressionNormalizeVisitor.java
index 642b3a3b617..59868395c39 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ExpressionNormalizeVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ExpressionNormalizeVisitor.java
@@ -61,7 +61,7 @@ public class ExpressionNormalizeVisitor extends 
ReconstructVisitor<Void> {
     if (newPath.isMeasurementAliasExists()) {
       ((MeasurementPath) newPath).removeMeasurementAlias();
     }
-    TimeSeriesOperand newOperand = new TimeSeriesOperand(newPath);
+    TimeSeriesOperand newOperand = new TimeSeriesOperand(newPath, 
timeSeriesOperand.getType());
     if (timeSeriesOperand.isViewExpression()) {
       newOperand.setViewPath(timeSeriesOperand.getViewPath());
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/GetMeasurementExpressionVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/GetMeasurementExpressionVisitor.java
index 53361f522d7..0395c3bc047 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/GetMeasurementExpressionVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/GetMeasurementExpressionVisitor.java
@@ -42,15 +42,17 @@ public class GetMeasurementExpressionVisitor extends 
ReconstructVisitor<Analysis
 
   @Override
   public Expression visitTimeSeriesOperand(TimeSeriesOperand 
timeSeriesOperand, Analysis analysis) {
-    MeasurementPath rawPath = (MeasurementPath) timeSeriesOperand.getPath();
-    String measurementName =
-        rawPath.isMeasurementAliasExists()
-            ? rawPath.getMeasurementAlias()
-            : rawPath.getMeasurement();
-    MeasurementPath measurementPath =
-        new MeasurementPath(
-            new PartialPath(measurementName, false), 
rawPath.getMeasurementSchema());
-    measurementPath.setTagMap(rawPath.getTagMap());
-    return new TimeSeriesOperand(measurementPath);
+    if (timeSeriesOperand.getPath() instanceof MeasurementPath) {
+      MeasurementPath rawPath = (MeasurementPath) timeSeriesOperand.getPath();
+      String measurementName =
+          rawPath.isMeasurementAliasExists()
+              ? rawPath.getMeasurementAlias()
+              : rawPath.getMeasurement();
+      return new TimeSeriesOperand(
+          new PartialPath(measurementName, false), 
rawPath.getMeasurementSchema().getType());
+    } else {
+      return new TimeSeriesOperand(
+          new PartialPath(timeSeriesOperand.getPath().getNodes()), 
timeSeriesOperand.getType());
+    }
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/RemoveRootPrefixVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/RemoveRootPrefixVisitor.java
index ada5d3c89ca..57b2b65a529 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/RemoveRootPrefixVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/RemoveRootPrefixVisitor.java
@@ -40,6 +40,6 @@ public class RemoveRootPrefixVisitor extends 
ReconstructVisitor<Void> {
     String[] newPartialNodes = new String[newPartialNodesLength];
     System.arraycopy(rawPartialNodes, 1, newPartialNodes, 0, 
newPartialNodesLength);
 
-    return new TimeSeriesOperand(new PartialPath(newPartialNodes));
+    return new TimeSeriesOperand(new PartialPath(newPartialNodes), 
timeSeriesOperand.getType());
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceLogicalViewVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceLogicalViewVisitor.java
index 23a00a0ff4f..39fe3c637c9 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceLogicalViewVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceLogicalViewVisitor.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.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;
@@ -173,13 +174,15 @@ public class ReplaceLogicalViewVisitor extends 
ExpressionVisitor<Expression, Lis
       TimeSeriesOperand timeSeriesOperand, List<PartialPath> context) {
     PartialPath path = timeSeriesOperand.getPath();
     try {
-      IMeasurementSchema measurementSchema = path.getMeasurementSchema();
-      if (measurementSchema.isLogicalView()) {
-        ViewExpression viewExpression = ((LogicalViewSchema) 
measurementSchema).getExpression();
-        Expression result = this.transform(viewExpression);
-        // record paths in this viewExpression
-        context.addAll(this.collectSourcePaths(viewExpression));
-        return result;
+      if (path instanceof MeasurementPath) {
+        IMeasurementSchema measurementSchema = path.getMeasurementSchema();
+        if (measurementSchema.isLogicalView()) {
+          ViewExpression viewExpression = ((LogicalViewSchema) 
measurementSchema).getExpression();
+          Expression result = this.transform(viewExpression);
+          // record paths in this viewExpression
+          context.addAll(this.collectSourcePaths(viewExpression));
+          return result;
+        }
       }
     } catch (Exception e) {
       throw new RuntimeException(e);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceSubTreeWithViewVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceSubTreeWithViewVisitor.java
index 7d20546722b..49702ff5528 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceSubTreeWithViewVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ReplaceSubTreeWithViewVisitor.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.queryengine.plan.expression.visitor;
 
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.db.queryengine.plan.analyze.Analysis;
 import org.apache.iotdb.db.queryengine.plan.expression.Expression;
 import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
@@ -32,7 +31,7 @@ public class ReplaceSubTreeWithViewVisitor extends 
ReconstructVisitor<Analysis>
   public Expression process(Expression expression, Analysis analysis) {
     if (expression.isViewExpression()) {
       TSDataType dataType = analysis.getType(expression);
-      return new TimeSeriesOperand(new 
MeasurementPath(expression.getViewPath(), dataType));
+      return new TimeSeriesOperand(expression.getViewPath(), dataType);
     }
     return expression.accept(this, analysis);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
index 8871329765a..04b741e4baf 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
@@ -464,7 +464,10 @@ public class LogicalPlanBuilder {
         for (String partialAggregationName : partialAggregationsNames) {
           typeProvider.setTreeModelType(
               String.format("%s(%s)", partialAggregationName, 
path.getFullPath()),
-              SchemaUtils.getSeriesTypeByPath(path, partialAggregationName));
+              SchemaUtils.getSeriesTypeByPath(
+                  ((TimeSeriesOperand) 
aggregationDescriptor.getOutputExpressions().get(0))
+                      .getOperandType(),
+                  partialAggregationName));
         }
       }
     } else {
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 ef55a417350..01ee500fe3e 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
@@ -1496,10 +1496,17 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
 
     for (Expression projectExpression : projectExpressions) {
       if (context.isBuildPlanUseTemplate()) {
-        ExpressionTypeAnalyzer.analyzeExpressionUsingTemplatedInfo(
-            expressionTypes, projectExpression, context.getTemplatedInfo());
+        ExpressionTypeAnalyzer.analyzeExpression(
+            expressionTypes,
+            projectExpression,
+            new ExpressionTypeAnalyzer.TemplateTypeProvider(
+                context.getTemplatedInfo().getSchemaMap()));
       } else {
-        ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, 
projectExpression);
+        ExpressionTypeAnalyzer.analyzeExpression(
+            expressionTypes,
+            projectExpression,
+            new ExpressionTypeAnalyzer.TypeProviderWrapper(
+                context.getTypeProvider().getTreeModelTypeMap()));
       }
     }
 
@@ -1618,10 +1625,17 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
       LocalExecutionPlanContext context) {
     final Map<NodeRef<Expression>, TSDataType> expressionTypes = new 
HashMap<>();
     if (context.isBuildPlanUseTemplate()) {
-      ExpressionTypeAnalyzer.analyzeExpressionUsingTemplatedInfo(
-          expressionTypes, predicate, 
context.getTypeProvider().getTemplatedInfo());
+      ExpressionTypeAnalyzer.analyzeExpression(
+          expressionTypes,
+          predicate,
+          new ExpressionTypeAnalyzer.TemplateTypeProvider(
+              context.getTypeProvider().getTemplatedInfo().getSchemaMap()));
     } else {
-      ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, predicate);
+      ExpressionTypeAnalyzer.analyzeExpression(
+          expressionTypes,
+          predicate,
+          new ExpressionTypeAnalyzer.TypeProviderWrapper(
+              context.getTypeProvider().getTreeModelTypeMap()));
     }
 
     // check whether predicate contains Non-Mappable UDF
@@ -1633,10 +1647,17 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
 
     for (Expression projectExpression : projectExpressions) {
       if (context.isBuildPlanUseTemplate()) {
-        ExpressionTypeAnalyzer.analyzeExpressionUsingTemplatedInfo(
-            expressionTypes, projectExpression, 
context.getTypeProvider().getTemplatedInfo());
+        ExpressionTypeAnalyzer.analyzeExpression(
+            expressionTypes,
+            projectExpression,
+            new ExpressionTypeAnalyzer.TemplateTypeProvider(
+                context.getTypeProvider().getTemplatedInfo().getSchemaMap()));
       } else {
-        ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, 
projectExpression);
+        ExpressionTypeAnalyzer.analyzeExpression(
+            expressionTypes,
+            projectExpression,
+            new ExpressionTypeAnalyzer.TypeProviderWrapper(
+                context.getTypeProvider().getTreeModelTypeMap()));
       }
     }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/component/HavingCondition.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/component/HavingCondition.java
index 655b4cdd6a8..34d7d272c63 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/component/HavingCondition.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/component/HavingCondition.java
@@ -26,9 +26,7 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.StatementNode;
 /** This class maintains information of {@code HAVING} clause. */
 public class HavingCondition extends StatementNode {
 
-  private Expression predicate;
-
-  public HavingCondition() {}
+  private final Expression predicate;
 
   public HavingCondition(Expression predicate) {
     // cast functionName to lowercase in havingExpression
@@ -39,10 +37,6 @@ public class HavingCondition extends StatementNode {
     return predicate;
   }
 
-  public void setPredicate(Expression predicate) {
-    this.predicate = ExpressionAnalyzer.toLowerCaseExpression(predicate);
-  }
-
   public String toSQLString() {
     return "HAVING " + predicate.getExpressionString();
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/internal/DeviceSchemaFetchStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/internal/DeviceSchemaFetchStatement.java
index 00271f19097..af2ce0df838 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/internal/DeviceSchemaFetchStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/internal/DeviceSchemaFetchStatement.java
@@ -48,6 +48,7 @@ public class DeviceSchemaFetchStatement extends Statement {
 
   @Override
   public List<PartialPath> getPaths() {
+    patternTree.constructTree();
     return patternTree.getAllPathPatterns();
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
index 34fd8b96bb0..eff6bbf3a6a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
@@ -100,7 +100,8 @@ public class ErrorHandlingUtils {
                 "Status code: %s, Query Statement: %s failed because %s",
                 status.getCode(), operation, status.getMessage());
         if (status.getCode() == TSStatusCode.SQL_PARSE_ERROR.getStatusCode()
-            || status.getCode() == 
TSStatusCode.SEMANTIC_ERROR.getStatusCode()) {
+            || status.getCode() == TSStatusCode.SEMANTIC_ERROR.getStatusCode()
+            || status.getCode() == TSStatusCode.NO_PERMISSION.getStatusCode()) 
{
           LOGGER.warn(message);
         } else {
           LOGGER.warn(message, e);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
index 52946580a60..74d753da9d5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
@@ -20,7 +20,6 @@ package org.apache.iotdb.db.utils;
 
 import org.apache.iotdb.common.rpc.thrift.TAggregationType;
 import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import org.apache.iotdb.db.utils.constant.SqlConstant;
 
@@ -105,12 +104,12 @@ public class SchemaUtils {
     return measurementDataType;
   }
 
-  public static TSDataType getSeriesTypeByPath(PartialPath path, String 
aggregation) {
+  public static TSDataType getSeriesTypeByPath(TSDataType seriesType, String 
aggregation) {
     TSDataType dataType = getBuiltinAggregationTypeByFuncName(aggregation);
     if (dataType != null) {
       return dataType;
     } else {
-      return path.getSeriesType();
+      return seriesType;
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TypeInferenceUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TypeInferenceUtils.java
index d4ac57f6599..b8721a59d8c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TypeInferenceUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TypeInferenceUtils.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.utils;
 
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.sql.SemanticException;
@@ -267,8 +266,7 @@ public class TypeInferenceUtils {
                     ExpressionUtils.reconstructBinaryExpression(
                         keepExpression,
                         new TimeSeriesOperand(
-                            new MeasurementPath(
-                                ((TimeSeriesOperand) 
leftExpression).getPath(), TSDataType.INT64)),
+                            ((TimeSeriesOperand) leftExpression).getPath(), 
TSDataType.INT64),
                         rightExpression)));
             return;
           } else {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
index 179044a7e15..134e313deaa 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java
@@ -22,7 +22,6 @@ package org.apache.iotdb.db.queryengine.plan.analyze;
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.QueryId;
@@ -289,8 +288,7 @@ public class AnalyzeTest {
       expectedAnalysis.setGlobalTimePredicate(gt(time(), longValue(100)));
       expectedAnalysis.setSelectExpressions(
           Sets.newHashSet(
-              new TimeSeriesOperand(
-                  new MeasurementPath(new PartialPath(DEVICE, false), 
TSDataType.TEXT)),
+              new TimeSeriesOperand(new PartialPath(DEVICE, false), 
TSDataType.TEXT),
               new TimeSeriesOperand(new PartialPath("s1")),
               new TimeSeriesOperand(new PartialPath("status")),
               new AdditionExpression(
@@ -353,8 +351,7 @@ public class AnalyzeTest {
           ImmutableMap.of(DEVICE1, Arrays.asList(1, 2, 3), DEVICE2, 
Arrays.asList(1, 2, 3)));
       expectedAnalysis.setDeviceViewOutputExpressions(
           Sets.newHashSet(
-              new TimeSeriesOperand(
-                  new MeasurementPath(new PartialPath(DEVICE, false), 
TSDataType.TEXT)),
+              new TimeSeriesOperand(new PartialPath(DEVICE, false), 
TSDataType.TEXT),
               new TimeSeriesOperand(new PartialPath("s1")),
               new TimeSeriesOperand(new PartialPath("status")),
               new AdditionExpression(
@@ -390,8 +387,7 @@ public class AnalyzeTest {
           and(gt(time(), longValue(100)), groupByTime(0, 1000, 10, 10)));
       expectedAnalysis.setSelectExpressions(
           Sets.newHashSet(
-              new TimeSeriesOperand(
-                  new MeasurementPath(new PartialPath(DEVICE, false), 
TSDataType.TEXT)),
+              new TimeSeriesOperand(new PartialPath(DEVICE, false), 
TSDataType.TEXT),
               new AdditionExpression(
                   new FunctionExpression(
                       "count",
@@ -526,8 +522,7 @@ public class AnalyzeTest {
                   new TimeSeriesOperand(new PartialPath("root.sg.d2.s2")))));
       expectedAnalysis.setDeviceViewOutputExpressions(
           Sets.newHashSet(
-              new TimeSeriesOperand(
-                  new MeasurementPath(new PartialPath(DEVICE, false), 
TSDataType.TEXT)),
+              new TimeSeriesOperand(new PartialPath(DEVICE, false), 
TSDataType.TEXT),
               new FunctionExpression(
                   "sum",
                   new LinkedHashMap<>(),
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzerTest.java
index 1cd47c695d3..d0771df65ba 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzerTest.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.QueryId;
 import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
+import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand;
 
 import org.junit.Test;
 
@@ -54,7 +55,9 @@ public class ExpressionAnalyzerTest {
             gt(timeSeries("root.sg.d1.s2"), intValue("1")),
             gt(timeSeries("root.sg.d2.s2"), intValue("1"))),
         ExpressionAnalyzer.bindSchemaForPredicate(
-            and(gt(timeSeries("s1"), intValue("1")), gt(timeSeries("s2"), 
intValue("1"))),
+            and(
+                gt(new TimeSeriesOperand(new PartialPath("s1")), 
intValue("1")),
+                gt(new TimeSeriesOperand(new PartialPath("s2")), 
intValue("1"))),
             prefixPaths,
             fakeSchemaTree,
             true,
@@ -79,7 +82,10 @@ public class ExpressionAnalyzerTest {
                     gt(timeSeries("root.sg.d2.s1"), intValue("1")),
                     gt(timeSeries("root.sg.d2.s2"), intValue("1"))))),
         ExpressionAnalyzer.bindSchemaForPredicate(
-            count(and(gt(timeSeries("s1"), intValue("1")), 
gt(timeSeries("s2"), intValue("1")))),
+            count(
+                and(
+                    gt(new TimeSeriesOperand(new PartialPath("s1")), 
intValue("1")),
+                    gt(new TimeSeriesOperand(new PartialPath("s2")), 
intValue("1")))),
             prefixPaths,
             fakeSchemaTree,
             true,
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/PlanGraphPrinterTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/PlanGraphPrinterTest.java
index 3061bd87619..19db60271bc 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/PlanGraphPrinterTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/PlanGraphPrinterTest.java
@@ -57,8 +57,10 @@ public class PlanGraphPrinterTest {
             Collections.emptyList(),
             Collections.emptyMap());
 
-    SeriesScanNode scanNode = new SeriesScanNode(new PlanNodeId("3"), new 
MeasurementPath("s1"));
-    
deviceViewNode.addChildDeviceNode(IDeviceID.Factory.DEFAULT_FACTORY.create("d1"),
 scanNode);
+    SeriesScanNode scanNode =
+        new SeriesScanNode(new PlanNodeId("3"), new 
MeasurementPath("root.db.d1.s1"));
+    deviceViewNode.addChildDeviceNode(
+        IDeviceID.Factory.DEFAULT_FACTORY.create("root.db.d1"), scanNode);
 
     topKNode.addChild(deviceViewNode);
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/SchemaUtilsTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/SchemaUtilsTest.java
index 818117cb8bc..85a10c7aaf3 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/SchemaUtilsTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/SchemaUtilsTest.java
@@ -18,9 +18,7 @@
  */
 package org.apache.iotdb.db.utils;
 
-import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.db.utils.constant.SqlConstant;
 
 import org.apache.tsfile.enums.TSDataType;
@@ -58,12 +56,12 @@ public class SchemaUtilsTest {
   }
 
   @Test
-  public void getSeriesTypeByPath() throws IllegalPathException {
-    MeasurementPath measurementPath = new MeasurementPath("s1", 
TSDataType.INT64);
+  public void getSeriesTypeByPath() {
     Assert.assertEquals(
-        TSDataType.DOUBLE, SchemaUtils.getSeriesTypeByPath(measurementPath, 
SqlConstant.SUM));
+        TSDataType.DOUBLE, SchemaUtils.getSeriesTypeByPath(TSDataType.INT64, 
SqlConstant.SUM));
     Assert.assertEquals(
-        TSDataType.INT64, SchemaUtils.getSeriesTypeByPath(measurementPath, 
SqlConstant.LAST_VALUE));
+        TSDataType.INT64,
+        SchemaUtils.getSeriesTypeByPath(TSDataType.INT64, 
SqlConstant.LAST_VALUE));
   }
 
   @Test
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/AlignedPath.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/AlignedPath.java
index 6bb91921769..150613e066c 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/AlignedPath.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/AlignedPath.java
@@ -52,6 +52,9 @@ import java.util.Objects;
  */
 public class AlignedPath extends PartialPath {
 
+  private static final String NODES_LENGTH_ERROR =
+      "nodes.length for MeasurementPath should always be greater than 1, 
current is: %s";
+
   private static final Logger logger = 
LoggerFactory.getLogger(AlignedPath.class);
 
   // todo improve vector implementation by remove this placeholder
@@ -64,6 +67,9 @@ public class AlignedPath extends PartialPath {
 
   public AlignedPath(String vectorPath, List<String> subSensorsList) throws 
IllegalPathException {
     super(vectorPath);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     // check whether subSensor is legal
     for (String subSensor : subSensorsList) {
       PathUtils.isLegalPath(subSensor);
@@ -91,6 +97,9 @@ public class AlignedPath extends PartialPath {
 
   public AlignedPath(String vectorPath, String subSensor) throws 
IllegalPathException {
     super(vectorPath);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     measurementList = new ArrayList<>();
     PathUtils.isLegalPath(subSensor);
     measurementList.add(subSensor);
@@ -98,6 +107,9 @@ public class AlignedPath extends PartialPath {
 
   public AlignedPath(PartialPath vectorPath, String subSensor) throws 
IllegalPathException {
     super(vectorPath.getNodes());
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     measurementList = new ArrayList<>();
     PathUtils.isLegalPath(subSensor);
     measurementList.add(subSensor);
@@ -105,12 +117,18 @@ public class AlignedPath extends PartialPath {
 
   public AlignedPath(PartialPath vectorPath) {
     super(vectorPath.getNodes());
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     measurementList = new ArrayList<>();
     schemaList = new ArrayList<>();
   }
 
   public AlignedPath(MeasurementPath path) {
     super(path.getDevicePath().getNodes());
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     measurementList = new ArrayList<>();
     measurementList.add(path.getMeasurement());
     schemaList = new ArrayList<>();
@@ -119,6 +137,9 @@ public class AlignedPath extends PartialPath {
 
   public AlignedPath(String vectorPath) throws IllegalPathException {
     super(vectorPath);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     measurementList = new ArrayList<>();
     schemaList = new ArrayList<>();
   }
@@ -126,6 +147,9 @@ public class AlignedPath extends PartialPath {
   public AlignedPath(
       String[] nodes, List<String> measurementList, List<IMeasurementSchema> 
schemaList) {
     super(nodes);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     this.measurementList = measurementList;
     this.schemaList = schemaList;
   }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
index 7a39c955337..bb2752fc003 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
@@ -49,6 +49,9 @@ import static 
org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDC
 
 public class MeasurementPath extends PartialPath {
 
+  private static final String NODES_LENGTH_ERROR =
+      "nodes.length for MeasurementPath should always be greater than 1, 
current is: %s";
+
   private static final Logger logger = 
LoggerFactory.getLogger(MeasurementPath.class);
 
   private IMeasurementSchema measurementSchema;
@@ -64,10 +67,16 @@ public class MeasurementPath extends PartialPath {
 
   public MeasurementPath(String measurementPath) throws IllegalPathException {
     super(measurementPath);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
   }
 
   public MeasurementPath(String measurementPath, TSDataType type) throws 
IllegalPathException {
     super(measurementPath);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     this.measurementSchema = new MeasurementSchema(getMeasurement(), type);
   }
 
@@ -84,6 +93,9 @@ public class MeasurementPath extends PartialPath {
       IMeasurementSchema measurementSchema,
       Boolean isUnderAlignedEntity) {
     super(measurementPath.getNodes());
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     this.measurementSchema = measurementSchema;
     this.isUnderAlignedEntity = isUnderAlignedEntity;
   }
@@ -100,21 +112,35 @@ public class MeasurementPath extends PartialPath {
 
   public MeasurementPath(String device, String measurement) throws 
IllegalPathException {
     super(device, measurement);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
   }
 
   public MeasurementPath(String device, String measurement, IMeasurementSchema 
measurementSchema)
       throws IllegalPathException {
     super(device, measurement);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     this.measurementSchema = measurementSchema;
   }
 
   public MeasurementPath(String[] nodes, IMeasurementSchema schema) {
     super(nodes);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(String.format(NODES_LENGTH_ERROR, 
Arrays.toString(nodes)));
+    }
     this.measurementSchema = schema;
   }
 
   public MeasurementPath(String[] nodes) {
     super(nodes);
+    if (nodes.length < 2) {
+      throw new IllegalArgumentException(
+          "nodes.length for MeasurementPath should always be greater than 2, 
current is: "
+              + Arrays.toString(nodes));
+    }
   }
 
   @Override
diff --git 
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
 
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
index e282481d4e4..777f06d2d39 100644
--- 
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
+++ 
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
@@ -387,7 +387,7 @@ public class PartialPathTest {
 
   @Test
   public void testConcatArray() throws IllegalPathException {
-    PartialPath a = new MeasurementPath("root", "sg1");
+    PartialPath a = new PartialPath("root", "sg1");
     String[] arr2 = new String[2];
     arr2[0] = "d1";
     arr2[1] = "s1";
@@ -799,14 +799,8 @@ public class PartialPathTest {
 
   @Test
   public void testAlignedToDeviceId() throws IllegalPathException {
-    PartialPath partialPath = new AlignedPath("root", 
Collections.singletonList("s1"));
+    PartialPath partialPath = new AlignedPath("root.a", 
Collections.singletonList("s1"));
     IDeviceID deviceID = partialPath.getIDeviceID();
-    assertEquals(1, deviceID.segmentNum());
-    assertEquals("root", deviceID.segment(0));
-    assertEquals("root", deviceID.getTableName());
-
-    partialPath = new AlignedPath("root.a", Collections.singletonList("s1"));
-    deviceID = partialPath.getIDeviceID();
     assertEquals(2, deviceID.segmentNum());
     assertEquals("root", deviceID.segment(0));
     assertEquals("a", deviceID.segment(1));
@@ -837,14 +831,8 @@ public class PartialPathTest {
 
   @Test
   public void testMeasurementPathToDeviceId() throws IllegalPathException {
-    PartialPath partialPath = new MeasurementPath("root.s1");
+    PartialPath partialPath = new MeasurementPath("root.a.s1");
     IDeviceID deviceID = partialPath.getIDeviceID();
-    assertEquals(1, deviceID.segmentNum());
-    assertEquals("root", deviceID.segment(0));
-    assertEquals("root", deviceID.getTableName());
-
-    partialPath = new MeasurementPath("root.a.s1");
-    deviceID = partialPath.getIDeviceID();
     assertEquals(2, deviceID.segmentNum());
     assertEquals("root", deviceID.segment(0));
     assertEquals("a", deviceID.segment(1));
diff --git a/pom.xml b/pom.xml
index 2077c3e9635..9b7ed3c6c65 100644
--- a/pom.xml
+++ b/pom.xml
@@ -166,7 +166,7 @@
         <thrift.version>0.14.1</thrift.version>
         <xz.version>1.9</xz.version>
         <zstd-jni.version>1.5.6-3</zstd-jni.version>
-        <tsfile.version>1.0.1-tsfilev4-240726-SNAPSHOT</tsfile.version>
+        <tsfile.version>1.2.0-8aaedb22-SNAPSHOT</tsfile.version>
     </properties>
     <!--
     if we claim dependencies in dependencyManagement, then we do not claim

Reply via email to