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 2021/02/07 06:55:08 UTC

[iotdb] branch master updated: [ISSUE-2585] show devices with storage group (#2475)

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/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new f3262c6  [ISSUE-2585] show devices with storage group (#2475)
f3262c6 is described below

commit f3262c65cb189df0f18c19b37ba03a329d2b41ca
Author: Haimei Guo <68...@users.noreply.github.com>
AuthorDate: Sun Feb 7 14:54:43 2021 +0800

    [ISSUE-2585] show devices with storage group (#2475)
---
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4   |  2 +-
 .../DDL Data Definition Language.md                | 41 +++++++++++++++++++--
 docs/UserGuide/Operation Manual/SQL Reference.md   |  9 +++--
 .../DDL Data Definition Language.md                | 42 +++++++++++++++++++++-
 .../zh/UserGuide/Operation Manual/SQL Reference.md |  9 +++--
 .../org/apache/iotdb/db/metadata/MManager.java     |  4 +--
 .../java/org/apache/iotdb/db/metadata/MTree.java   | 13 +++++--
 .../db/qp/logical/sys/ShowDevicesOperator.java     |  9 +++++
 .../iotdb/db/qp/physical/sys/ShowDevicesPlan.java  |  9 ++++-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  5 ++-
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  2 +-
 .../iotdb/db/query/dataset/ShowDevicesDataSet.java | 20 ++++++++---
 .../dataset/ShowDevicesResult.java}                | 18 ++++------
 .../dataset/ShowResult.java}                       | 35 ++++++++++++------
 .../db/query/dataset/ShowTimeSeriesResult.java     | 22 ++----------
 .../iotdb/db/integration/IoTDBAddSubDeviceIT.java  | 42 ++++++++++++++++++++--
 .../iotdb/db/integration/IoTDBMetadataFetchIT.java | 37 +++++++++++++++++++
 .../iotdb/db/query/dataset/ListDataSetTest.java    | 21 +++++++++++
 .../iotdb/session/IoTDBSessionIteratorIT.java      |  1 -
 .../zeppelin/iotdb/IoTDBInterpreterTest.java       | 13 +++++++
 20 files changed, 289 insertions(+), 65 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
index a7ecb19..30809e3 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
@@ -77,7 +77,7 @@ statement
     | SHOW LATEST? TIMESERIES prefixPath? showWhereClause? limitClause? #showTimeseries
     | SHOW STORAGE GROUP prefixPath? #showStorageGroup
     | SHOW CHILD PATHS prefixPath? #showChildPaths
-    | SHOW DEVICES prefixPath? limitClause? #showDevices
+    | SHOW DEVICES prefixPath? (WITH STORAGE GROUP)? limitClause? #showDevices
     | SHOW MERGE #showMergeStatus
     | SHOW QUERY PROCESSLIST #showQueryProcesslist
     | KILL QUERY INT? #killQuery
diff --git a/docs/UserGuide/Operation Manual/DDL Data Definition Language.md b/docs/UserGuide/Operation Manual/DDL Data Definition Language.md
index 9d9d43c..5002893 100644
--- a/docs/UserGuide/Operation Manual/DDL Data Definition Language.md	
+++ b/docs/UserGuide/Operation Manual/DDL Data Definition Language.md	
@@ -395,11 +395,11 @@ IoTDB> delete timeseries root.ln.wf02.*
 
 ## Show Devices
 
-* SHOW DEVICES prefixPath? limitClause?
+* SHOW DEVICES prefixPath? (WITH STORAGE GROUP)? limitClause? #showDevices
 
 Similar to `Show Timeseries`, IoTDB also supports two ways of viewing devices:
 
-* `SHOW DEVICES` statement presents all devices information, which is equal to `SHOW DEVICES root`.
+* `SHOW DEVICES` statement presents all devices' information, which is equal to `SHOW DEVICES root`.
 * `SHOW DEVICES <PrefixPath>` statement specifies the `PrefixPath` and returns the devices information under the given level.
 
 SQL statement is as follows:
@@ -433,6 +433,43 @@ Total line number = 2
 It costs 0.001s
 ```
 
+To view devices' information with storage group, we can use `SHOW DEVICES WITH STORAGE GROUP` statement.
+
+* `SHOW DEVICES WITH STORAGE GROUP` statement presents all devices' information with their storage group.
+* `SHOW DEVICES <PrefixPath> WITH STORAGE GROUP` statement specifies the `PrefixPath` and returns the 
+devices' information under the given level with their storage group information.
+
+SQL statement is as follows:
+
+```
+IoTDB> show devices with storage group
+IoTDB> show devices root.ln with storage group
+```
+
+You can get results below:
+
+```
++-------------------+-------------+
+|            devices|storage group|
++-------------------+-------------+
+|  root.ln.wf01.wt01|      root.ln|
+|  root.ln.wf02.wt02|      root.ln|
+|root.sgcc.wf03.wt01|    root.sgcc|
+|    root.turbine.d1| root.turbine|
++-------------------+-------------+
+Total line number = 4
+It costs 0.003s
+
++-----------------+-------------+
+|          devices|storage group|
++-----------------+-------------+
+|root.ln.wf01.wt01|      root.ln|
+|root.ln.wf02.wt02|      root.ln|
++-----------------+-------------+
+Total line number = 2
+It costs 0.001s
+```
+
 # TTL
 
 IoTDB supports storage-level TTL settings, which means it is able to delete old data automatically and periodically. The benefit of using TTL is that hopefully you can control the total disk space usage and prevent the machine from running out of disks. Moreover, the query performance may downgrade as the total number of files goes up and the memory usage also increase as there are more files. Timely removing such files helps to keep at a high query performance level and reduce memory usage.
diff --git a/docs/UserGuide/Operation Manual/SQL Reference.md b/docs/UserGuide/Operation Manual/SQL Reference.md
index c412b6a..0398a3c 100644
--- a/docs/UserGuide/Operation Manual/SQL Reference.md	
+++ b/docs/UserGuide/Operation Manual/SQL Reference.md	
@@ -256,18 +256,21 @@ Note: This statement can be used in IoTDB Client and JDBC.
 * Show All Devices Statement
 
 ```
-SHOW Devices
-Eg: IoTDB > SHOW Devices
+SHOW DEVICES (WITH STORAGE GROUP)? limitClause? 
+Eg: IoTDB > SHOW DEVICES
+Eg: IoTDB > SHOW DEVICES WITH STORAGE GROUP
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
 
 * Show Specific Devices Statement
 
 ```
-SHOW DEVICES <PrefixPath>
+SHOW DEVICES <PrefixPath> (WITH STORAGE GROUP)? limitClause?
 Eg: IoTDB > SHOW DEVICES root
 Eg: IoTDB > SHOW DEVICES root.ln
 Eg: IoTDB > SHOW DEVICES root.*.wf01
+Eg: IoTDB > SHOW DEVICES root.ln WITH STORAGE GROUP
+Eg: IoTDB > SHOW DEVICES root.*.wf01 WITH STORAGE GROUP
 Note: The path can be prefix path or star path.
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
diff --git a/docs/zh/UserGuide/Operation Manual/DDL Data Definition Language.md b/docs/zh/UserGuide/Operation Manual/DDL Data Definition Language.md
index 09ff7d2..217d27d 100644
--- a/docs/zh/UserGuide/Operation Manual/DDL Data Definition Language.md	
+++ b/docs/zh/UserGuide/Operation Manual/DDL Data Definition Language.md	
@@ -362,6 +362,7 @@ It costs 0.002s
 ## 删除时间序列
 
 我们可以使用`DELETE TimeSeries <PrefixPath>`语句来删除我们之前创建的时间序列。SQL语句如下所示:
+
 ```
 IoTDB> delete timeseries root.ln.wf01.wt01.status
 IoTDB> delete timeseries root.ln.wf01.wt01.temperature, root.ln.wf02.wt02.hardware
@@ -370,19 +371,22 @@ IoTDB> delete timeseries root.ln.wf02.*
 
 ## 查看设备
 
-* SHOW DEVICES prefixPath? limitClause?
+* SHOW DEVICES prefixPath? (WITH STORAGE GROUP)? limitClause? #showDevices
 
 与 `Show Timeseries` 相似,IoTDB 目前也支持两种方式查看设备。
+
 * `SHOW DEVICES` 语句显示当前所有的设备信息,等价于 `SHOW DEVICES root`。
 * `SHOW DEVICES <PrefixPath>` 语句规定了 `PrefixPath`,返回在给定的前缀路径下的设备信息。
 
 SQL语句如下所示:
+
 ```
 IoTDB> show devices
 IoTDB> show devices root.ln
 ```
 
 你可以获得如下数据:
+
 ```
 +-------------------+
 |            devices|
@@ -405,6 +409,42 @@ Total line number = 2
 It costs 0.001s
 ```
 
+查看设备及其存储组信息,可以使用 `SHOW DEVICES WITH STORAGE GROUP` 语句。
+
+* `SHOW DEVICES WITH STORAGE GROUP` 语句显示当前所有的设备信息和其所在的存储组,等价于 `SHOW DEVICES root`。
+* `SHOW DEVICES <PrefixPath> WITH STORAGE GROUP` 语句规定了 `PrefixPath`,返回在给定的前缀路径下的设备信息和其所在的存储组。
+
+SQL语句如下所示:
+
+```
+IoTDB> show devices with storage group
+IoTDB> show devices root.ln with storage group
+```
+
+你可以获得如下数据:
+
+```
++-------------------+-------------+
+|            devices|storage group|
++-------------------+-------------+
+|  root.ln.wf01.wt01|      root.ln|
+|  root.ln.wf02.wt02|      root.ln|
+|root.sgcc.wf03.wt01|    root.sgcc|
+|    root.turbine.d1| root.turbine|
++-------------------+-------------+
+Total line number = 4
+It costs 0.003s
+
++-----------------+-------------+
+|          devices|storage group|
++-----------------+-------------+
+|root.ln.wf01.wt01|      root.ln|
+|root.ln.wf02.wt02|      root.ln|
++-----------------+-------------+
+Total line number = 2
+It costs 0.001s
+```
+
 # TTL
 
 IoTDB支持对存储组级别设置数据存活时间(TTL),这使得IoTDB可以定期、自动地删除一定时间之前的数据。合理使用TTL
diff --git a/docs/zh/UserGuide/Operation Manual/SQL Reference.md b/docs/zh/UserGuide/Operation Manual/SQL Reference.md
index 13464ba..fcaf288 100644
--- a/docs/zh/UserGuide/Operation Manual/SQL Reference.md	
+++ b/docs/zh/UserGuide/Operation Manual/SQL Reference.md	
@@ -245,18 +245,21 @@ Note: This statement can be used in IoTDB Client and JDBC.
 * 显示所有设备语句
 
 ```
-SHOW DEVICES limitClause?
-Eg: IoTDB > SHOW DEVICES 
+SHOW DEVICES (WITH STORAGE GROUP)? limitClause? 
+Eg: IoTDB > SHOW DEVICES
+Eg: IoTDB > SHOW DEVICES WITH STORAGE GROUP
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
 
 * 显示特定设备语句
 
 ```
-SHOW DEVICES <PrefixPath> limitClause?
+SHOW DEVICES <PrefixPath> (WITH STORAGE GROUP)? limitClause?
 Eg: IoTDB > SHOW DEVICES root
 Eg: IoTDB > SHOW DEVICES root.ln
 Eg: IoTDB > SHOW DEVICES root.*.wf01
+Eg: IoTDB > SHOW DEVICES root.ln WITH STORAGE GROUP
+Eg: IoTDB > SHOW DEVICES root.*.wf01 WITH STORAGE GROUP
 Note: The path can be prefix path or star path.
 Note: This statement can be used in IoTDB Client and JDBC.
 ```
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 cc3c285..d98ac5c 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
@@ -43,7 +43,6 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
-
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.StorageEngine;
@@ -80,6 +79,7 @@ import org.apache.iotdb.db.qp.physical.sys.SetTTLPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowDevicesPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.query.dataset.ShowDevicesResult;
 import org.apache.iotdb.db.query.dataset.ShowTimeSeriesResult;
 import org.apache.iotdb.db.rescon.MemTableManager;
 import org.apache.iotdb.db.rescon.PrimitiveArrayManager;
@@ -701,7 +701,7 @@ public class MManager {
     return mtree.getDevices(prefixPath);
   }
 
-  public Set<PartialPath> getDevices(ShowDevicesPlan plan) throws MetadataException {
+  public List<ShowDevicesResult> getDevices(ShowDevicesPlan plan) throws MetadataException {
     return mtree.getDevices(plan);
   }
 
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 762d154..8c81655 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
@@ -76,6 +76,7 @@ import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.StorageGroupMNodePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
+import org.apache.iotdb.db.query.dataset.ShowDevicesResult;
 import org.apache.iotdb.db.query.executor.fill.LastPointReader;
 import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -1185,7 +1186,7 @@ public class MTree implements Serializable {
     return devices;
   }
 
-  Set<PartialPath> getDevices(ShowDevicesPlan plan) throws MetadataException {
+  List<ShowDevicesResult> getDevices(ShowDevicesPlan plan) throws MetadataException {
     String[] nodes = plan.getPath().getNodes();
     if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
       throw new IllegalPathException(plan.getPath().getFullPath());
@@ -1201,7 +1202,15 @@ public class MTree implements Serializable {
     offset.remove();
     curOffset.remove();
     count.remove();
-    return devices;
+    List<ShowDevicesResult> res = new ArrayList<>();
+    for (PartialPath device : devices) {
+      if (plan.hasSgCol()) {
+        res.add(new ShowDevicesResult(device.getFullPath(), getStorageGroupPath(device).getFullPath()));
+      } else {
+        res.add(new ShowDevicesResult(device.getFullPath()));
+      }
+    }
+    return res;
   }
 
   /**
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/ShowDevicesOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/ShowDevicesOperator.java
index 185e2e6..809187c 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/ShowDevicesOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/ShowDevicesOperator.java
@@ -26,6 +26,7 @@ public class ShowDevicesOperator extends ShowOperator {
   private PartialPath path;
   private int limit = 0;
   private int offset = 0;
+  private boolean hasSgCol;
 
   public ShowDevicesOperator(int tokenIntType, PartialPath path) {
     super(tokenIntType);
@@ -51,4 +52,12 @@ public class ShowDevicesOperator extends ShowOperator {
   public void setOffset(int offset) {
     this.offset = offset;
   }
+
+  public void setSgCol(boolean hasSgCol) {
+    this.hasSgCol = hasSgCol;
+  }
+
+  public boolean hasSgCol() {
+    return hasSgCol;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
index 3b5d7f2..1a6b846 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
@@ -22,13 +22,20 @@ import org.apache.iotdb.db.metadata.PartialPath;
 
 public class ShowDevicesPlan extends ShowPlan {
 
+  private boolean hasSgCol;
+
   public ShowDevicesPlan(PartialPath path) {
     super(ShowContentType.DEVICES, path);
   }
 
   public ShowDevicesPlan(PartialPath path, int limit, int offset,
-      int fetchSize) {
+      int fetchSize, boolean hasSgCol) {
     super(ShowContentType.DEVICES, path, limit, offset, fetchSize);
+    this.hasSgCol = hasSgCol;
+  }
+
+  public boolean hasSgCol() {
+    return hasSgCol;
   }
 }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 2910c61..3ab0104 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -23,7 +23,6 @@ import static org.apache.iotdb.db.index.common.IndexConstant.THRESHOLD;
 import static org.apache.iotdb.db.index.common.IndexConstant.TOP_K;
 import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH;
 import static org.apache.iotdb.db.qp.constant.SQLConstant.TOK_KILL_QUERY;
-import static org.apache.iotdb.db.qp.constant.SQLConstant.TOK_QUERY;
 
 import java.io.File;
 import java.time.ZoneId;
@@ -790,6 +789,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     if (ctx.limitClause() != null) {
       parseLimitClause(ctx.limitClause(), showDevicesOperator);
     }
+    //show devices wtih storage group
+    if (ctx.WITH() != null) {
+      showDevicesOperator.setSgCol(true);
+    }
     return showDevicesOperator;
   }
 
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 1f85a58..b63535e 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
@@ -263,7 +263,7 @@ public class PhysicalGenerator {
           case SQLConstant.TOK_DEVICES:
             ShowDevicesOperator showDevicesOperator = (ShowDevicesOperator) operator;
             return new ShowDevicesPlan(showDevicesOperator.getPath(), showDevicesOperator.getLimit(),
-                  showDevicesOperator.getOffset(), fetchSize);
+                  showDevicesOperator.getOffset(), fetchSize, showDevicesOperator.hasSgCol());
           case SQLConstant.TOK_COUNT_DEVICES:
             return new CountPlan(
                 ShowContentType.COUNT_DEVICES, ((CountOperator) operator).getPath());
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesDataSet.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesDataSet.java
index 65a9886..7aca9c7 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesDataSet.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesDataSet.java
@@ -20,10 +20,10 @@
 package org.apache.iotdb.db.query.dataset;
 
 import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_DEVICES;
+import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_STORAGE_GROUP;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Set;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.physical.sys.ShowDevicesPlan;
@@ -34,11 +34,18 @@ import org.apache.iotdb.tsfile.read.common.RowRecord;
 
 public class ShowDevicesDataSet extends ShowDataSet {
 
+  private static final Path[] resourcePathsWithSg = {new PartialPath(COLUMN_DEVICES, false),
+      new PartialPath(COLUMN_STORAGE_GROUP, false),};
+  private static final TSDataType[] resourceTypesWithSg = {TSDataType.TEXT, TSDataType.TEXT};
   private static final Path[] resourcePaths = {new PartialPath(COLUMN_DEVICES, false)};
   private static final TSDataType[] resourceTypes = {TSDataType.TEXT};
 
+  private boolean hasSgCol;
+
   public ShowDevicesDataSet(ShowDevicesPlan showDevicesPlan) throws MetadataException {
-    super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes));
+    super(showDevicesPlan.hasSgCol() ? Arrays.asList(resourcePathsWithSg) : Arrays.asList(resourcePaths),
+        showDevicesPlan.hasSgCol() ? Arrays.asList(resourceTypesWithSg) : Arrays.asList(resourceTypes));
+    hasSgCol = showDevicesPlan.hasSgCol();
     this.plan = showDevicesPlan;
     hasLimit = plan.hasLimit();
     getQueryDataSet();
@@ -46,11 +53,14 @@ public class ShowDevicesDataSet extends ShowDataSet {
 
   @Override
   public List<RowRecord> getQueryDataSet() throws MetadataException {
-    Set<PartialPath> devicesSet = IoTDB.metaManager.getDevices((ShowDevicesPlan) plan);
+    List<ShowDevicesResult> devicesList = IoTDB.metaManager.getDevices((ShowDevicesPlan) plan);
     List<RowRecord> records = new ArrayList<>();
-    for (PartialPath path : devicesSet) {
+    for (ShowDevicesResult result : devicesList) {
       RowRecord record = new RowRecord(0);
-      updateRecord(record, path.getFullPath());
+      updateRecord(record, result.getName());
+      if (hasSgCol) {
+        updateRecord(record, result.getSgName());
+      }
       records.add(record);
       putRecord(record);
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesResult.java
similarity index 63%
copy from server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
copy to server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesResult.java
index 3b5d7f2..8c3ec9a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesResult.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,19 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.qp.physical.sys;
+package org.apache.iotdb.db.query.dataset;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+public class ShowDevicesResult extends ShowResult {
 
-public class ShowDevicesPlan extends ShowPlan {
-
-  public ShowDevicesPlan(PartialPath path) {
-    super(ShowContentType.DEVICES, path);
+  public ShowDevicesResult(String name, String sgName) {
+    super(name, sgName);
   }
 
-  public ShowDevicesPlan(PartialPath path, int limit, int offset,
-      int fetchSize) {
-    super(ShowContentType.DEVICES, path, limit, offset, fetchSize);
+  public ShowDevicesResult(String name) {
+    super(name);
   }
 }
-
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowResult.java
similarity index 56%
copy from server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
copy to server/src/main/java/org/apache/iotdb/db/query/dataset/ShowResult.java
index 3b5d7f2..b400e97 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowDevicesPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowResult.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,19 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.qp.physical.sys;
+package org.apache.iotdb.db.query.dataset;
 
-import org.apache.iotdb.db.metadata.PartialPath;
+public class ShowResult implements Comparable<ShowResult> {
 
-public class ShowDevicesPlan extends ShowPlan {
+  protected String name;
+  protected String sgName;
 
-  public ShowDevicesPlan(PartialPath path) {
-    super(ShowContentType.DEVICES, path);
+  public ShowResult(String name, String sgName) {
+    this.name = name;
+    this.sgName = sgName;
   }
 
-  public ShowDevicesPlan(PartialPath path, int limit, int offset,
-      int fetchSize) {
-    super(ShowContentType.DEVICES, path, limit, offset, fetchSize);
+  public ShowResult(String name) {
+    this.name = name;
+  }
+
+  public ShowResult() {
+  }
+
+  public String getName() {
+    return name;
+  }
+  public String getSgName() {
+    return sgName;
   }
-}
 
+  @Override
+  public int compareTo(ShowResult o) {
+    return this.getName().compareTo(o.getName());
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeSeriesResult.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeSeriesResult.java
index ee34ebe..e717fab 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeSeriesResult.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeSeriesResult.java
@@ -30,11 +30,9 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
-public class ShowTimeSeriesResult implements Comparable<ShowTimeSeriesResult> {
+public class ShowTimeSeriesResult extends ShowResult {
 
-  private String name;
   private String alias;
-  private String sgName;
   private TSDataType dataType;
   private TSEncoding encoding;
   private CompressionType compressor;
@@ -43,9 +41,8 @@ public class ShowTimeSeriesResult implements Comparable<ShowTimeSeriesResult> {
 
   public ShowTimeSeriesResult(String name, String alias, String sgName, TSDataType dataType,
       TSEncoding encoding, CompressionType compressor, Map<String, String> tags, Map<String, String> attributes) {
-    this.name = name;
+    super(name, sgName);
     this.alias = alias;
-    this.sgName = sgName;
     this.dataType = dataType;
     this.encoding = encoding;
     this.compressor = compressor;
@@ -54,21 +51,13 @@ public class ShowTimeSeriesResult implements Comparable<ShowTimeSeriesResult> {
   }
 
   public ShowTimeSeriesResult() {
-
-  }
-
-  public String getName() {
-    return name;
+    super();
   }
 
   public String getAlias() {
     return alias;
   }
 
-  public String getSgName() {
-    return sgName;
-  }
-
   public TSDataType getDataType() {
     return dataType;
   }
@@ -90,11 +79,6 @@ public class ShowTimeSeriesResult implements Comparable<ShowTimeSeriesResult> {
   }
 
   @Override
-  public int compareTo(ShowTimeSeriesResult o) {
-    return this.name.compareTo(o.name);
-  }
-
-  @Override
   public boolean equals(Object o) {
     if (this == o) {
       return true;
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBAddSubDeviceIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBAddSubDeviceIT.java
index b51cde6..5a1b06f 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBAddSubDeviceIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBAddSubDeviceIT.java
@@ -32,8 +32,6 @@ import java.sql.ResultSetMetaData;
 import java.sql.Statement;
 import java.sql.Types;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -75,6 +73,46 @@ public class IoTDBAddSubDeviceIT {
   }
 
   @Test
+  public void showDevicesWithSg() throws ClassNotFoundException {
+    String[] retArray = new String[]{
+        "root.sg1.d1,root.sg1,",
+        "root.sg1.d1.s1,root.sg1,",
+    };
+
+    Class.forName(Config.JDBC_DRIVER_NAME);
+    try (Connection connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+        Statement statement = connection.createStatement()) {
+      boolean hasResultSet = statement.execute("SHOW DEVICES WITH STORAGE GROUP");
+      Assert.assertTrue(hasResultSet);
+
+      try (ResultSet resultSet = statement.getResultSet()) {
+        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+        StringBuilder header = new StringBuilder();
+        for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+          header.append(resultSetMetaData.getColumnName(i)).append(",");
+        }
+        Assert.assertEquals("devices,storage group,", header.toString());
+        Assert.assertEquals(Types.VARCHAR, resultSetMetaData.getColumnType(1));
+
+        int cnt = 0;
+        while (resultSet.next()) {
+          StringBuilder builder = new StringBuilder();
+          for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+            builder.append(resultSet.getString(i)).append(",");
+          }
+          Assert.assertEquals(retArray[cnt], builder.toString());
+          cnt++;
+        }
+        Assert.assertEquals(retArray.length, cnt);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
   public void showDevices() throws ClassNotFoundException {
     String[] retArray = new String[]{
         "root.sg1.d1,",
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 1ebbe9b..c0a6955 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
@@ -229,6 +229,43 @@ public class IoTDBMetadataFetchIT {
   }
 
   @Test
+  public void showDevicesWithSgTest() throws SQLException, ClassNotFoundException {
+    Class.forName(Config.JDBC_DRIVER_NAME);
+    try (Connection connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+        Statement statement = connection.createStatement()) {
+      String[] sqls = new String[]{"show devices root.ln with storage group",
+          "show devices root.ln.wf01.wt01.temperature"};
+      Set<String>[] standards = new Set[]{
+          new HashSet<>(Arrays.asList("root.ln.wf01.wt01,root.ln.wf01.wt01,", "root.ln.wf01.wt01.status,root.ln.wf01.wt01,")),
+          new HashSet<>(Collections.singletonList(""))};
+
+      for (int n = 0; n < sqls.length; n++) {
+        String sql = sqls[n];
+        Set<String> standard = standards[n];
+        try {
+          boolean hasResultSet = statement.execute(sql);
+          if (hasResultSet) {
+            try (ResultSet resultSet = statement.getResultSet()) {
+              ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+              while (resultSet.next()) {
+                StringBuilder builder = new StringBuilder();
+                for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+                  builder.append(resultSet.getString(i)).append(",");
+                }
+                Assert.assertTrue(standard.contains(builder.toString()));
+              }
+            }
+          }
+        } catch (SQLException e) {
+          logger.error("showDevicesTest() failed", e);
+          fail(e.getMessage());
+        }
+      }
+    }
+  }
+
+  @Test
   public void showDevicesTest() throws SQLException, ClassNotFoundException {
     Class.forName(Config.JDBC_DRIVER_NAME);
     try (Connection connection = DriverManager
diff --git a/server/src/test/java/org/apache/iotdb/db/query/dataset/ListDataSetTest.java b/server/src/test/java/org/apache/iotdb/db/query/dataset/ListDataSetTest.java
index 783dfa8..cc76e6c 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/dataset/ListDataSetTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/dataset/ListDataSetTest.java
@@ -123,4 +123,25 @@ public class ListDataSetTest {
       i++;
     }
   }
+
+  @Test
+  public void showDevicesWithSg()
+      throws QueryProcessException, TException, StorageEngineException, QueryFilterOptimizationException, MetadataException, IOException, InterruptedException, SQLException {
+    String[] results = new String [] {"0\troot.test.d0\troot.test", "0\troot.test.d1\troot.test",
+        "0\troot.vehicle.d0\troot.vehicle"};
+    PhysicalPlan plan = processor
+        .parseSQLToPhysicalPlan(
+            "show devices with storage group");
+    QueryDataSet dataSet = queryExecutor
+        .processQuery(plan, EnvironmentUtils.TEST_QUERY_CONTEXT);
+    Assert.assertTrue(dataSet instanceof ShowDevicesDataSet);
+    Assert.assertEquals("devices", dataSet.getPaths().get(0).toString());
+    Assert.assertEquals("storage group", dataSet.getPaths().get(1).toString());
+    int i = 0;
+    while (dataSet.hasNext()) {
+      RowRecord record = dataSet.next();
+      Assert.assertEquals(results[i], record.toString());
+      i++;
+    }
+  }
 }
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIteratorIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIteratorIT.java
index ae41176..9730a0d 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIteratorIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIteratorIT.java
@@ -19,7 +19,6 @@
 package org.apache.iotdb.session;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
index c32b9a0..54892f5 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
@@ -323,6 +323,19 @@ public class IoTDBInterpreterTest {
   }
 
   @Test
+  public void testShowDevicesWithSg() {
+    InterpreterResult actual = interpreter
+        .internalInterpret("show devices with storage group", null);
+    String gt = "devices\tstorage group\n"
+        + "root.test.wf01.wt01\troot.test.wf01\n"
+        + "root.test.wf02.wt02\troot.test.wf02";
+    Assert.assertNotNull(actual);
+    Assert.assertEquals(Code.SUCCESS, actual.code());
+    System.out.println(actual.message().get(0).getData());
+    Assert.assertEquals(gt, actual.message().get(0).getData());
+  }
+
+  @Test
   public void testShowAllTTL() {
     interpreter.internalInterpret("SET TTL TO root.test.wf01 12345", null);
     InterpreterResult actual = interpreter