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

geniuspig pushed a commit to branch optimize_path_v2
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/optimize_path_v2 by this push:
     new 02c0181  mmagner and mtree.
02c0181 is described below

commit 02c0181fd0762eb54c2ce9fbff4fa3d4a72aaece
Author: zhutianci <[email protected]>
AuthorDate: Fri Aug 14 19:32:03 2020 +0800

    mmagner and mtree.
---
 .../org/apache/iotdb/db/metadata/MManager.java     |  75 +++++++------
 .../java/org/apache/iotdb/db/metadata/MTree.java   | 125 ++++++++++-----------
 .../org/apache/iotdb/db/metadata/MetaUtils.java    |  14 +--
 .../org/apache/iotdb/db/metadata/PartialPath.java  |  66 ++++++++++-
 .../apache/iotdb/db/monitor/MonitorConstants.java  |   1 +
 .../apache/iotdb/db/qp/constant/SQLConstant.java   |   4 +-
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |   5 +-
 .../qp/logical/sys/CreateTimeSeriesOperator.java   |   4 +-
 .../db/qp/physical/crud/RawDataQueryPlan.java      |  24 ++--
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  68 +++++------
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  74 ++++++------
 .../org/apache/iotdb/db/utils/SchemaUtils.java     |   6 +-
 12 files changed, 259 insertions(+), 207 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index f915a62..0650db4 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -208,7 +208,7 @@ public class MManager {
       if (config.isEnableParameterAdapter()) {
         List<String> storageGroups = mtree.getAllStorageGroupNames();
         for (String sg : storageGroups) {
-          MNode node = mtree.getNodeByPath(sg);
+          MNode node = mtree.getNodeByPath(new PartialPath(sg));
           seriesNumberInStorageGroups.put(sg, node.getLeafCount());
         }
         maxSeriesNumberAmongStorageGroup =
@@ -330,7 +330,7 @@ public class MManager {
           tagMap = tagLogFile.readTag(config.getTagAttributeTotalSize(), 
offset);
         }
 
-        CreateTimeSeriesPlan plan = new CreateTimeSeriesPlan(new Path(args[1]),
+        CreateTimeSeriesPlan plan = new CreateTimeSeriesPlan(new 
PartialPath(args[1]),
             TSDataType.deserialize(Short.parseShort(args[2])),
             TSEncoding.deserialize(Short.parseShort(args[3])),
             CompressionType.deserialize(Short.parseShort(args[4])), props, 
tagMap, null, alias);
@@ -338,16 +338,19 @@ public class MManager {
         createTimeseries(plan, offset);
         break;
       case MetadataOperationType.DELETE_TIMESERIES:
-        String failedTimeseries = deleteTimeseries(args[1]);
+        String failedTimeseries = deleteTimeseries(new PartialPath(args[1]));
         if (!failedTimeseries.isEmpty()) {
           throw new DeleteFailedException(failedTimeseries);
         }
         break;
       case MetadataOperationType.SET_STORAGE_GROUP:
-        setStorageGroup(args[1]);
+        setStorageGroup(new PartialPath(args[1]));
         break;
       case MetadataOperationType.DELETE_STORAGE_GROUP:
-        List<String> storageGroups = new 
ArrayList<>(Arrays.asList(args).subList(1, args.length));
+        List<PartialPath> storageGroups = new ArrayList<>();
+        for(int i = 1; i <= args.length; i++) {
+          storageGroups.add(new PartialPath(args[i]));
+        }
         deleteStorageGroups(storageGroups);
         break;
       case MetadataOperationType.SET_TTL:
@@ -371,12 +374,12 @@ public class MManager {
   public void createTimeseries(CreateTimeSeriesPlan plan, long offset) throws 
MetadataException {
     lock.writeLock().lock();
     try {
-      String path = plan.getPath().getFullPath();
+      PartialPath path = plan.getPath();
       SchemaUtils.checkDataTypeWithEncoding(plan.getDataType(), 
plan.getEncoding());
       /*
        * get the storage group with auto create schema
        */
-      String storageGroupName;
+      PartialPath storageGroupName;
       try {
         storageGroupName = mtree.getStorageGroupName(path);
       } catch (StorageGroupNotSetException e) {
@@ -407,8 +410,8 @@ public class MManager {
 
       // update statistics
       if (config.isEnableParameterAdapter()) {
-        int size = seriesNumberInStorageGroups.get(storageGroupName);
-        seriesNumberInStorageGroups.put(storageGroupName, size + 1);
+        int size = 
seriesNumberInStorageGroups.get(storageGroupName.toString());
+        seriesNumberInStorageGroups.put(storageGroupName.toString(), size + 1);
         if (size + 1 > maxSeriesNumberAmongStorageGroup) {
           maxSeriesNumberAmongStorageGroup = size + 1;
         }
@@ -441,10 +444,10 @@ public class MManager {
    * @return whether the measurement occurs for the first time in this storage 
group (if true, the
    * measurement should be registered to the StorageEngine too)
    */
-  public void createTimeseries(String path, TSDataType dataType, TSEncoding 
encoding,
+  public void createTimeseries(PartialPath path, TSDataType dataType, 
TSEncoding encoding,
       CompressionType compressor, Map<String, String> props) throws 
MetadataException {
     createTimeseries(
-        new CreateTimeSeriesPlan(new Path(path), dataType, encoding, 
compressor, props, null, null,
+        new CreateTimeSeriesPlan(path, dataType, encoding, compressor, props, 
null, null,
             null));
   }
 
@@ -454,14 +457,14 @@ public class MManager {
    * @param prefixPath path to be deleted, could be root or a prefix path or a 
full path
    * @return The String is the deletion failed Timeseries
    */
-  public String deleteTimeseries(String prefixPath) throws MetadataException {
+  public String deleteTimeseries(PartialPath prefixPath) throws 
MetadataException {
     lock.writeLock().lock();
 
     if (isStorageGroup(prefixPath)) {
 
       if (config.isEnableParameterAdapter()) {
         int size = seriesNumberInStorageGroups.get(prefixPath);
-        seriesNumberInStorageGroups.put(prefixPath, 0);
+        seriesNumberInStorageGroups.put(prefixPath.toString(), 0);
         if (size == maxSeriesNumberAmongStorageGroup) {
           seriesNumberInStorageGroups.values().stream()
               .max(Integer::compareTo)
@@ -472,19 +475,19 @@ public class MManager {
       mNodeCache.clear();
     }
     try {
-      List<String> allTimeseries = mtree.getAllTimeseriesName(prefixPath);
+      List<PartialPath> allTimeseries = mtree.getAllTimeseriesName(prefixPath);
       // Monitor storage group seriesPath is not allowed to be deleted
-      allTimeseries.removeIf(p -> 
p.startsWith(MonitorConstants.STAT_STORAGE_GROUP_PREFIX));
+      allTimeseries.removeIf(p -> 
p.startsWith(MonitorConstants.STAT_STORAGE_GROUP_PREFIX_ARRAY));
 
       Set<String> failedNames = new HashSet<>();
-      for (String p : allTimeseries) {
+      for (PartialPath p : allTimeseries) {
         try {
           String emptyStorageGroup = deleteOneTimeseriesAndUpdateStatistics(p);
           if (!isRecovering) {
             if (emptyStorageGroup != null) {
               
StorageEngine.getInstance().deleteAllDataFilesInOneStorageGroup(emptyStorageGroup);
             }
-            logWriter.deleteTimeseries(p);
+            logWriter.deleteTimeseries(p.toString());
           }
         } catch (DeleteFailedException e) {
           failedNames.add(e.getName());
@@ -541,7 +544,7 @@ public class MManager {
    * @param path full path from root to leaf node
    * @return after delete if the storage group is empty, return its name, 
otherwise return null
    */
-  private String deleteOneTimeseriesAndUpdateStatistics(String path)
+  private String deleteOneTimeseriesAndUpdateStatistics(PartialPath path)
       throws MetadataException, IOException {
     lock.writeLock().lock();
     try {
@@ -558,7 +561,7 @@ public class MManager {
       }
 
       if (config.isEnableParameterAdapter()) {
-        String storageGroup = getStorageGroupName(path);
+        String storageGroup = getStorageGroupName(path).toString();
         int size = seriesNumberInStorageGroups.get(storageGroup);
         seriesNumberInStorageGroups.put(storageGroup, size - 1);
         if (size == maxSeriesNumberAmongStorageGroup) {
@@ -577,18 +580,18 @@ public class MManager {
    *
    * @param storageGroup root.node.(node)*
    */
-  public void setStorageGroup(String storageGroup) throws MetadataException {
+  public void setStorageGroup(PartialPath storageGroup) throws 
MetadataException {
     lock.writeLock().lock();
     try {
       mtree.setStorageGroup(storageGroup);
       IoTDBConfigDynamicAdapter.getInstance().addOrDeleteStorageGroup(1);
 
       if (config.isEnableParameterAdapter()) {
-        ActiveTimeSeriesCounter.getInstance().init(storageGroup);
-        seriesNumberInStorageGroups.put(storageGroup, 0);
+        ActiveTimeSeriesCounter.getInstance().init(storageGroup.toString());
+        seriesNumberInStorageGroups.put(storageGroup.toString(), 0);
       }
       if (!isRecovering) {
-        logWriter.setStorageGroup(storageGroup);
+        logWriter.setStorageGroup(storageGroup.toString());
       }
     } catch (IOException e) {
       throw new MetadataException(e.getMessage());
@@ -605,10 +608,10 @@ public class MManager {
    *
    * @param storageGroups list of paths to be deleted. Format: root.node
    */
-  public void deleteStorageGroups(List<String> storageGroups) throws 
MetadataException {
+  public void deleteStorageGroups(List<PartialPath> storageGroups) throws 
MetadataException {
     lock.writeLock().lock();
     try {
-      for (String storageGroup : storageGroups) {
+      for (PartialPath storageGroup : storageGroups) {
 
         // clear cached MNode
         mNodeCache.clear();
@@ -621,10 +624,10 @@ public class MManager {
 
         if (config.isEnableParameterAdapter()) {
           IoTDBConfigDynamicAdapter.getInstance().addOrDeleteStorageGroup(-1);
-          int size = seriesNumberInStorageGroups.get(storageGroup);
+          int size = seriesNumberInStorageGroups.get(storageGroup.toString());
           IoTDBConfigDynamicAdapter.getInstance().addOrDeleteTimeSeries(size * 
-1);
-          ActiveTimeSeriesCounter.getInstance().delete(storageGroup);
-          seriesNumberInStorageGroups.remove(storageGroup);
+          
ActiveTimeSeriesCounter.getInstance().delete(storageGroup.toString());
+          seriesNumberInStorageGroups.remove(storageGroup.toString());
           if (size == maxSeriesNumberAmongStorageGroup) {
             maxSeriesNumberAmongStorageGroup =
                 
seriesNumberInStorageGroups.values().stream().max(Integer::compareTo).orElse(0);
@@ -632,7 +635,7 @@ public class MManager {
         }
         // if success
         if (!isRecovering) {
-          logWriter.deleteStorageGroup(storageGroup);
+          logWriter.deleteStorageGroup(storageGroup.toString());
         }
       }
     } catch (ConfigAdjusterException e) {
@@ -650,7 +653,7 @@ public class MManager {
    * @param path Format: root.node.(node)*
    * @apiNote :for cluster
    */
-  boolean isStorageGroup(String path) {
+  boolean isStorageGroup(PartialPath path) {
     lock.readLock().lock();
     try {
       return mtree.isStorageGroup(path);
@@ -742,7 +745,7 @@ public class MManager {
    *
    * @return storage group in the given path
    */
-  public String getStorageGroupName(String path) throws 
StorageGroupNotSetException {
+  public PartialPath getStorageGroupName(PartialPath path) throws 
StorageGroupNotSetException {
     lock.readLock().lock();
     try {
       return mtree.getStorageGroupName(path);
@@ -782,7 +785,7 @@ public class MManager {
    * @param prefixPath can be a prefix or a full path. if the wildcard is not 
at the tail, then each
    *                   wildcard can only match one level, otherwise it can 
match to the tail.
    */
-  public List<String> getAllTimeseriesName(PartialPath prefixPath) throws 
MetadataException {
+  public List<PartialPath> getAllTimeseriesName(PartialPath prefixPath) throws 
MetadataException {
     lock.readLock().lock();
     try {
       return mtree.getAllTimeseriesName(prefixPath);
@@ -795,7 +798,7 @@ public class MManager {
    * Similar to method getAllTimeseriesName(), but return Path instead of 
String in order to include
    * alias.
    */
-  public List<Path> getAllTimeseriesPath(String prefixPath) throws 
MetadataException {
+  public List<PartialPath> getAllTimeseriesPath(PartialPath prefixPath) throws 
MetadataException {
     lock.readLock().lock();
     try {
       return mtree.getAllTimeseriesPath(prefixPath);
@@ -872,7 +875,7 @@ public class MManager {
       }
 
       List<ShowTimeSeriesResult> res = new LinkedList<>();
-      String[] prefixNodes = 
MetaUtils.getNodeNames(plan.getPath().getFullPath());
+      String[] prefixNodes = plan.getPath().getNodes();
       int curOffset = -1;
       int count = 0;
       int limit = plan.getLimit();
@@ -891,7 +894,7 @@ public class MManager {
             pair.left.putAll(pair.right);
             MeasurementSchema measurementSchema = leaf.getSchema();
             res.add(new ShowTimeSeriesResult(leaf.getFullPath(), 
leaf.getAlias(),
-                getStorageGroupName(leaf.getFullPath()), 
measurementSchema.getType().toString(),
+                getStorageGroupName(leaf.getPartialPath()).toString(), 
measurementSchema.getType().toString(),
                 measurementSchema.getEncodingType().toString(),
                 measurementSchema.getCompressor().toString(), pair.left));
             if (limit != 0) {
@@ -943,7 +946,7 @@ public class MManager {
   private List<ShowTimeSeriesResult> 
showTimeseriesWithoutIndex(ShowTimeSeriesPlan plan,
       QueryContext context) throws MetadataException {
     lock.readLock().lock();
-    List<String[]> ans;
+    List<Pair<PartialPath, String[]>> ans;
     try {
       if (plan.isOrderByHeat()) {
         ans = mtree.getAllMeasurementSchemaByHeatOrder(plan, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index f40a7b6..6843d4e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -112,16 +112,16 @@ public class MTree implements Serializable {
    * @param alias      alias of measurement
    */
   MeasurementMNode createTimeseries(
-      String path,
+      PartialPath path,
       TSDataType dataType,
       TSEncoding encoding,
       CompressionType compressor,
       Map<String, String> props,
       String alias)
       throws MetadataException {
-    String[] nodeNames = MetaUtils.getNodeNames(path);
+    String[] nodeNames = path.getNodes();
     if (nodeNames.length <= 2 || !nodeNames[0].equals(root.getName())) {
-      throw new IllegalPathException(path);
+      throw new IllegalPathException(path.toString());
     }
     MNode cur = root;
     boolean hasSetStorageGroup = false;
@@ -141,10 +141,10 @@ public class MTree implements Serializable {
     }
     String leafName = nodeNames[nodeNames.length - 1];
     if (cur.hasChild(leafName)) {
-      throw new PathAlreadyExistException(path);
+      throw new PathAlreadyExistException(path.toString());
     }
     if (alias != null && cur.hasChild(alias)) {
-      throw new AliasAlreadyExistException(path, alias);
+      throw new AliasAlreadyExistException(path.toString(), alias);
     }
     MeasurementMNode leaf = new MeasurementMNode(cur, leafName, alias, 
dataType, encoding,
         compressor, props);
@@ -208,11 +208,11 @@ public class MTree implements Serializable {
    *
    * @param path path
    */
-  void setStorageGroup(String path) throws MetadataException {
-    String[] nodeNames = MetaUtils.getNodeNames(path);
+  void setStorageGroup(PartialPath path) throws MetadataException {
+    String[] nodeNames = path.getNodes();
     MNode cur = root;
     if (nodeNames.length <= 1 || !nodeNames[0].equals(root.getName())) {
-      throw new IllegalPathException(path);
+      throw new IllegalPathException(path.toString());
     }
     int i = 1;
     // e.g., path = root.a.b.sg, create internal nodes for a, b
@@ -229,7 +229,7 @@ public class MTree implements Serializable {
     }
     if (cur.hasChild(nodeNames[i])) {
       // node b has child sg
-      throw new StorageGroupAlreadySetException(path);
+      throw new StorageGroupAlreadySetException(path.toString());
     } else {
       StorageGroupMNode storageGroupMNode =
           new StorageGroupMNode(
@@ -241,10 +241,10 @@ public class MTree implements Serializable {
   /**
    * Delete a storage group
    */
-  List<MeasurementMNode> deleteStorageGroup(String path) throws 
MetadataException {
+  List<MeasurementMNode> deleteStorageGroup(PartialPath path) throws 
MetadataException {
     MNode cur = getNodeByPath(path);
     if (!(cur instanceof StorageGroupMNode)) {
-      throw new StorageGroupNotSetException(path);
+      throw new StorageGroupNotSetException(path.toString());
     }
     // Suppose current system has root.a.b.sg1, root.a.sg2, and delete 
root.a.b.sg1
     // delete the storage group node sg1
@@ -283,8 +283,8 @@ public class MTree implements Serializable {
    * @param path path
    * @apiNote :for cluster
    */
-  boolean isStorageGroup(String path) {
-    String[] nodeNames = MetaUtils.getNodeNames(path);
+  boolean isStorageGroup(PartialPath path) {
+    String[] nodeNames = path.getNodes();
     if (nodeNames.length <= 1 || 
!nodeNames[0].equals(IoTDBConstant.PATH_ROOT)) {
       return false;
     }
@@ -306,15 +306,15 @@ public class MTree implements Serializable {
    *
    * @param path Format: root.node(.node)+
    */
-  Pair<String, MeasurementMNode> 
deleteTimeseriesAndReturnEmptyStorageGroup(String path)
+  Pair<String, MeasurementMNode> 
deleteTimeseriesAndReturnEmptyStorageGroup(PartialPath path)
       throws MetadataException {
     MNode curNode = getNodeByPath(path);
     if (!(curNode instanceof MeasurementMNode)) {
-      throw new PathNotExistException(path);
+      throw new PathNotExistException(path.toString());
     }
-    String[] nodes = MetaUtils.getNodeNames(path);
+    String[] nodes = MetaUtils.getNodeNames(path.toString());
     if (nodes.length == 0 || !IoTDBConstant.PATH_ROOT.equals(nodes[0])) {
-      throw new IllegalPathException(path);
+      throw new IllegalPathException(path.toString());
     }
     // delete the last node of path
     curNode.getParent().deleteChild(curNode.getName());
@@ -379,12 +379,12 @@ public class MTree implements Serializable {
   /**
    * Get storage group node, if the give path is not a storage group, throw 
exception
    */
-  StorageGroupMNode getStorageGroupNode(String path) throws MetadataException {
+  StorageGroupMNode getStorageGroupNode(PartialPath path) throws 
MetadataException {
     MNode node = getNodeByPath(path);
     if (node instanceof StorageGroupMNode) {
       return (StorageGroupMNode) node;
     } else {
-      throw new StorageGroupNotSetException(path);
+      throw new StorageGroupNotSetException(path.toString());
     }
   }
 
@@ -498,18 +498,18 @@ public class MTree implements Serializable {
    *
    * @return storage group in the given path
    */
-  String getStorageGroupName(String path) throws StorageGroupNotSetException {
-    String[] nodes = MetaUtils.getNodeNames(path);
+  PartialPath getStorageGroupName(PartialPath path) throws 
StorageGroupNotSetException {
+    String[] nodes = path.getNodes();
     MNode cur = root;
     for (int i = 1; i < nodes.length; i++) {
       cur = cur.getChild(nodes[i]);
       if (cur instanceof StorageGroupMNode) {
-        return cur.getFullPath();
+        return cur.getPartialPath();
       } else if (cur == null) {
-        throw new StorageGroupNotSetException(path);
+        throw new StorageGroupNotSetException(path.toString());
       }
     }
-    throw new StorageGroupNotSetException(path);
+    throw new StorageGroupNotSetException(path.toString());
   }
 
   /**
@@ -534,12 +534,12 @@ public class MTree implements Serializable {
    *
    * @param prefixPath a prefix path or a full path, may contain '*'.
    */
-  List<String> getAllTimeseriesName(PartialPath prefixPath) throws 
MetadataException {
+  List<PartialPath> getAllTimeseriesName(PartialPath prefixPath) throws 
MetadataException {
     ShowTimeSeriesPlan plan = new ShowTimeSeriesPlan(prefixPath);
-    List<String[]> res = getAllMeasurementSchema(plan);
-    List<String> paths = new ArrayList<>();
-    for (String[] p : res) {
-      paths.add(p[0]);
+    List<Pair<PartialPath, String[]>> res = getAllMeasurementSchema(plan);
+    List<PartialPath> paths = new ArrayList<>();
+    for (Pair<PartialPath, String[]> p : res) {
+      paths.add(p.left);
     }
     return paths;
   }
@@ -549,17 +549,15 @@ public class MTree implements Serializable {
    *
    * @param prefixPath a prefix path or a full path, may contain '*'.
    */
-  List<Path> getAllTimeseriesPath(String prefixPath) throws MetadataException {
-    Path prePath = new Path(prefixPath);
-    ShowTimeSeriesPlan plan = new ShowTimeSeriesPlan(prePath);
-    List<String[]> res = getAllMeasurementSchema(plan);
-    List<Path> paths = new ArrayList<>();
-    for (String[] p : res) {
-      Path path = new Path(p[0]);
-      if (prePath.getMeasurement().equals(p[1])) {
-        path.setAlias(p[1]);
+  List<PartialPath> getAllTimeseriesPath(PartialPath prefixPath) throws 
MetadataException {
+    ShowTimeSeriesPlan plan = new ShowTimeSeriesPlan(prefixPath);
+    List<Pair<PartialPath, String[]>> res = getAllMeasurementSchema(plan);
+    List<PartialPath> paths = new ArrayList<>();
+    for (Pair<PartialPath, String[]> p : res) {
+      if (p.left.getLastNode().equals(p.right[0])) {
+        p.left.setAlias(p.right[0]);
       }
-      paths.add(path);
+      paths.add(p.left);
     }
     return paths;
   }
@@ -644,19 +642,19 @@ public class MTree implements Serializable {
    *
    * <p>result: [name, alias, storage group, dataType, encoding, compression, 
offset]
    */
-  List<String[]> getAllMeasurementSchemaByHeatOrder(ShowTimeSeriesPlan plan,
+  List<Pair<PartialPath, String[]>> 
getAllMeasurementSchemaByHeatOrder(ShowTimeSeriesPlan plan,
       QueryContext queryContext) throws MetadataException {
-    String[] nodes = MetaUtils.getNodeNames(plan.getPath().getFullPath());
+    String[] nodes = plan.getPath().getNodes();
     if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
-      throw new IllegalPathException(plan.getPath().getFullPath());
+      throw new IllegalPathException(plan.getPath().toString());
     }
-    List<String[]> allMatchedNodes = new ArrayList<>();
+    List<Pair<PartialPath, String[]>> allMatchedNodes = new ArrayList<>();
 
     findPath(root, nodes, 1, allMatchedNodes, false, true, queryContext);
 
-    Stream<String[]> sortedStream = allMatchedNodes.stream().sorted(
-        Comparator.comparingLong((String[] s) -> 
Long.parseLong(s[7])).reversed()
-            .thenComparing((String[] array) -> array[0]));
+    Stream<Pair<PartialPath, String[]>> sortedStream = 
allMatchedNodes.stream().sorted(
+        Comparator.comparingLong((Pair<PartialPath, String[]> p) -> 
Long.parseLong(p.right[6])).reversed()
+            .thenComparing((Pair<PartialPath, String[]> p) -> p.left));
 
     // no limit
     if (plan.getLimit() == 0) {
@@ -672,8 +670,8 @@ public class MTree implements Serializable {
    *
    * <p>result: [name, alias, storage group, dataType, encoding, compression, 
offset]
    */
-  List<String[]> getAllMeasurementSchema(ShowTimeSeriesPlan plan) throws 
MetadataException {
-    List<String[]> res;
+  List<Pair<PartialPath, String[]>> getAllMeasurementSchema(ShowTimeSeriesPlan 
plan) throws MetadataException {
+    List<Pair<PartialPath, String[]>> res;
     String[] nodes = plan.getPath().getNodes();
     if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
       throw new IllegalPathException(plan.getPath().toString());
@@ -704,7 +702,7 @@ public class MTree implements Serializable {
    * @param timeseriesSchemaList List<timeseriesSchema> result: [name, alias, 
storage group,
    *                             dataType, encoding, compression, offset, 
lastTimeStamp]
    */
-  private void findPath(MNode node, String[] nodes, int idx, List<String[]> 
timeseriesSchemaList,
+  private void findPath(MNode node, String[] nodes, int idx, 
List<Pair<PartialPath, String[]>> timeseriesSchemaList,
       boolean hasLimit, boolean needLast, QueryContext queryContext) throws 
MetadataException {
     if (node instanceof MeasurementMNode && nodes.length <= idx) {
       if (hasLimit) {
@@ -713,25 +711,20 @@ public class MTree implements Serializable {
           return;
         }
       }
-      String nodeName;
-      if (node.getName().contains(TsFileConstant.PATH_SEPARATOR)) {
-        nodeName = "\"" + node + "\"";
-      } else {
-        nodeName = node.getName();
-      }
-      String nodePath = node.getParent().getFullPath() + 
TsFileConstant.PATH_SEPARATOR + nodeName;
-      String[] tsRow = new String[8];
-      tsRow[0] = nodePath;
-      tsRow[1] = ((MeasurementMNode) node).getAlias();
+
+      PartialPath nodePath = node.getPartialPath();
+      String[] tsRow = new String[7];
+      tsRow[0] = ((MeasurementMNode) node).getAlias();
       MeasurementSchema measurementSchema = ((MeasurementMNode) 
node).getSchema();
-      tsRow[2] = getStorageGroupName(nodePath);
-      tsRow[3] = measurementSchema.getType().toString();
-      tsRow[4] = measurementSchema.getEncodingType().toString();
-      tsRow[5] = measurementSchema.getCompressor().toString();
-      tsRow[6] = String.valueOf(((MeasurementMNode) node).getOffset());
-      tsRow[7] =
+      tsRow[1] = getStorageGroupName(nodePath).toString();
+      tsRow[2] = measurementSchema.getType().toString();
+      tsRow[3] = measurementSchema.getEncodingType().toString();
+      tsRow[4] = measurementSchema.getCompressor().toString();
+      tsRow[5] = String.valueOf(((MeasurementMNode) node).getOffset());
+      tsRow[6] =
           needLast ? String.valueOf(getLastTimeStamp((MeasurementMNode) node, 
queryContext)) : null;
-      timeseriesSchemaList.add(tsRow);
+      Pair<PartialPath, String[]> temp = new Pair<>(nodePath, tsRow);
+      timeseriesSchemaList.add(temp);
 
       if (hasLimit) {
         count.set(count.get() + 1);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
index 255d1be..ae709bf 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
@@ -106,15 +106,13 @@ public class MetaUtils {
    * @param path path
    * @param level level
    */
-  public static String getStorageGroupNameByLevel(String path, int level) 
throws MetadataException {
-    String[] nodeNames = MetaUtils.getNodeNames(path);
+  static PartialPath getStorageGroupNameByLevel(PartialPath path, int level) 
throws MetadataException {
+    String[] nodeNames = path.getNodes();
     if (nodeNames.length <= level || 
!nodeNames[0].equals(IoTDBConstant.PATH_ROOT)) {
-      throw new IllegalPathException(path);
+      throw new IllegalPathException(path.toString());
     }
-    StringBuilder storageGroupName = new StringBuilder(nodeNames[0]);
-    for (int i = 1; i <= level; i++) {
-      
storageGroupName.append(IoTDBConstant.PATH_SEPARATOR).append(nodeNames[i]);
-    }
-    return storageGroupName.toString();
+    String[] storageGroupNodes = new String[level];
+    System.arraycopy(nodeNames, 0, storageGroupNodes, 0, level);
+    return new PartialPath(storageGroupNodes);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
index b60d65f..a941410 100755
--- a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
@@ -25,10 +25,12 @@ import 
org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 /**
  * A prefix path, suffix path or fullPath generated from SQL
  */
-public class PartialPath {
+public class PartialPath implements Comparable<PartialPath> {
 
   private String[] nodes;
   private String path;
+  private String pathWithoutLastNode;
+  private String alias;
 
   public PartialPath(String path) throws IllegalPathException {
     this.nodes = MetaUtils.splitPathToDetachedPath(path);
@@ -39,12 +41,22 @@ public class PartialPath {
     nodes = partialNodes;
   }
 
-  public void concatPath(PartialPath partialPath) {
+  /**
+   * it will return a new partial path
+   * @param partialPath the path you want to concat
+   * @return new partial path
+   */
+  public PartialPath concatPath(PartialPath partialPath) {
     int len = nodes.length;
-    this.nodes = Arrays.copyOf(nodes, nodes.length + partialPath.nodes.length);
-    System.arraycopy(partialPath.nodes, 0, nodes, len, 
partialPath.nodes.length);
+    String[] newNodes = Arrays.copyOf(nodes, nodes.length + 
partialPath.nodes.length);
+    System.arraycopy(partialPath.nodes, 0, newNodes, len, 
partialPath.nodes.length);
+    return new PartialPath(newNodes);
   }
 
+  /**
+   * It will change nodes in this partial path
+   * @param otherNodes nodes
+   */
   public void concatPath(String[] otherNodes) {
     int len = nodes.length;
     this.nodes = Arrays.copyOf(nodes, nodes.length + otherNodes.length);
@@ -97,5 +109,51 @@ public class PartialPath {
     return this.toString().hashCode();
   }
 
+  public String getLastNode() {
+    return nodes[nodes.length - 1];
+  }
+
+  public String getFirstNode() {
+    return nodes[0];
+  }
+
+  public String getPathWithoutLastNode() {
+    if (pathWithoutLastNode != null) {
+      return pathWithoutLastNode;
+    } else {
+      StringBuilder s = new StringBuilder(nodes[0]);
+      for (int i = 1; i < nodes.length - 1; i++) {
+        s.append(TsFileConstant.PATH_SEPARATOR);
+        s.append(nodes[i]);
+      }
+      pathWithoutLastNode = s.toString();
+      return pathWithoutLastNode;
+    }
+  }
+
+  public void setAlias(String alias) {
+    this.alias = alias;
+  }
+
+  public String getPathWithoutLastNodeWithAlias() {
+    return getPathWithoutLastNode() + alias;
+  }
+
+  public String getAlias() {
+    return alias;
+  }
+
+  public boolean startsWith(String[] otherNodes) {
+    for(int i = 0; i < otherNodes.length; i++) {
+      if(!nodes[i].equals(otherNodes[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
 
+  @Override
+  public int compareTo(PartialPath o) {
+    return this.toString().compareTo(o.toString());
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/monitor/MonitorConstants.java 
b/server/src/main/java/org/apache/iotdb/db/monitor/MonitorConstants.java
index 6344c1a..c2f2259 100644
--- a/server/src/main/java/org/apache/iotdb/db/monitor/MonitorConstants.java
+++ b/server/src/main/java/org/apache/iotdb/db/monitor/MonitorConstants.java
@@ -31,6 +31,7 @@ public class MonitorConstants {
   private static IoTDBConfig config = 
IoTDBDescriptor.getInstance().getConfig();
   public static final String DATA_TYPE_INT64 = "INT64";
   public static final String STAT_STORAGE_GROUP_PREFIX = "root.stats";
+  public static final String[] STAT_STORAGE_GROUP_PREFIX_ARRAY = {"root", 
"stats"};
   static final String FILENODE_PROCESSOR_CONST = "FILENODE_PROCESSOR_CONST";
   private static final String FILENODE_MANAGER_CONST = 
"FILENODE_MANAGER_CONST";
   static final String FILE_SIZE_CONST = "FILE_SIZE_CONST";
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java 
b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
index 4b21890..3278dcd 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
@@ -247,8 +247,8 @@ public class SQLConstant {
     reverseWords.put(GREATERTHAN, LESSTHANOREQUALTO);
   }
 
-  public static boolean isReservedPath(Path pathStr) {
-    return pathStr.equals(SQLConstant.RESERVED_TIME);
+  public static boolean isReservedPath(PartialPath pathStr) {
+    return pathStr.equals(TIME_PATH);
 
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 7420dcd..43b0c2d 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -74,6 +74,7 @@ import 
org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.MManager;
+import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.MNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
@@ -299,12 +300,12 @@ public class PlanExecutor implements IPlanExecutor {
       StorageEngine.getInstance().syncCloseAllProcessor();
     } else {
       if (plan.isSeq() == null) {
-        for (Path storageGroup : plan.getPaths()) {
+        for (PartialPath storageGroup : plan.getPaths()) {
           
StorageEngine.getInstance().asyncCloseProcessor(storageGroup.toString(), true);
           
StorageEngine.getInstance().asyncCloseProcessor(storageGroup.toString(), false);
         }
       } else {
-        for (Path storageGroup : plan.getPaths()) {
+        for (PartialPath storageGroup : plan.getPaths()) {
           
StorageEngine.getInstance().asyncCloseProcessor(storageGroup.toString(), 
plan.isSeq());
         }
       }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/CreateTimeSeriesOperator.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/CreateTimeSeriesOperator.java
index 4b5e9d3..9a969cb 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/CreateTimeSeriesOperator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/CreateTimeSeriesOperator.java
@@ -18,14 +18,12 @@
  */
 package org.apache.iotdb.db.qp.logical.sys;
 
+import java.util.Map;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.RootOperator;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
-import org.apache.iotdb.tsfile.read.common.Path;
-
-import java.util.Map;
 
 public class CreateTimeSeriesOperator extends RootOperator {
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
index 6f3a584..d762d06 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
@@ -25,14 +25,14 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.read.common.Path;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
 
 public class RawDataQueryPlan extends QueryPlan {
 
-  private List<Path> deduplicatedPaths = new ArrayList<>();
+  private List<PartialPath> deduplicatedPaths = new ArrayList<>();
   private List<TSDataType> deduplicatedDataTypes = new ArrayList<>();
   private IExpression expression = null;
   private Map<String, Set<String>> deviceToMeasurements = new HashMap<>();
@@ -53,13 +53,13 @@ public class RawDataQueryPlan extends QueryPlan {
     this.expression = expression;
   }
 
-  public List<Path> getDeduplicatedPaths() {
+  public List<PartialPath> getDeduplicatedPaths() {
     return deduplicatedPaths;
   }
 
-  public void addDeduplicatedPaths(Path path) {
-    deviceToMeasurements.computeIfAbsent(path.getDevice(), key -> new 
HashSet<>())
-        .add(path.getMeasurement());
+  public void addDeduplicatedPaths(PartialPath path) {
+    deviceToMeasurements.computeIfAbsent(path.toString(), key -> new 
HashSet<>())
+        .add(path.getLastNode());
     this.deduplicatedPaths.add(path);
   }
 
@@ -67,11 +67,11 @@ public class RawDataQueryPlan extends QueryPlan {
    * used for AlignByDevice Query, the query is executed by each device, So we 
only maintain
    * measurements of current device.
    */
-  public void setDeduplicatedPaths(List<Path> deduplicatedPaths) {
+  public void setDeduplicatedPaths(List<PartialPath> deduplicatedPaths) {
     deviceToMeasurements.clear();
     deduplicatedPaths.forEach(
-        path -> deviceToMeasurements.computeIfAbsent(path.getDevice(), key -> 
new HashSet<>())
-            .add(path.getMeasurement()));
+        path -> 
deviceToMeasurements.computeIfAbsent(path.getPathWithoutLastNode(), key -> new 
HashSet<>())
+            .add(path.getLastNode()));
     this.deduplicatedPaths = deduplicatedPaths;
   }
 
@@ -92,9 +92,9 @@ public class RawDataQueryPlan extends QueryPlan {
     return deviceToMeasurements.getOrDefault(device, Collections.emptySet());
   }
 
-  public void addFilterPathInDeviceToMeasurements(Path path) {
-    deviceToMeasurements.computeIfAbsent(path.getDevice(), key -> new 
HashSet<>())
-        .add(path.getMeasurement());
+  public void addFilterPathInDeviceToMeasurements(PartialPath path) {
+    deviceToMeasurements.computeIfAbsent(path.getPathWithoutLastNode(), key -> 
new HashSet<>())
+        .add(path.getLastNode());
   }
 
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 0cc2bcb..21b91a5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -313,7 +313,7 @@ public class PhysicalGenerator {
     }
   }
 
-  protected List<TSDataType> getSeriesTypes(List<Path> paths) throws 
MetadataException {
+  protected List<TSDataType> getSeriesTypes(List<PartialPath> paths) throws 
MetadataException {
     return SchemaUtils.getSeriesTypesByPath(paths);
   }
 
@@ -437,26 +437,26 @@ public class PhysicalGenerator {
         Set<String> measurementSetOfGivenSuffix = new LinkedHashSet<>();
 
         // if const measurement
-        String[] nodes = suffixPath.getNodes();
-        if (nodes[0].startsWith("'") || nodes[0].startsWith("\"")) {
-          measurements.add(nodes[0]);
-          measurementTypeMap.put(nodes[0], MeasurementType.Constant);
+        if (suffixPath.getLastNode().startsWith("'") || 
suffixPath.getLastNode().startsWith("\"")) {
+          measurements.add(suffixPath.getLastNode());
+          measurementTypeMap.put(suffixPath.getLastNode(), 
MeasurementType.Constant);
           continue;
         }
 
         for (PartialPath device : devices) { // per device in FROM after 
deduplication
-          //device is full path now
-         device.concatPath(suffixPath);
-         String[] detachFullPath = device.getNodes();
+
+          PartialPath fullPath = device.concatPath(suffixPath);
           try {
             // remove stars in SELECT to get actual paths
-            List<PartialPath> actualPaths = getMatchedTimeseries(device);
+            List<PartialPath> actualPaths = getMatchedTimeseries(fullPath);
             // for actual non exist path
-            if (actualPaths.isEmpty() && originAggregations.isEmpty()) {
-              String nonExistMeasurement = 
detachFullPath[detachFullPath.length - 1];
+            if (originAggregations != null && actualPaths.isEmpty() && 
originAggregations
+                .isEmpty()) {
+              String nonExistMeasurement = fullPath.getLastNode();
               if (measurementSetOfGivenSuffix.add(nonExistMeasurement)
                   && measurementTypeMap.get(nonExistMeasurement) != 
MeasurementType.Exist) {
-                measurementTypeMap.put(detachFullPath[detachFullPath.length - 
1], MeasurementType.NonExist);
+                measurementTypeMap
+                    .put(fullPath.getLastNode(), MeasurementType.NonExist);
               }
             }
 
@@ -481,9 +481,9 @@ public class PhysicalGenerator {
               // while root.sg1.d1.s0 is INT32 and root.sg1.d2.s0 is FLOAT.
               String measurementChecked;
               if (originAggregations != null && !originAggregations.isEmpty()) 
{
-                measurementChecked = originAggregations.get(i) + "(" + 
path.getMeasurement() + ")";
+                measurementChecked = originAggregations.get(i) + "(" + 
path.getLastNode() + ")";
               } else {
-                measurementChecked = path.getMeasurement();
+                measurementChecked = path.getLastNode();
               }
               TSDataType columnDataType = columnDataTypes.get(pathIdx);
               if (columnDataTypeMap.containsKey(measurementChecked)) {
@@ -512,7 +512,7 @@ public class PhysicalGenerator {
           } catch (MetadataException e) {
             throw new LogicalOptimizeException(
                 String.format(
-                    "Error when getting all paths of a full path: %s", 
device.toString())
+                    "Error when getting all paths of a full path: %s", 
fullPath.toString())
                     + e.getMessage());
           }
         }
@@ -551,17 +551,17 @@ public class PhysicalGenerator {
       queryPlan = alignByDevicePlan;
     } else {
       queryPlan.setAlignByTime(queryOperator.isAlignByTime());
-      List<Path> paths = queryOperator.getSelectedPaths();
+      List<PartialPath> paths = queryOperator.getSelectedPaths();
       queryPlan.setPaths(paths);
 
       // transform filter operator to expression
       FilterOperator filterOperator = queryOperator.getFilterOperator();
 
       if (filterOperator != null) {
-        List<Path> filterPaths = new ArrayList<>(filterOperator.getPathSet());
+        List<PartialPath> filterPaths = new 
ArrayList<>(filterOperator.getPathSet());
         try {
           List<TSDataType> seriesTypes = getSeriesTypes(filterPaths);
-          HashMap<Path, TSDataType> pathTSDataTypeHashMap = new HashMap<>();
+          HashMap<PartialPath, TSDataType> pathTSDataTypeHashMap = new 
HashMap<>();
           for (int i = 0; i < filterPaths.size(); i++) {
             ((RawDataQueryPlan) 
queryPlan).addFilterPathInDeviceToMeasurements(filterPaths.get(i));
             pathTSDataTypeHashMap.put(filterPaths.get(i), seriesTypes.get(i));
@@ -589,21 +589,21 @@ public class PhysicalGenerator {
   // [root.ln.d1 -> root.ln.d1.s1 < 20 AND root.ln.d1.s2 > 10,
   //  root.ln.d2 -> root.ln.d2.s1 < 20 AND root.ln.d2.s2 > 10)]
   private Map<String, IExpression> concatFilterByDevice(
-      List<String> devices, FilterOperator operator) throws 
QueryProcessException {
+      List<PartialPath> devices, FilterOperator operator) throws 
QueryProcessException {
     Map<String, IExpression> deviceToFilterMap = new HashMap<>();
-    Set<Path> filterPaths = new HashSet<>();
-    for (String device : devices) {
+    Set<PartialPath> filterPaths = new HashSet<>();
+    for (PartialPath device : devices) {
       FilterOperator newOperator = operator.copy();
       concatFilterPath(device, newOperator, filterPaths);
       // transform to a list so it can be indexed
-      List<Path> filterPathList = new ArrayList<>(filterPaths);
+      List<PartialPath> filterPathList = new ArrayList<>(filterPaths);
       try {
         List<TSDataType> seriesTypes = getSeriesTypes(filterPathList);
-        Map<Path, TSDataType> pathTSDataTypeHashMap = new HashMap<>();
+        Map<PartialPath, TSDataType> pathTSDataTypeHashMap = new HashMap<>();
         for (int i = 0; i < filterPathList.size(); i++) {
           pathTSDataTypeHashMap.put(filterPathList.get(i), seriesTypes.get(i));
         }
-        deviceToFilterMap.put(device, 
newOperator.transformToExpression(pathTSDataTypeHashMap));
+        deviceToFilterMap.put(device.toString(), 
newOperator.transformToExpression(pathTSDataTypeHashMap));
         filterPaths.clear();
       } catch (MetadataException e) {
         throw new QueryProcessException(e);
@@ -629,7 +629,7 @@ public class PhysicalGenerator {
     return retDevices;
   }
 
-  private void concatFilterPath(String prefix, FilterOperator operator, 
Set<Path> filterPaths) {
+  private void concatFilterPath(PartialPath prefix, FilterOperator operator, 
Set<PartialPath> filterPaths) {
     if (!operator.isLeaf()) {
       for (FilterOperator child : operator.getChildren()) {
         concatFilterPath(prefix, child, filterPaths);
@@ -637,22 +637,22 @@ public class PhysicalGenerator {
       return;
     }
     BasicFunctionOperator basicOperator = (BasicFunctionOperator) operator;
-    Path filterPath = basicOperator.getSinglePath();
+    PartialPath filterPath = basicOperator.getSinglePath();
 
     // do nothing in the cases of "where time > 5" or "where root.d1.s1 > 5"
-    if (SQLConstant.isReservedPath(filterPath) || 
filterPath.startWith(SQLConstant.ROOT)) {
+    if (SQLConstant.isReservedPath(filterPath) || 
filterPath.getFirstNode().startsWith(SQLConstant.ROOT)) {
       filterPaths.add(filterPath);
       return;
     }
 
-    Path concatPath = Path.addPrefixPath(filterPath, prefix);
+    PartialPath concatPath = filterPath.concatPath(prefix);
     filterPaths.add(concatPath);
     basicOperator.setSinglePath(concatPath);
   }
 
   private void deduplicate(QueryPlan queryPlan) throws MetadataException {
     // generate dataType first
-    List<Path> paths = queryPlan.getPaths();
+    List<PartialPath> paths = queryPlan.getPaths();
     List<TSDataType> dataTypes = getSeriesTypes(paths);
     queryPlan.setDataTypes(dataTypes);
 
@@ -666,10 +666,10 @@ public class PhysicalGenerator {
     // if it's a last query, no need to sort by device
     if (queryPlan instanceof LastQueryPlan) {
       for (int i = 0; i < paths.size(); i++) {
-        Path path = paths.get(i);
+        PartialPath path = paths.get(i);
         String column;
         if (path.getAlias() != null) {
-          column = path.getFullPathWithAlias();
+          column = path.getPathWithoutLastNodeWithAlias();
         } else {
           column = path.toString();
         }
@@ -684,17 +684,17 @@ public class PhysicalGenerator {
     }
 
     // sort path by device
-    List<Pair<Path, Integer>> indexedPaths = new ArrayList<>();
+    List<Pair<PartialPath, Integer>> indexedPaths = new ArrayList<>();
     for (int i = 0; i < paths.size(); i++) {
       indexedPaths.add(new Pair<>(paths.get(i), i));
     }
     indexedPaths.sort(Comparator.comparing(pair -> pair.left));
 
     int index = 0;
-    for (Pair<Path, Integer> indexedPath : indexedPaths) {
+    for (Pair<PartialPath, Integer> indexedPath : indexedPaths) {
       String column;
       if (indexedPath.left.getAlias() != null) {
-        column = indexedPath.left.getFullPathWithAlias();
+        column = indexedPath.left.getPathWithoutLastNodeWithAlias();
       } else {
         column = indexedPath.left.toString();
       }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index 62d0dec..e841dab 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@ -21,11 +21,11 @@ package org.apache.iotdb.db.qp.strategy.optimizer;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.runtime.SQLParserException;
+import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.crud.*;
 import org.apache.iotdb.db.service.IoTDB;
-import org.apache.iotdb.tsfile.read.common.Path;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,7 +52,7 @@ public class ConcatPathOptimizer implements ILogicalOptimizer 
{
     }
     SFWOperator sfwOperator = (SFWOperator) operator;
     FromOperator from = sfwOperator.getFromOperator();
-    List<Path> prefixPaths;
+    List<PartialPath> prefixPaths;
     if (from == null) {
       logger.warn(WARNING_NO_PREFIX_PATHS);
       return operator;
@@ -64,7 +64,7 @@ public class ConcatPathOptimizer implements ILogicalOptimizer 
{
       }
     }
     SelectOperator select = sfwOperator.getSelectOperator();
-    List<Path> initialSuffixPaths;
+    List<PartialPath> initialSuffixPaths;
     if (select == null) {
       logger.warn(WARNING_NO_SUFFIX_PATHS);
       return operator;
@@ -90,8 +90,8 @@ public class ConcatPathOptimizer implements ILogicalOptimizer 
{
         }
       } else {
         isAlignByDevice = true;
-        for (Path path : initialSuffixPaths) {
-          String device = path.getDevice();
+        for (PartialPath path : initialSuffixPaths) {
+          String device = path.getPathWithoutLastNode();
           if (!device.isEmpty()) {
             throw new LogicalOptimizeException(
                     "The paths of the SELECT clause can only be single level. 
In other words, "
@@ -106,7 +106,7 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
 
     // concat filter
     FilterOperator filter = sfwOperator.getFilterOperator();
-    Set<Path> filterPaths = new HashSet<>();
+    Set<PartialPath> filterPaths = new HashSet<>();
     if (filter == null) {
       return operator;
     }
@@ -119,9 +119,9 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     return sfwOperator;
   }
 
-  private List<Path> judgeSelectOperator(SelectOperator selectOperator)
+  private List<PartialPath> judgeSelectOperator(SelectOperator selectOperator)
       throws LogicalOptimizeException {
-    List<Path> suffixPaths;
+    List<PartialPath> suffixPaths;
     if (selectOperator == null) {
       throw new LogicalOptimizeException(WARNING_NO_SUFFIX_PATHS);
     } else {
@@ -152,19 +152,19 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
    * Extract paths from select&from cql, expand them into complete versions, 
and reassign them to
    * selectOperator's suffixPathList. Treat aggregations similarly.
    */
-  private void concatSelect(List<Path> fromPaths, SelectOperator 
selectOperator)
+  private void concatSelect(List<PartialPath> fromPaths, SelectOperator 
selectOperator)
       throws LogicalOptimizeException {
-    List<Path> suffixPaths = judgeSelectOperator(selectOperator);
+    List<PartialPath> suffixPaths = judgeSelectOperator(selectOperator);
 
-    List<Path> allPaths = new ArrayList<>();
+    List<PartialPath> allPaths = new ArrayList<>();
     List<String> originAggregations = selectOperator.getAggregations();
     List<String> afterConcatAggregations = new ArrayList<>();
 
     for (int i = 0; i < suffixPaths.size(); i++) {
       // selectPath cannot start with ROOT, which is guaranteed by TSParser
-      Path selectPath = suffixPaths.get(i);
-      for (Path fromPath : fromPaths) {
-        allPaths.add(Path.addPrefixPath(selectPath, fromPath));
+      PartialPath selectPath = suffixPaths.get(i);
+      for (PartialPath fromPath : fromPaths) {
+        allPaths.add(fromPath.concatPath(selectPath));
         extendListSafely(originAggregations, i, afterConcatAggregations);
       }
     }
@@ -181,7 +181,7 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
    */
   private void slimitTrim(SelectOperator select, int seriesLimit, int 
seriesOffset)
       throws LogicalOptimizeException {
-    List<Path> suffixList = select.getSuffixPaths();
+    List<PartialPath> suffixList = select.getSuffixPaths();
     List<String> aggregations = select.getAggregations();
     int size = suffixList.size();
 
@@ -195,7 +195,7 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     }
 
     // trim seriesPath list
-    List<Path> trimedSuffixList = new 
ArrayList<>(suffixList.subList(seriesOffset, endPosition));
+    List<PartialPath> trimedSuffixList = new 
ArrayList<>(suffixList.subList(seriesOffset, endPosition));
     select.setSuffixPathList(trimedSuffixList);
 
     // trim aggregations if exists
@@ -206,8 +206,8 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     }
   }
 
-  private FilterOperator concatFilter(List<Path> fromPaths, FilterOperator 
operator,
-      Set<Path> filterPaths)
+  private FilterOperator concatFilter(List<PartialPath> fromPaths, 
FilterOperator operator,
+      Set<PartialPath> filterPaths)
       throws LogicalOptimizeException {
     if (!operator.isLeaf()) {
       List<FilterOperator> newFilterList = new ArrayList<>();
@@ -218,15 +218,15 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
       return operator;
     }
     FunctionOperator functionOperator = (FunctionOperator) operator;
-    Path filterPath = functionOperator.getSinglePath();
+    PartialPath filterPath = functionOperator.getSinglePath();
     // do nothing in the cases of "where time > 5" or "where root.d1.s1 > 5"
-    if (SQLConstant.isReservedPath(filterPath) || 
filterPath.startWith(SQLConstant.ROOT)) {
+    if (SQLConstant.isReservedPath(filterPath) || 
filterPath.getFirstNode().startsWith(SQLConstant.ROOT)) {
       filterPaths.add(filterPath);
       return operator;
     }
-    List<Path> concatPaths = new ArrayList<>();
-    fromPaths.forEach(fromPath -> 
concatPaths.add(Path.addPrefixPath(filterPath, fromPath)));
-    List<Path> noStarPaths = removeStarsInPathWithUnique(concatPaths);
+    List<PartialPath> concatPaths = new ArrayList<>();
+    fromPaths.forEach(fromPath -> 
concatPaths.add(fromPath.concatPath(filterPath)));
+    List<PartialPath> noStarPaths = removeStarsInPathWithUnique(concatPaths);
     filterPaths.addAll(noStarPaths);
     if (noStarPaths.size() == 1) {
       // Transform "select s1 from root.car.* where s1 > 10" to
@@ -243,7 +243,7 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     }
   }
 
-  private FilterOperator constructBinaryFilterTreeWithAnd(List<Path> 
noStarPaths,
+  private FilterOperator constructBinaryFilterTreeWithAnd(List<PartialPath> 
noStarPaths,
       FilterOperator operator)
       throws LogicalOptimizeException {
     FilterOperator filterBinaryTree = new FilterOperator(SQLConstant.KW_AND);
@@ -271,15 +271,15 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
    * @param paths list of paths which may contain stars
    * @return a unique seriesPath list
    */
-  private List<Path> removeStarsInPathWithUnique(List<Path> paths) throws 
LogicalOptimizeException {
-    List<Path> retPaths = new ArrayList<>();
-    HashSet<String> pathSet = new HashSet<>();
+  private List<PartialPath> removeStarsInPathWithUnique(List<PartialPath> 
paths) throws LogicalOptimizeException {
+    List<PartialPath> retPaths = new ArrayList<>();
+    HashSet<PartialPath> pathSet = new HashSet<>();
     try {
-      for (Path path : paths) {
-        List<Path> all = removeWildcard(path.getFullPath());
-        for (Path subPath : all) {
-          if (!pathSet.contains(subPath.getFullPath())) {
-            pathSet.add(subPath.getFullPath());
+      for (PartialPath path : paths) {
+        List<PartialPath> all = removeWildcard(path);
+        for (PartialPath subPath : all) {
+          if (!pathSet.contains(subPath)) {
+            pathSet.add(subPath);
             retPaths.add(subPath);
           }
         }
@@ -290,14 +290,14 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     return retPaths;
   }
 
-  private void removeStarsInPath(List<Path> paths, List<String> 
afterConcatAggregations,
+  private void removeStarsInPath(List<PartialPath> paths, List<String> 
afterConcatAggregations,
       SelectOperator selectOperator) throws LogicalOptimizeException {
-    List<Path> retPaths = new ArrayList<>();
+    List<PartialPath> retPaths = new ArrayList<>();
     List<String> newAggregations = new ArrayList<>();
     for (int i = 0; i < paths.size(); i++) {
       try {
-        List<Path> actualPaths = removeWildcard(paths.get(i).getFullPath());
-        for (Path actualPath : actualPaths) {
+        List<PartialPath> actualPaths = removeWildcard(paths.get(i));
+        for (PartialPath actualPath : actualPaths) {
           retPaths.add(actualPath);
           if (afterConcatAggregations != null && 
!afterConcatAggregations.isEmpty()) {
             newAggregations.add(afterConcatAggregations.get(i));
@@ -311,7 +311,7 @@ public class ConcatPathOptimizer implements 
ILogicalOptimizer {
     selectOperator.setAggregations(newAggregations);
   }
 
-  protected List<Path> removeWildcard(String path) throws MetadataException {
+  protected List<PartialPath> removeWildcard(PartialPath path) throws 
MetadataException {
     return IoTDB.metaManager.getAllTimeseriesPath(path);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java 
b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
index 1319706..4131d79 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
@@ -91,11 +91,11 @@ public class SchemaUtils {
 
   }
 
-  public static List<TSDataType> getSeriesTypesByPath(Collection<Path> paths)
+  public static List<TSDataType> getSeriesTypesByPath(Collection<PartialPath> 
paths)
       throws MetadataException {
     List<TSDataType> dataTypes = new ArrayList<>();
-    for (Path path : paths) {
-      dataTypes.add(IoTDB.metaManager.getSeriesType(path.getFullPath()));
+    for (PartialPath path : paths) {
+      dataTypes.add(IoTDB.metaManager.getSeriesType(path));
     }
     return dataTypes;
   }

Reply via email to