You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2019/11/05 13:48:53 UTC

[incubator-iotdb] branch master updated: [IOTDB-259] level query of path (#506)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 48d5bc2  [IOTDB-259] level query of path (#506)
48d5bc2 is described below

commit 48d5bc206f5d1c33a628976e5735049b7d70d394
Author: Haonan <hh...@outlook.com>
AuthorDate: Tue Nov 5 21:48:44 2019 +0800

    [IOTDB-259] level query of path (#506)
    
    * support query child paths
---
 .../5-Operation Manual/4-SQL Reference.md          | 16 +++++++++++++
 .../5-Operation Manual/4-SQL Reference.md          | 16 +++++++++++++
 .../main/java/org/apache/iotdb/jdbc/Constant.java  |  3 +++
 .../apache/iotdb/jdbc/IoTDBDatabaseMetadata.java   | 14 +++++++++++
 .../apache/iotdb/jdbc/IoTDBMetadataResultSet.java  | 20 +++++++++++++++-
 .../java/org/apache/iotdb/jdbc/IoTDBStatement.java | 17 ++++++++++++++
 .../java/org/apache/iotdb/db/metadata/MGraph.java  |  4 ++++
 .../org/apache/iotdb/db/metadata/MManager.java     | 12 ++++++++++
 .../java/org/apache/iotdb/db/metadata/MTree.java   | 27 ++++++++++++++++++++++
 .../org/apache/iotdb/db/service/TSServiceImpl.java | 10 ++++++++
 service-rpc/rpc-changelist.md                      |  1 +
 service-rpc/src/main/thrift/rpc.thrift             |  3 ++-
 12 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/docs/Documentation-CHN/UserGuide/5-Operation Manual/4-SQL Reference.md b/docs/Documentation-CHN/UserGuide/5-Operation Manual/4-SQL Reference.md
index 396dd2c..42d7dd5 100644
--- a/docs/Documentation-CHN/UserGuide/5-Operation Manual/4-SQL Reference.md	
+++ b/docs/Documentation-CHN/UserGuide/5-Operation Manual/4-SQL Reference.md	
@@ -147,6 +147,22 @@ Eg: IoTDB > SHOW DEVICES
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
 
+* 显示ROOT节点的子节点名称语句
+```
+SHOW CHILD PATHS
+Eg: IoTDB > SHOW CHILD PATHS
+Note: This statement can be used in IoTDB Client and JDBC.
+```
+
+* 显示子节点名称语句
+```
+SHOW CHILD PATHS <Path>
+Eg: IoTDB > SHOW CHILD PATHS root
+Eg: IoTDB > SHOW CHILD PATHS root.ln
+Eg: IoTDB > SHOW CHILD PATHS root.ln.wf01
+Note: The path can only be prefix path.
+Note: This statement can be used in IoTDB Client and JDBC.
+```
 ### 数据管理语句
 
 * 插入记录语句
diff --git a/docs/Documentation/UserGuide/5-Operation Manual/4-SQL Reference.md b/docs/Documentation/UserGuide/5-Operation Manual/4-SQL Reference.md
index 28e0d0e..b6c30cd 100644
--- a/docs/Documentation/UserGuide/5-Operation Manual/4-SQL Reference.md	
+++ b/docs/Documentation/UserGuide/5-Operation Manual/4-SQL Reference.md	
@@ -156,6 +156,22 @@ Eg: IoTDB > SHOW DEVICES
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
 
+* Show Child Paths of Root Statement
+```
+SHOW CHILD PATH
+Eg: IoTDB > SHOW CHILD PATHS
+Note: This statement can be used in IoTDB Client and JDBC.
+```
+
+* Show Child Paths Statement
+```
+SHOW CHILD PATHS <Path>
+Eg: IoTDB > SHOW CHILD PATHS root
+Eg: IoTDB > SHOW CHILD PATHS root.ln
+Eg: IoTDB > SHOW CHILD PATHS root.ln.wf01
+Note: The path can only be prefix path.
+Note: This statement can be used in IoTDB Client and JDBC.
+```
 ### Data Management Statement
 
 * Insert Record Statement
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java
index 4b0586d..bca6af8 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java
@@ -39,6 +39,8 @@ public class Constant {
   static final String GLOBAL_COUNT_NODES_REQ = "COUNT_NODES";
 
   static final String GLOBAL_SHOW_STORAGE_GROUP_REQ = "SHOW_STORAGE_GROUP";
+  
+  static final String GLOBAL_SHOW_CHILD_PATHS_REQ = "SHOW_CHILD_PATHS";
 
   static final String GLOBAL_COLUMNS_REQ = "ALL_COLUMNS";
 
@@ -47,6 +49,7 @@ public class Constant {
   public static final String CATALOG_TIMESERIES = "ts";
   public static final String CATALOG_STORAGE_GROUP = "sg";
   public static final String CATALOG_DEVICES = "devices";
+  public static final String CATALOG_CHILD_PATHS = "cp";
   public static final String CATALOG_VERSION = "version";
 
   static final String COUNT_TIMESERIES = "cntts";
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
index 60d4dab..433b41a 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
@@ -104,6 +104,20 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
         } catch (TException e) {
           throw new TException("Connection error when fetching device metadata", e);
         }
+      case Constant.CATALOG_CHILD_PATHS:
+        req = new TSFetchMetadataReq(Constant.GLOBAL_SHOW_CHILD_PATHS_REQ);
+        req.setColumnPath(schemaPattern);
+        try {
+            TSFetchMetadataResp resp = client.fetchMetadata(req);
+          try {
+            RpcUtils.verifySuccess(resp.getStatus());
+          } catch (IoTDBRPCException e) {
+            throw new IoTDBSQLException(e.getMessage(), resp.getStatus());
+          }
+          return new IoTDBMetadataResultSet(resp.getChildPaths(), MetadataType.CHILD_PATHS);
+        } catch (TException e) {
+          throw new TException("Connection error when fetching child path metadata", e);
+        }
       case Constant.CATALOG_STORAGE_GROUP:
         req = new TSFetchMetadataReq(Constant.GLOBAL_SHOW_STORAGE_GROUP_REQ);
         try {
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java
index 8de848f..7df876c 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java
@@ -34,6 +34,7 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   private static final String GET_STRING_TIMESERIES_NAME = "Timeseries";
   private static final String GET_STRING_DEVICES = "DEVICES";
   private static final String GET_STRING_TIMESERIES_STORAGE_GROUP = "Storage Group";
+  private static final String GET_STRING_CHILD_PATHS = "Child Paths";
 
   public static final String GET_STRING_TIMESERIES_DATATYPE = "DataType";
   private static final String GET_STRING_TIMESERIES_ENCODING = "Encoding";
@@ -42,6 +43,7 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   private String currentColumn;
   private String currentStorageGroup;
   private String currentDevice;
+  private String currentChildPath;
   private String currentVersion;
   private List<String> currentTimeseries;
   private List<String> timeseriesNumList;
@@ -81,6 +83,12 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         showLabels = new String[]{"Device"};
         columnItr = devicesSet.iterator();
         break;
+      case CHILD_PATHS:
+        Set<String> childPathsSet = (Set<String>) object;
+        colCount = 1;
+        showLabels = new String[]{"Child Paths"};
+        columnItr = childPathsSet.iterator();
+        break;
       case TIMESERIES:
         List<List<String>> showTimeseriesList = (List<List<String>>) object;
         colCount = 4;
@@ -260,6 +268,9 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         case DEVICES:
           currentDevice = (String) columnItr.next();
           break;
+        case CHILD_PATHS:
+          currentChildPath = (String) columnItr.next();
+          break;
         case COUNT_TIMESERIES:
           timeseriesNum = (String) columnItr.next();
           break;
@@ -329,6 +340,10 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         if (columnIndex == 1) {
           return getString(GET_STRING_DEVICES);
         }
+      case CHILD_PATHS:
+        if (columnIndex == 1) {
+          return getString(GET_STRING_CHILD_PATHS);
+        }
       case COUNT_TIMESERIES:
         if (columnIndex == 1) {
           return getString(GET_STRING_TIMESERIES_NUM);
@@ -364,6 +379,8 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         return currentColumn;
       case GET_STRING_DEVICES:
         return currentDevice;
+      case GET_STRING_CHILD_PATHS:
+        return currentChildPath;
       case GET_STRING_TIMESERIES_NUM:
         return timeseriesNum;
       case GET_STRING_NODES_NUM:
@@ -409,6 +426,7 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   }
 
   public enum MetadataType {
-    STORAGE_GROUP, TIMESERIES, COLUMN, DEVICES, COUNT_TIMESERIES, COUNT_NODES, COUNT_NODE_TIMESERIES, VERSION
+    STORAGE_GROUP, TIMESERIES, COLUMN, DEVICES, CHILD_PATHS, 
+    COUNT_TIMESERIES, COUNT_NODES, COUNT_NODE_TIMESERIES, VERSION
   }
 }
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
index 9d8fce3..ae8afe0 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
@@ -50,6 +50,7 @@ public class IoTDBStatement implements Statement {
   private static final String SHOW_TIMESERIES_COMMAND_LOWERCASE = "show timeseries";
   private static final String SHOW_STORAGE_GROUP_COMMAND_LOWERCASE = "show storage group";
   private static final String SHOW_DEVICES_COMMAND_LOWERCASE = "show devices";
+  private static final String SHOW_CHILD_PATHS_COMMAND_LOWERCASE = "show child paths";
   private static final String COUNT_TIMESERIES_COMMAND_LOWERCASE = "count timeseries";
   private static final String COUNT_NODES_COMMAND_LOWERCASE = "count nodes";
   private static final String METHOD_NOT_SUPPORTED_STRING = "Method not supported";
@@ -254,6 +255,22 @@ public class IoTDBStatement implements Statement {
       DatabaseMetaData databaseMetaData = connection.getMetaData();
       resultSet = databaseMetaData.getColumns(Constant.CATALOG_STORAGE_GROUP, null, null, null);
       return true;
+    } else if (sqlToLowerCase.startsWith(SHOW_CHILD_PATHS_COMMAND_LOWERCASE)) {
+      if (sqlToLowerCase.equals(SHOW_CHILD_PATHS_COMMAND_LOWERCASE)) {
+        DatabaseMetaData databaseMetaData = connection.getMetaData();
+        resultSet = databaseMetaData.getColumns(Constant.CATALOG_CHILD_PATHS, "root", null, null);
+        return true;
+      } else {
+        String[] cmdSplit = sql.split("\\s+");
+        if (cmdSplit.length != 4) {
+          throw new SQLException("Error format of \'SHOW CHILD PATHS <PATH>\'");
+        } else {
+          String path = cmdSplit[3];
+          DatabaseMetaData databaseMetaData = connection.getMetaData();
+          resultSet = databaseMetaData.getColumns(Constant.CATALOG_CHILD_PATHS, path, null, null);
+          return true;
+        }
+      }
     } else if (sqlToLowerCase.equals(SHOW_DEVICES_COMMAND_LOWERCASE)) {
       DatabaseMetaData databaseMetaData = connection.getMetaData();
       resultSet = databaseMetaData.getColumns(Constant.CATALOG_DEVICES, null, null, null);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java b/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java
index b0618be..8cb716c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java
@@ -278,6 +278,10 @@ public class MGraph implements Serializable {
   List<String> getLeafNodePathInNextLevel(String path) throws PathErrorException {
     return mtree.getLeafNodePathInNextLevel(path);
   }
+  
+  Set<String> getChildNodePathInNextLevel(String path) throws PathErrorException {
+    return mtree.getChildNodePathInNextLevel(path);
+  }
 
   /**
    * Get all ColumnSchemas for given delta object type.
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 3102d7c..e72c589 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
@@ -1095,6 +1095,18 @@ public class MManager {
       lock.readLock().unlock();
     }
   }
+  
+  /**
+   * function for getting leaf node path in the next level of given seriesPath.
+   */
+  public Set<String> getChildNodePathInNextLevel(String path) throws PathErrorException {
+    lock.readLock().lock();
+    try {
+      return mgraph.getChildNodePathInNextLevel(path);
+    } finally {
+      lock.readLock().unlock();
+    }
+  }  
 
   /**
    * Check whether the seriesPath given exists.
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 92e6f2e..5cc1b12 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
@@ -649,6 +649,33 @@ public class MTree implements Serializable {
     }
     return ret;
   }
+  
+  /**
+   * function for getting child node path in the next level of the given path.
+   *
+   * @return All child nodes' seriesPath(s) of given seriesPath.
+   */
+  Set<String> getChildNodePathInNextLevel(String path) throws PathErrorException {
+    Set<String> ret = new HashSet<>();
+    String[] nodes = MetaUtils.getNodeNames(path, PATH_SEPARATOR);
+    if (!nodes[0].equals(getRoot().getName())) {
+      throw new PathErrorException(String.format(SERIES_NOT_CORRECT, path));
+    }
+    MNode cur = getRoot();
+    for (int i = 1; i < nodes.length; i++) {
+      if (!cur.hasChild(nodes[i])) {
+        throw new PathErrorException("Path: \"" + path + "\" doesn't correspond to any known time series");
+      }
+      cur = cur.getChild(nodes[i]);
+    }
+    if (!cur.hasChildren()) {
+      throw new PathErrorException("Path: \"" + path + "\" doesn't have a child node");
+    }
+    for (MNode child : cur.getChildren().values()) {
+      ret.add(path + "." + child.getName());
+    }
+    return ret;
+  }  
 
   /**
    * function for getting all paths in list.
diff --git a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 6c968ca..0d77ac9 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -324,6 +324,12 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
           resp.setDevices(devices);
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
           break;
+        case "SHOW_CHILD_PATHS":
+          path = req.getColumnPath();
+          Set<String> childPaths = getChildPaths(path);
+          resp.setChildPaths(childPaths);
+          status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
+          break;
         case "COLUMN":
           resp.setDataType(getSeriesType(req.getColumnPath()).toString());
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
@@ -385,6 +391,10 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
   private Set<String> getAllDevices() throws SQLException {
     return MManager.getInstance().getAllDevices();
   }
+  
+  private Set<String> getChildPaths(String path) throws PathErrorException {
+	  return MManager.getInstance().getChildNodePathInNextLevel(path);
+  }
 
   private String getVersion() throws SQLException {
     return IoTDBConstant.VERSION;
diff --git a/service-rpc/rpc-changelist.md b/service-rpc/rpc-changelist.md
index 0ec3c3b..0b4f895 100644
--- a/service-rpc/rpc-changelist.md
+++ b/service-rpc/rpc-changelist.md
@@ -71,6 +71,7 @@ Last Updated on October 27th, 2019 by Lei Rui.
 | Rename some fields in TSFetchMetadataResp: ~~ColumnsList~~ to columnsList, ~~showTimeseriesList~~ to timeseriesList, ~~showStorageGroups~~ to storageGroups | Zesong Sun             |
 | Change struct TSQueryDataSet to eliminate row-wise rpc writing | Lei Rui                |
 | Add optional i32 timeseriesNum in TSFetchMetadataResp        | Jack Tsai              |
+| Add optional set\<string> childPaths in TSFetchMetadataResp     | Haonan Hou             |
 | Add optional string version in TSFetchMetadataResp           | Genius_pig             |
 
 
diff --git a/service-rpc/src/main/thrift/rpc.thrift b/service-rpc/src/main/thrift/rpc.thrift
index 826a460..8a630a6 100644
--- a/service-rpc/src/main/thrift/rpc.thrift
+++ b/service-rpc/src/main/thrift/rpc.thrift
@@ -184,7 +184,8 @@ struct TSFetchMetadataResp{
 		8: optional set<string> devices
 		9: optional list<string> nodesList
 		10: optional map<string, string> nodeTimeseriesNum
-		11: optional string version
+		11: optional set<string> childPaths
+		12: optional string version
 }
 
 struct TSFetchMetadataReq{