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/09/26 01:42:13 UTC

[incubator-iotdb] branch master updated: [IOTDB-239] Add interface for showing devices (#421)

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 c0bec96  [IOTDB-239] Add interface for showing devices (#421)
c0bec96 is described below

commit c0bec96a39bf8105f425a9a01a0dff204d852d89
Author: Zesong Sun <sz...@mails.tsinghua.edu.cn>
AuthorDate: Thu Sep 26 09:42:08 2019 +0800

    [IOTDB-239] Add interface for showing devices (#421)
    
    * Add interface for showing devices
---
 .../UserGuide/6-JDBC API/1-JDBC API.md             | 11 +++-
 .../main/java/org/apache/iotdb/jdbc/Constant.java  |  4 +-
 .../apache/iotdb/jdbc/IoTDBDatabaseMetadata.java   | 25 +++++-----
 .../apache/iotdb/jdbc/IoTDBMetadataResultSet.java  | 19 ++++++-
 .../java/org/apache/iotdb/jdbc/IoTDBStatement.java |  9 +++-
 .../iotdb/jdbc/IoTDBDatabaseMetadataTest.java      | 58 +++++++++++++++++++---
 .../org/apache/iotdb/jdbc/IoTDBStatementTest.java  |  8 +--
 .../java/org/apache/iotdb/db/metadata/MGraph.java  |  8 ++-
 .../org/apache/iotdb/db/metadata/MManager.java     | 17 ++++++-
 .../java/org/apache/iotdb/db/metadata/MTree.java   | 28 ++++++++---
 .../org/apache/iotdb/db/service/TSServiceImpl.java | 24 ++++-----
 .../iotdb/db/integration/IoTDBMetadataFetchIT.java |  4 +-
 service-rpc/rpc-changelist.md                      |  2 +
 service-rpc/src/main/thrift/rpc.thrift             |  9 ++--
 14 files changed, 167 insertions(+), 59 deletions(-)

diff --git a/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md b/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md
index 6e68d8d..859ffad 100644
--- a/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md	
+++ b/docs/Documentation/UserGuide/6-JDBC API/1-JDBC API.md	
@@ -31,12 +31,16 @@
 ## How to package only jdbc project
 
 In root directory:
-> mvn clean package -pl jdbc -am -Dmaven.test.skip=true
+```
+mvn clean package -pl jdbc -am -Dmaven.test.skip=true
+```
 
 ## How to install in local maven repository
 
 In root directory:
-> mvn clean install -pl jdbc -am -Dmaven.test.skip=true
+```
+mvn clean install -pl jdbc -am -Dmaven.test.skip=true
+```
 
 ## Using IoTDB JDBC with Maven
 
@@ -99,6 +103,9 @@ public class JDBCExample {
     //Show time series
     statement.execute("SHOW TIMESERIES root.demo");
     outputResult(statement.getResultSet());
+    //Show devices
+    statement.execute("SHOW DEVICES");
+    outputResult(statement.getResultSet());
     //Count time series
     statement.execute("COUNT TIMESERIES root");
     outputResult(statement.getResultSet());
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 34df3a3..d7259fb 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/Constant.java
@@ -28,7 +28,7 @@ public class Constant {
 
   public static final String GLOBAL_COLUMN_REQ = "COLUMN";
 
-  public static final String GLOBAL_DELTA_OBJECT_REQ = "DELTA_OBEJECT";
+  public static final String GLOBAL_SHOW_DEVICES_REQ = "SHOW_DEVICES";
 
   public static final String GLOBAL_SHOW_TIMESERIES_REQ = "SHOW_TIMESERIES";
 
@@ -46,7 +46,7 @@ public class Constant {
   public static final String CATALOG_COLUMN = "col";
   public static final String CATALOG_TIMESERIES = "ts";
   public static final String CATALOG_STORAGE_GROUP = "sg";
-  public static final String CATALOG_DEVICE = "delta";
+  public static final String CATALOG_DEVICES = "devices";
   public static final String COUNT_TIMESERIES = "cntts";
   public static final String COUNT_NODE_TIMESERIES = "cnttsbg";
   public static final String COUNT_NODES = "cntnode";
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 1344c2d..3e3dbb4 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.jdbc;
 import java.sql.*;
 import java.util.List;
 import java.util.Set;
+import org.apache.iotdb.jdbc.IoTDBMetadataResultSet.MetadataType;
 import org.apache.iotdb.rpc.IoTDBRPCException;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.service.rpc.thrift.TSFetchMetadataReq;
@@ -85,12 +86,12 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
           } catch (IoTDBRPCException e) {
             throw new IoTDBSQLException(e.getMessage());
           }
-          return new IoTDBMetadataResultSet(resp.getColumnsList(), IoTDBMetadataResultSet.MetadataType.COLUMN);
+          return new IoTDBMetadataResultSet(resp.getColumnsList(), MetadataType.COLUMN);
         } catch (TException e) {
           throw new TException("Conncetion error when fetching column metadata", e);
         }
-      case Constant.CATALOG_DEVICE:
-        req = new TSFetchMetadataReq(Constant.GLOBAL_DELTA_OBJECT_REQ);
+      case Constant.CATALOG_DEVICES:
+        req = new TSFetchMetadataReq(Constant.GLOBAL_SHOW_DEVICES_REQ);
         req.setColumnPath(schemaPattern);
         try {
           TSFetchMetadataResp resp = client.fetchMetadata(req);
@@ -99,9 +100,9 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
           } catch (IoTDBRPCException e) {
             throw new IoTDBSQLException(e.getMessage());
           }
-          return new IoTDBMetadataResultSet(resp.getColumnsList(), IoTDBMetadataResultSet.MetadataType.COLUMN);
+          return new IoTDBMetadataResultSet(resp.getDevices(), MetadataType.DEVICES);
         } catch (TException e) {
-          throw new TException("Conncetion error when fetching delta object metadata", e);
+          throw new TException("Conncetion error when fetching device metadata", e);
         }
       case Constant.CATALOG_STORAGE_GROUP:
         req = new TSFetchMetadataReq(Constant.GLOBAL_SHOW_STORAGE_GROUP_REQ);
@@ -112,8 +113,8 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
           } catch (IoTDBRPCException e) {
             throw new IoTDBSQLException(e.getMessage());
           }
-          Set<String> showStorageGroup = resp.getShowStorageGroups();
-          return new IoTDBMetadataResultSet(showStorageGroup, IoTDBMetadataResultSet.MetadataType.STORAGE_GROUP);
+          Set<String> showStorageGroup = resp.getStorageGroups();
+          return new IoTDBMetadataResultSet(showStorageGroup, MetadataType.STORAGE_GROUP);
         } catch (TException e) {
           throw new TException("Conncetion error when fetching storage group metadata", e);
         }
@@ -127,8 +128,8 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
           } catch (IoTDBRPCException e) {
             throw new IoTDBSQLException(e.getMessage());
           }
-          List<List<String>> showTimeseriesList = resp.getShowTimeseriesList();
-          return new IoTDBMetadataResultSet(showTimeseriesList, IoTDBMetadataResultSet.MetadataType.TIMESERIES);
+          List<List<String>> showTimeseriesList = resp.getTimeseriesList();
+          return new IoTDBMetadataResultSet(showTimeseriesList, MetadataType.TIMESERIES);
         } catch (TException e) {
           throw new TException("Conncetion error when fetching timeseries metadata", e);
         }
@@ -142,7 +143,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
           } catch (IoTDBRPCException e) {
             throw new IoTDBSQLException(e.getMessage());
           }
-          return new IoTDBMetadataResultSet(resp.getColumnsList().size(), IoTDBMetadataResultSet.MetadataType.COUNT_TIMESERIES);
+          return new IoTDBMetadataResultSet(resp.getColumnsList().size(), MetadataType.COUNT_TIMESERIES);
         } catch (TException e) {
           throw new TException("Connection error when fetching timeseries metadata", e);
         }
@@ -153,7 +154,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
   }
 
   public ResultSet getNodes(String catalog, String schemaPattern, String columnPattern,
-      String devicePattern, String nodeLevel) throws SQLException {
+      String devicePattern, int nodeLevel) throws SQLException {
     try {
       return getNodesFunc(catalog, nodeLevel);
     } catch (TException e) {
@@ -178,7 +179,7 @@ public class IoTDBDatabaseMetadata implements DatabaseMetaData {
     }
   }
 
-  private ResultSet getNodesFunc(String catalog, String nodeLevel) throws TException, SQLException {
+  private ResultSet getNodesFunc(String catalog, int nodeLevel) throws TException, SQLException {
     TSFetchMetadataReq req;
     switch (catalog) {
       case Constant.COUNT_NODES:
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 c52d327..1a56fcf 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBMetadataResultSet.java
@@ -32,6 +32,7 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   public static final String GET_STRING_NODE_PATH = "NODE_PATH";
   public static final String GET_STRING_NODE_TIMESERIES_NUM = "NODE_TIMESERIES_NUM";
   public static final String GET_STRING_TIMESERIES_NAME = "Timeseries";
+  public static final String GET_STRING_DEVICES = "DEVICES";
   public static final String GET_STRING_TIMESERIES_STORAGE_GROUP = "Storage Group";
   public static final String GET_STRING_TIMESERIES_DATATYPE = "DataType";
   public static final String GET_STRING_TIMESERIES_ENCODING = "Encoding";
@@ -39,6 +40,7 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   private MetadataType type;
   private String currentColumn;
   private String currentStorageGroup;
+  private String currentDevice;
   private List<String> currentTimeseries;
   private List<String> timeseriesNumList;
   private List<String> nodesNumList;
@@ -71,6 +73,12 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         showLabels = new String[]{"Storage Group"};
         columnItr = storageGroupSet.iterator();
         break;
+      case DEVICES:
+        Set<String> devicesSet = (Set<String>) object;
+        colCount = 1;
+        showLabels = new String[]{"Device"};
+        columnItr = devicesSet.iterator();
+        break;
       case TIMESERIES:
         List<List<String>> showTimeseriesList = (List<List<String>>) object;
         colCount = 4;
@@ -239,6 +247,9 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         case COLUMN:
           currentColumn = (String) columnItr.next();
           break;
+        case DEVICES:
+          currentDevice = (String) columnItr.next();
+          break;
         case COUNT_TIMESERIES:
           timeseriesNum = (String) columnItr.next();
           break;
@@ -300,6 +311,10 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
           return getString(GET_STRING_COLUMN);
         }
         break;
+      case DEVICES:
+        if (columnIndex == 1) {
+          return getString(GET_STRING_DEVICES);
+        }
       case COUNT_TIMESERIES:
         if (columnIndex == 1) {
           return getString(GET_STRING_TIMESERIES_NUM);
@@ -333,6 +348,8 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
         return currentTimeseries.get(3);
       case GET_STRING_COLUMN:
         return currentColumn;
+      case GET_STRING_DEVICES:
+        return currentDevice;
       case GET_STRING_TIMESERIES_NUM:
         return timeseriesNum;
       case GET_STRING_NODES_NUM:
@@ -378,6 +395,6 @@ public class IoTDBMetadataResultSet extends IoTDBQueryResultSet {
   }
 
   public enum MetadataType {
-    STORAGE_GROUP, TIMESERIES, COLUMN, COUNT_TIMESERIES, COUNT_NODES, COUNT_NODE_TIMESERIES
+    STORAGE_GROUP, TIMESERIES, COLUMN, DEVICES, COUNT_TIMESERIES, COUNT_NODES, COUNT_NODE_TIMESERIES
   }
 }
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 a786cb3..c442c9d 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
@@ -49,6 +49,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 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";
@@ -252,6 +253,10 @@ public class IoTDBStatement implements Statement {
       DatabaseMetaData databaseMetaData = connection.getMetaData();
       resultSet = databaseMetaData.getColumns(Constant.CATALOG_STORAGE_GROUP, null, 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);
+      return true;
     } else if (sqlToLowerCase.startsWith(COUNT_TIMESERIES_COMMAND_LOWERCASE)) {
       String[] cmdSplited = sqlToLowerCase.split("\\s+", 4);
       if (cmdSplited.length != 3 && !(cmdSplited.length == 4 && cmdSplited[3].startsWith("group by level"))) {
@@ -265,7 +270,7 @@ public class IoTDBStatement implements Statement {
         return true;
       } else {
         String path = cmdSplited[2];
-        String level = cmdSplited[3].replaceAll(" ", "").substring(13);
+        int level = Integer.parseInt(cmdSplited[3].replaceAll(" ", "").substring(13));
         IoTDBDatabaseMetadata databaseMetadata = (IoTDBDatabaseMetadata) connection.getMetaData();
         resultSet = databaseMetadata.getNodes(Constant.COUNT_NODE_TIMESERIES, path, null, null, level);
         return true;
@@ -276,7 +281,7 @@ public class IoTDBStatement implements Statement {
         throw new SQLException("Error format of \'COUNT NODES LEVEL=<INTEGER>\'");
       } else {
         String path = cmdSplited[2];
-        String level = cmdSplited[3].replaceAll(" ", "").substring(6);
+        int level = Integer.parseInt(cmdSplited[3].replaceAll(" ", "").substring(6));
         IoTDBDatabaseMetadata databaseMetaData = (IoTDBDatabaseMetadata) connection.getMetaData();
         resultSet = databaseMetaData.getNodes(Constant.COUNT_NODES, path, null, null, level);
         return true;
diff --git a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
index 28111f5..ec63598 100644
--- a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
+++ b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
@@ -108,6 +108,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -143,6 +144,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -163,7 +165,7 @@ public class IoTDBDatabaseMetadataTest {
     String standard = "count,\n" + "4,\n";
     try {
       IoTDBDatabaseMetadata metadata = (IoTDBDatabaseMetadata) databaseMetaData;
-      String level = "3";
+      int level = 3;
       ResultSet resultSet = metadata.getNodes(Constant.COUNT_NODES, "root", null, null, level);
       ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
       int colCount = resultSetMetaData.getColumnCount();
@@ -181,6 +183,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -205,7 +208,7 @@ public class IoTDBDatabaseMetadataTest {
             + "root.vehicle.d4,2,\n";
     try {
       IoTDBDatabaseMetadata metadata = (IoTDBDatabaseMetadata) databaseMetaData;
-      String level = "3";
+      int level = 3;
       ResultSet resultSet = metadata.getNodes(Constant.COUNT_NODE_TIMESERIES, "root", null, null, level);
       ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
       int colCount = resultSetMetaData.getColumnCount();
@@ -223,6 +226,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -231,7 +235,7 @@ public class IoTDBDatabaseMetadataTest {
    */
   @SuppressWarnings("resource")
   @Test
-  public void device() throws Exception {
+  public void deviceUnderColumn() throws Exception {
     List<String> columnList = new ArrayList<>();
     columnList.add("root.vehicle.d0");
 
@@ -240,7 +244,42 @@ public class IoTDBDatabaseMetadataTest {
     String standard = "column,\n" + "root.vehicle.d0,\n";
     try {
       ResultSet resultSet = databaseMetaData
-          .getColumns(Constant.CATALOG_DEVICE, "vehicle", null, null);
+          .getColumns(Constant.CATALOG_COLUMN, "vehicle", null, null);
+      ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+      int colCount = resultSetMetaData.getColumnCount();
+      StringBuilder resultStr = new StringBuilder();
+      for (int i = 1; i < colCount + 1; i++) {
+        resultStr.append(resultSetMetaData.getColumnName(i)).append(",");
+      }
+      resultStr.append("\n");
+      while (resultSet.next()) {
+        for (int i = 1; i <= colCount; i++) {
+          resultStr.append(resultSet.getString(i)).append(",");
+        }
+        resultStr.append("\n");
+      }
+      Assert.assertEquals(resultStr.toString(), standard);
+    } catch (SQLException e) {
+      System.out.println(e);
+      Assert.fail(e.getMessage());
+    }
+  }
+
+  /**
+   * get all devices
+   */
+  @SuppressWarnings("resource")
+  @Test
+  public void device() throws Exception {
+    Set<String> devicesSet = new HashSet<>();
+    devicesSet.add("root.vehicle.d0");
+
+    when(fetchMetadataResp.getDevices()).thenReturn(devicesSet);
+
+    String standard = "Device,\n" + "root.vehicle.d0,\n";
+    try {
+      ResultSet resultSet = databaseMetaData
+          .getColumns(Constant.CATALOG_DEVICES, null, null, null);
       ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
       int colCount = resultSetMetaData.getColumnCount();
       StringBuilder resultStr = new StringBuilder();
@@ -257,6 +296,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -292,7 +332,7 @@ public class IoTDBDatabaseMetadataTest {
       }
     });
 
-    when(fetchMetadataResp.getShowTimeseriesList()).thenReturn(tslist);
+    when(fetchMetadataResp.getTimeseriesList()).thenReturn(tslist);
 
     String standard = "Timeseries,Storage Group,DataType,Encoding,\n"
         + "root.vehicle.d0.s0,root.vehicle,INT32,RLE,\n"
@@ -316,6 +356,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -335,7 +376,7 @@ public class IoTDBDatabaseMetadataTest {
       }
     });
 
-    when(fetchMetadataResp.getShowTimeseriesList()).thenReturn(tslist);
+    when(fetchMetadataResp.getTimeseriesList()).thenReturn(tslist);
 
     String standard = "DataType,\n" + "INT32,\n";
     try (ResultSet resultSet = databaseMetaData
@@ -352,6 +393,7 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -363,7 +405,7 @@ public class IoTDBDatabaseMetadataTest {
   public void ShowStorageGroup() throws Exception {
     Set<String> sgSet = new HashSet<>();
     sgSet.add("root.vehicle");
-    when(fetchMetadataResp.getShowStorageGroups()).thenReturn(sgSet);
+    when(fetchMetadataResp.getStorageGroups()).thenReturn(sgSet);
 
     String standard = "Storage Group,\n" + "root.vehicle,\n";
     try (ResultSet resultSet = databaseMetaData
@@ -384,7 +426,9 @@ public class IoTDBDatabaseMetadataTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
+
   }
 
   /**
diff --git a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBStatementTest.java b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBStatementTest.java
index 6a558cf..2991d16 100644
--- a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBStatementTest.java
+++ b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBStatementTest.java
@@ -107,7 +107,7 @@ public class IoTDBStatementTest {
             + "root.vehicle.d0.s0,root.vehicle,INT32,RLE,\n"
             + "root.vehicle.d0.s1,root.vehicle,INT64,RLE,\n"
             + "root.vehicle.d0.s2,root.vehicle,FLOAT,RLE,\n";
-    when(fetchMetadataResp.getShowTimeseriesList()).thenReturn(tslist);
+    when(fetchMetadataResp.getTimeseriesList()).thenReturn(tslist);
     boolean res = stmt.execute("show timeseries");
     assertTrue(res);
     try (ResultSet resultSet = stmt.getResultSet()) {
@@ -127,6 +127,7 @@ public class IoTDBStatementTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
@@ -163,7 +164,7 @@ public class IoTDBStatementTest {
         + "root.vehicle.d0.s0,root.vehicle,INT32,RLE,\n"
         + "root.vehicle.d0.s1,root.vehicle,INT64,RLE,\n"
         + "root.vehicle.d0.s2,root.vehicle,FLOAT,RLE,\n";
-    when(fetchMetadataResp.getShowTimeseriesList()).thenReturn(tslist);
+    when(fetchMetadataResp.getTimeseriesList()).thenReturn(tslist);
     boolean res = stmt.execute("show timeseries root.vehicle.d0");
     assertTrue(res);
     try (ResultSet resultSet = stmt.getResultSet()) {
@@ -192,7 +193,7 @@ public class IoTDBStatementTest {
     IoTDBStatement stmt = new IoTDBStatement(connection, client, sessHandle, zoneID);
     Set<String> sgSet = new HashSet<>();
     sgSet.add("root.vehicle");
-    when(fetchMetadataResp.getShowStorageGroups()).thenReturn(sgSet);
+    when(fetchMetadataResp.getStorageGroups()).thenReturn(sgSet);
     String standard = "Storage Group,\nroot.vehicle,\n";
     boolean res = stmt.execute("show storage group");
     assertTrue(res);
@@ -213,6 +214,7 @@ public class IoTDBStatementTest {
       Assert.assertEquals(resultStr.toString(), standard);
     } catch (SQLException e) {
       System.out.println(e);
+      Assert.fail(e.getMessage());
     }
   }
 
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 1251d68..1dedc80 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
@@ -244,11 +244,15 @@ public class MGraph implements Serializable {
     return new Metadata(deviceIdMap);
   }
 
-  HashSet<String> getAllStorageGroup() {
+  Set<String> getAllStorageGroup() {
     return mtree.getAllStorageGroup();
   }
 
-  List<String> getNodesList(String nodeLevel) {
+  Set<String> getAllDevices() {
+    return mtree.getAllDevices();
+  }
+
+  List<String> getNodesList(int nodeLevel) {
     return mtree.getNodesList(nodeLevel);
   }
 
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 854f585..05c9331 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
@@ -762,11 +762,26 @@ public class MManager {
   }
 
   /**
+   * Get the full devices info.
+   *
+   * @return A HashSet instance which stores all devices info
+   */
+  public Set<String> getAllDevices() throws PathErrorException {
+
+    lock.readLock().lock();
+    try {
+      return mgraph.getAllDevices();
+    } finally {
+      lock.readLock().unlock();
+    }
+  }
+
+  /**
    * Get all nodes from the given level
    *
    * @return A List instance which stores all node at given level
    */
-  public List<String> getNodesList(String nodeLevel) {
+  public List<String> getNodesList(int nodeLevel) {
 
     lock.readLock().lock();
     try {
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 aaa74d9..e3f6431 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
@@ -18,14 +18,18 @@
  */
 package org.apache.iotdb.db.metadata;
 
-import java.io.Serializable;
-import java.util.*;
-
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import org.apache.iotdb.db.exception.PathErrorException;
-import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -741,7 +745,7 @@ public class MTree implements Serializable {
    *
    * @return a list contains all distinct storage groups
    */
-  HashSet<String> getAllStorageGroup() {
+  Set<String> getAllStorageGroup() {
     HashSet<String> res = new HashSet<>();
     MNode rootNode;
     if ((rootNode = getRoot()) != null) {
@@ -761,16 +765,24 @@ public class MTree implements Serializable {
   }
 
   /**
+   * Get all devices in current Metadata Tree.
+   *
+   * @return a list contains all distinct devices
+   */
+  Set<String> getAllDevices() {
+    return new HashSet<>(getNodesList(3));
+  }
+
+  /**
    * Get all nodes at the given level in current Metadata Tree.
    *
    * @return a list contains all nodes at the given level
    */
-  List<String> getNodesList(String nodeLevel) {
+  List<String> getNodesList(int nodeLevel) {
     List<String> res = new ArrayList<>();
-    int level = Integer.parseInt(nodeLevel);
     MNode rootNode;
     if ((rootNode = getRoot()) != null) {
-      findNodes(rootNode, "root", res, level);
+      findNodes(rootNode, "root", res, nodeLevel);
     }
     return res;
   }
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 59c3ce9..41ceed3 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
@@ -297,13 +297,13 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
       switch (req.getType()) {
         case "SHOW_TIMESERIES":
           String path = req.getColumnPath();
-          List<List<String>> showTimeseriesList = getTimeSeriesForPath(path);
-          resp.setShowTimeseriesList(showTimeseriesList);
+          List<List<String>> timeseriesList = getTimeSeriesForPath(path);
+          resp.setTimeseriesList(timeseriesList);
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
           break;
         case "SHOW_STORAGE_GROUP":
           Set<String> storageGroups = getAllStorageGroups();
-          resp.setShowStorageGroups(storageGroups);
+          resp.setStorageGroups(storageGroups);
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
           break;
         case "METADATA_IN_JSON":
@@ -311,15 +311,9 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
           resp.setMetadataInJson(metadataInJson);
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
           break;
-        case "DELTA_OBEJECT":
-          Metadata metadata = getMetadata();
-          String column = req.getColumnPath();
-          Map<String, List<String>> deviceMap = metadata.getDeviceMap();
-          if (deviceMap == null || !deviceMap.containsKey(column)) {
-            resp.setColumnsList(new ArrayList<>());
-          } else {
-            resp.setColumnsList(deviceMap.get(column));
-          }
+        case "SHOW_DEVICES":
+          Set<String> devices = getAllDevices();
+          resp.setDevices(devices);
           status = new TSStatus(getStatus(TSStatusCode.SUCCESS_STATUS));
           break;
         case "COLUMN":
@@ -364,7 +358,7 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
     return nodeColumnsNum;
   }
 
-  private List<String> getNodesList(String level) throws PathErrorException {
+  private List<String> getNodesList(int level) throws PathErrorException {
     return MManager.getInstance().getNodesList(level);
   }
 
@@ -372,6 +366,10 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
     return MManager.getInstance().getAllStorageGroup();
   }
 
+  private Set<String> getAllDevices() throws PathErrorException {
+    return MManager.getInstance().getAllDevices();
+  }
+
   private List<List<String>> getTimeSeriesForPath(String path)
       throws PathErrorException {
     return MManager.getInstance().getShowTimeseriesPath(path);
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMetadataFetchIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMetadataFetchIT.java
index 379d663..67bc5d6 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMetadataFetchIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMetadataFetchIT.java
@@ -230,10 +230,10 @@ public class IoTDBMetadataFetchIT {
    * get all delta objects under a given column
    */
   private void device() throws SQLException {
-    String standard = "column,\n" + "root.ln.wf01.wt01,\n";
+    String standard = "Device,\n" + "root.ln.wf01,\n";
 
 
-    try (ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_DEVICE, "ln", null,
+    try (ResultSet resultSet = databaseMetaData.getColumns(Constant.CATALOG_DEVICES, null, null,
         null)) {
       ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
       int colCount = resultSetMetaData.getColumnCount();
diff --git a/service-rpc/rpc-changelist.md b/service-rpc/rpc-changelist.md
index 25a2b87..3b9166c 100644
--- a/service-rpc/rpc-changelist.md
+++ b/service-rpc/rpc-changelist.md
@@ -36,3 +36,5 @@
 * Add method **TSStatus deleteTimeseries(1:TSDeleteReq req)** for deleting timeseries.
 
 * Change item in enum **TSProtocolVersion** from ~~TSFILE_SERVICE_PROTOCOL_V1~~ to IOTDB_SERVICE_PROTOCOL_V1.
+
+* Add **storageGroups** in struct **TSFetchMetadataResp**. Rename ~~ColumnsList~~ to **columnsList**, ~~showTimeseriesList~~ to **timeseriesList**, ~~showStorageGroups~~ to **storageGroups**.
\ No newline at end of file
diff --git a/service-rpc/src/main/thrift/rpc.thrift b/service-rpc/src/main/thrift/rpc.thrift
index 88fb51b..79ff757 100644
--- a/service-rpc/src/main/thrift/rpc.thrift
+++ b/service-rpc/src/main/thrift/rpc.thrift
@@ -192,10 +192,11 @@ struct TSFetchResultsResp{
 struct TSFetchMetadataResp{
 		1: required TSStatus status
 		2: optional string metadataInJson
-		3: optional list<string> ColumnsList
+		3: optional list<string> columnsList
 		4: optional string dataType
-		5: optional list<list<string>> showTimeseriesList
-		7: optional set<string> showStorageGroups
+		5: optional list<list<string>> timeseriesList
+		6: optional set<string> storageGroups
+		7: optional set<string> devices
 		8: optional list<string> nodesList
 		9: optional map<string, string> nodeTimeseriesNum
 }
@@ -203,7 +204,7 @@ struct TSFetchMetadataResp{
 struct TSFetchMetadataReq{
 		1: required string type
 		2: optional string columnPath
-		3: optional string nodeLevel
+		3: optional i32 nodeLevel
 }
 
 struct TSColumnSchema{