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

haonan 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 70b228a  show devices limit (#2389)
70b228a is described below

commit 70b228aa08db386f3c3ed6504009b1c76ced5686
Author: Haimei Guo <[email protected]>
AuthorDate: Tue Jan 12 13:37:06 2021 +0800

    show devices limit (#2389)
---
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4   |  2 +-
 .../org/apache/iotdb/db/metadata/MManager.java     |  5 ++
 .../java/org/apache/iotdb/db/metadata/MTree.java   | 54 +++++++++++----
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |  9 +--
 .../db/qp/logical/sys/ShowDevicesOperator.java     | 18 +++++
 .../iotdb/db/qp/physical/sys/ShowDevicesPlan.java  | 13 ++--
 .../apache/iotdb/db/qp/physical/sys/ShowPlan.java  | 49 ++++++++++++++
 .../db/qp/physical/sys/ShowTimeSeriesPlan.java     | 51 +++++---------
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 13 +++-
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    | 16 +++--
 .../apache/iotdb/db/query/dataset/ShowDataSet.java | 78 ++++++++++++++++++++++
 .../iotdb/db/query/dataset/ShowDevicesDataSet.java | 58 ++++++++++++++++
 .../db/query/dataset/ShowTimeseriesDataSet.java    | 46 +------------
 .../org/apache/iotdb/db/service/TSServiceImpl.java | 10 ---
 .../iotdb/db/integration/IoTDBSimpleQueryIT.java   | 52 +++++++++++++++
 .../iotdb/db/query/dataset/ListDataSetTest.java    |  2 +-
 16 files changed, 351 insertions(+), 125 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 3139522..849ae49 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? #showDevices
+    | SHOW DEVICES prefixPath? limitClause? #showDevices
     | SHOW MERGE #showMergeStatus
     | TRACING ON #tracingOn
     | TRACING OFF #tracingOff
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 c1623ed..aa342d3 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
@@ -77,6 +77,7 @@ import 
org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 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.ShowTimeSeriesResult;
@@ -696,6 +697,10 @@ public class MManager {
     return mtree.getDevices(prefixPath);
   }
 
+  public Set<PartialPath> getDevices(ShowDevicesPlan plan) throws 
MetadataException {
+    return mtree.getDevices(plan);
+  }
+
   /**
    * Get all nodes from the given level
    *
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 054bff9..2e5a4c8 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
@@ -65,6 +65,7 @@ import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.MNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.MeasurementMNodePlan;
+import org.apache.iotdb.db.qp.physical.sys.ShowDevicesPlan;
 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;
@@ -965,7 +966,7 @@ public class MTree implements Serializable {
 
   List<Pair<PartialPath, String[]>> getAllMeasurementSchema(ShowTimeSeriesPlan 
plan, boolean removeCurrentOffset)
       throws MetadataException {
-    List<Pair<PartialPath, String[]>> res;
+    List<Pair<PartialPath, String[]>> res = new LinkedList<>();
     String[] nodes = plan.getPath().getNodes();
     if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
       throw new IllegalPathException(plan.getPath().getFullPath());
@@ -974,13 +975,7 @@ public class MTree implements Serializable {
     offset.set(plan.getOffset());
     curOffset.set(-1);
     count.set(0);
-    if (offset.get() != 0 || limit.get() != 0) {
-      res = new LinkedList<>();
-      findPath(root, nodes, 1, res, true, false, null);
-    } else {
-      res = new LinkedList<>();
-      findPath(root, nodes, 1, res, false, false, null);
-    }
+    findPath(root, nodes, 1, res, offset.get() != 0 || limit.get() != 0, 
false, null);
     // avoid memory leaks
     limit.remove();
     offset.remove();
@@ -1121,7 +1116,26 @@ public class MTree implements Serializable {
       throw new IllegalPathException(prefixPath.getFullPath());
     }
     Set<PartialPath> devices = new TreeSet<>();
-    findDevices(root, nodes, 1, devices);
+    findDevices(root, nodes, 1, devices, false);
+    return devices;
+  }
+
+  Set<PartialPath> 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());
+    }
+    Set<PartialPath> devices = new TreeSet<>();
+    limit.set(plan.getLimit());
+    offset.set(plan.getOffset());
+    curOffset.set(-1);
+    count.set(0);
+    findDevices(root, nodes, 1, devices, offset.get() != 0 || limit.get() != 
0);
+    // avoid memory leaks
+    limit.remove();
+    offset.remove();
+    curOffset.remove();
+    count.remove();
     return devices;
   }
 
@@ -1134,16 +1148,24 @@ public class MTree implements Serializable {
    * @param res   store all matched device names
    */
   @SuppressWarnings("squid:S3776")
-  private void findDevices(MNode node, String[] nodes, int idx, 
Set<PartialPath> res) {
+  private void findDevices(MNode node, String[] nodes, int idx, 
Set<PartialPath> res, boolean hasLimit) {
     String nodeReg = MetaUtils.getNodeRegByIdx(idx, nodes);
     // the node path doesn't contains '*'
     if (!nodeReg.contains(PATH_WILDCARD)) {
       MNode next = node.getChild(nodeReg);
       if (next != null) {
         if (next instanceof MeasurementMNode && idx >= nodes.length) {
+          if (hasLimit) {
+            curOffset.set(curOffset.get() + 1);
+            if (curOffset.get() < offset.get() || count.get().intValue() == 
limit.get()
+                .intValue()) {
+              return;
+            }
+            count.set(count.get() + 1);
+          }
           res.add(node.getPartialPath());
         } else {
-          findDevices(next, nodes, idx + 1, res);
+          findDevices(next, nodes, idx + 1, res, hasLimit);
         }
       }
     } else { // the node path contains '*'
@@ -1155,10 +1177,18 @@ public class MTree implements Serializable {
           continue;
         }
         if (child instanceof MeasurementMNode && !deviceAdded && idx >= 
nodes.length) {
+          if (hasLimit) {
+            curOffset.set(curOffset.get() + 1);
+            if (curOffset.get() < offset.get() || count.get().intValue() == 
limit.get()
+                .intValue()) {
+              return;
+            }
+            count.set(count.get() + 1);
+          }
           res.add(node.getPartialPath());
           deviceAdded = true;
         }
-        findDevices(child, nodes, idx + 1, res);
+        findDevices(child, nodes, idx + 1, res, hasLimit);
       }
     }
   }
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 418ad7a..3119555 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
@@ -138,6 +138,7 @@ import org.apache.iotdb.db.qp.physical.sys.TracingPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.dataset.AlignByDeviceDataSet;
 import org.apache.iotdb.db.query.dataset.ListDataSet;
+import org.apache.iotdb.db.query.dataset.ShowDevicesDataSet;
 import org.apache.iotdb.db.query.dataset.ShowTimeseriesDataSet;
 import org.apache.iotdb.db.query.dataset.SingleDataSet;
 import org.apache.iotdb.db.query.executor.IQueryRouter;
@@ -562,13 +563,7 @@ public class PlanExecutor implements IPlanExecutor {
 
   private QueryDataSet processShowDevices(ShowDevicesPlan showDevicesPlan)
       throws MetadataException {
-    ListDataSet listDataSet =
-        new ListDataSet(
-            Collections.singletonList(new PartialPath(COLUMN_DEVICES, false)),
-            Collections.singletonList(TSDataType.TEXT));
-    Set<PartialPath> devices = getDevices(showDevicesPlan.getPath());
-    addToDataSet(devices, listDataSet);
-    return listDataSet;
+    return new ShowDevicesDataSet(showDevicesPlan);
   }
 
   protected Set<PartialPath> getDevices(PartialPath path) throws 
MetadataException {
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 9d5ad6d..185e2e6 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
@@ -24,6 +24,8 @@ import org.apache.iotdb.db.metadata.PartialPath;
 public class ShowDevicesOperator extends ShowOperator {
 
   private PartialPath path;
+  private int limit = 0;
+  private int offset = 0;
 
   public ShowDevicesOperator(int tokenIntType, PartialPath path) {
     super(tokenIntType);
@@ -33,4 +35,20 @@ public class ShowDevicesOperator extends ShowOperator {
   public PartialPath getPath() {
     return path;
   }
+
+  public int getLimit() {
+    return limit;
+  }
+
+  public void setLimit(int limit) {
+    this.limit = limit;
+  }
+
+  public int getOffset() {
+    return offset;
+  }
+
+  public void setOffset(int offset) {
+    this.offset = offset;
+  }
 }
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 8da6b96..3b5d7f2 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
@@ -20,16 +20,15 @@ package org.apache.iotdb.db.qp.physical.sys;
 
 import org.apache.iotdb.db.metadata.PartialPath;
 
-public class ShowDevicesPlan extends ShowPlan{
-  private PartialPath path;
+public class ShowDevicesPlan extends ShowPlan {
 
-  public ShowDevicesPlan(ShowContentType showContentType, PartialPath path) {
-    super(showContentType);
-    this.path = path;
+  public ShowDevicesPlan(PartialPath path) {
+    super(ShowContentType.DEVICES, path);
   }
 
-  public PartialPath getPath() {
-    return this.path;
+  public ShowDevicesPlan(PartialPath path, int limit, int offset,
+      int fetchSize) {
+    super(ShowContentType.DEVICES, path, limit, offset, fetchSize);
   }
 }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
index 23e9852..7a5188a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
@@ -28,6 +28,10 @@ import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 public class ShowPlan extends PhysicalPlan {
 
   private ShowContentType showContentType;
+  protected int limit = 0;
+  protected int offset = 0;
+  protected PartialPath path;
+  private boolean hasLimit;
 
   public ShowPlan(ShowContentType showContentType) {
     super(true);
@@ -35,6 +39,23 @@ public class ShowPlan extends PhysicalPlan {
     setOperatorType(OperatorType.SHOW);
   }
 
+  public ShowPlan(ShowContentType showContentType, PartialPath path) {
+    this(showContentType);
+    this.path = path;
+  }
+
+  public ShowPlan(ShowContentType showContentType, PartialPath path, int 
limit, int offset, int fetchSize) {
+    this(showContentType, path);
+    this.limit = limit;
+    this.offset = offset;
+    if (limit == 0) {
+      this.limit = fetchSize;
+      this.hasLimit = false;
+    } else {
+      this.hasLimit = true;
+    }
+  }
+
   @Override
   public List<PartialPath> getPaths() {
     return Collections.emptyList();
@@ -44,6 +65,34 @@ public class ShowPlan extends PhysicalPlan {
     return showContentType;
   }
 
+  public PartialPath getPath() {
+    return this.path;
+  }
+
+  public int getLimit() {
+    return limit;
+  }
+
+  public void setLimit(int limit) {
+    this.limit = limit;
+  }
+
+  public int getOffset() {
+    return offset;
+  }
+
+  public void setOffset(int offset) {
+    this.offset = offset;
+  }
+
+  public boolean hasLimit() {
+    return hasLimit;
+  }
+
+  public void setHasLimit(boolean hasLimit) {
+    this.hasLimit = hasLimit;
+  }
+
   @Override
   public String toString() {
     return String.format("%s %s", getOperatorType().toString(), 
showContentType);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowTimeSeriesPlan.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowTimeSeriesPlan.java
index 5c37793..7edd0f2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowTimeSeriesPlan.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowTimeSeriesPlan.java
@@ -26,22 +26,15 @@ import org.apache.iotdb.db.metadata.PartialPath;
 
 public class ShowTimeSeriesPlan extends ShowPlan {
 
-  // path can be root, root.*  root.*.*.a etc.. if the wildcard is not at the 
tail, then each
-  // * wildcard can only match one level, otherwise it can match to the tail.
-  private PartialPath path;
   private boolean isContains;
   private String key;
   private String value;
-  private int limit = 0;
-  private int offset = 0;
+
   // if is true, the result will be sorted according to the inserting 
frequency of the timeseries
   private boolean orderByHeat;
 
-  private boolean hasLimit;
-
   public ShowTimeSeriesPlan(PartialPath path) {
-    super(ShowContentType.TIMESERIES);
-    this.path = path;
+    super(ShowContentType.TIMESERIES, path);
   }
 
   public ShowTimeSeriesPlan(PartialPath path, boolean isContains, String key, 
String value, int limit,
@@ -56,40 +49,36 @@ public class ShowTimeSeriesPlan extends ShowPlan {
     this.orderByHeat = orderByHeat;
   }
 
-  public ShowTimeSeriesPlan() {
-    super(ShowContentType.TIMESERIES);
+  public ShowTimeSeriesPlan(PartialPath path, int limit, int offset, int 
fetchSize) {
+    super(ShowContentType.TIMESERIES, path, limit, offset, fetchSize);
   }
 
-  public PartialPath getPath() {
-    return this.path;
+  public ShowTimeSeriesPlan() {
+    super(ShowContentType.TIMESERIES);
   }
 
   public boolean isContains() {
     return isContains;
   }
 
-  public String getKey() {
-    return key;
-  }
-
-  public String getValue() {
-    return value;
+  public void setIsContains(boolean isContains) {
+    this.isContains = isContains;
   }
 
-  public int getLimit() {
-    return limit;
+  public String getKey() {
+    return key;
   }
 
-  public void setLimit(int limit) {
-    this.limit = limit;
+  public void setKey(String key) {
+    this.key = key;
   }
 
-  public int getOffset() {
-    return offset;
+  public String getValue() {
+    return value;
   }
 
-  public void setOffset(int offset) {
-    this.offset = offset;
+  public void setValue(String value) {
+    this.value = value;
   }
 
   public boolean isOrderByHeat() {
@@ -100,14 +89,6 @@ public class ShowTimeSeriesPlan extends ShowPlan {
     this.orderByHeat = orderByHeat;
   }
 
-  public boolean hasLimit() {
-    return hasLimit;
-  }
-
-  public void setHasLimit(boolean hasLimit) {
-    this.hasLimit = hasLimit;
-  }
-
   @Override
   public void serialize(DataOutputStream outputStream) throws IOException {
     outputStream.write(PhysicalPlanType.SHOW_TIMESERIES.ordinal());
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 ea0fcaf..d6c5db2 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
@@ -760,13 +760,18 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitShowDevices(ShowDevicesContext ctx) {
+    ShowDevicesOperator showDevicesOperator;
     if (ctx.prefixPath() != null) {
-      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
+      showDevicesOperator = new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
           parsePrefixPath(ctx.prefixPath()));
     } else {
-      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
+      showDevicesOperator = new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
           new PartialPath(SQLConstant.getSingleRootArray()));
     }
+    if (ctx.limitClause() != null) {
+      parseLimitClause(ctx.limitClause(), showDevicesOperator);
+    }
+    return showDevicesOperator;
   }
 
   @Override
@@ -1242,6 +1247,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     }
     if (operator instanceof ShowTimeSeriesOperator) {
       ((ShowTimeSeriesOperator) operator).setLimit(limit);
+    } else if (operator instanceof ShowDevicesOperator) {
+      ((ShowDevicesOperator) operator).setLimit(limit);
     } else {
       ((QueryOperator) operator).setRowLimit(limit);
     }
@@ -1263,6 +1270,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     }
     if (operator instanceof ShowTimeSeriesOperator) {
       ((ShowTimeSeriesOperator) operator).setOffset(offset);
+    } else if (operator instanceof ShowDevicesOperator) {
+      ((ShowDevicesOperator) operator).setOffset(offset);
     } else {
       ((QueryOperator) operator).setRowOffset(offset);
     }
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 eb298e5..c906dfe 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
@@ -247,16 +247,20 @@ public class PhysicalGenerator {
             return new ShowPlan(ShowContentType.VERSION);
           case SQLConstant.TOK_TIMESERIES:
             ShowTimeSeriesOperator showTimeSeriesOperator = 
(ShowTimeSeriesOperator) operator;
-            return new ShowTimeSeriesPlan(showTimeSeriesOperator.getPath(),
-                showTimeSeriesOperator.isContains(), 
showTimeSeriesOperator.getKey(),
-                showTimeSeriesOperator.getValue(), 
showTimeSeriesOperator.getLimit(),
-                showTimeSeriesOperator.getOffset(), 
showTimeSeriesOperator.isOrderByHeat());
+            ShowTimeSeriesPlan showTimeSeriesPlan = new 
ShowTimeSeriesPlan(showTimeSeriesOperator.getPath(),
+                showTimeSeriesOperator.getLimit(), 
showTimeSeriesOperator.getOffset(), fetchSize);
+            
showTimeSeriesPlan.setIsContains(showTimeSeriesOperator.isContains());
+            showTimeSeriesPlan.setKey(showTimeSeriesOperator.getKey());
+            showTimeSeriesPlan.setValue(showTimeSeriesOperator.getValue());
+            
showTimeSeriesPlan.setOrderByHeat(showTimeSeriesOperator.isOrderByHeat());
+            return showTimeSeriesPlan;
           case SQLConstant.TOK_STORAGE_GROUP:
             return new ShowStorageGroupPlan(
                 ShowContentType.STORAGE_GROUP, ((ShowStorageGroupOperator) 
operator).getPath());
           case SQLConstant.TOK_DEVICES:
-            return new ShowDevicesPlan(
-                ShowContentType.DEVICES, ((ShowDevicesOperator) 
operator).getPath());
+            ShowDevicesOperator showDevicesOperator = (ShowDevicesOperator) 
operator;
+            return new ShowDevicesPlan(showDevicesOperator.getPath(), 
showDevicesOperator.getLimit(),
+                  showDevicesOperator.getOffset(), fetchSize);
           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/ShowDataSet.java 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDataSet.java
new file mode 100644
index 0000000..fb64388
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDataSet.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.dataset;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.qp.physical.sys.ShowPlan;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.common.Field;
+import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
+import org.apache.iotdb.tsfile.utils.Binary;
+
+public abstract class ShowDataSet extends QueryDataSet {
+  protected ShowPlan plan;
+  private List<RowRecord> result = new ArrayList<>();
+  private int index = 0;
+  protected boolean hasLimit;
+
+  protected ShowDataSet(List<Path> paths, List<TSDataType> dataTypes) {
+    super(paths, dataTypes);
+  }
+
+  @Override
+  public boolean hasNextWithoutConstraint() throws IOException {
+    if (index == result.size() && !hasLimit && result.size() == 
plan.getLimit()) {
+      plan.setOffset(plan.getOffset() + plan.getLimit());
+      try {
+        result = getQueryDataSet();
+        index = 0;
+      } catch (MetadataException e) {
+        throw new IOException(e);
+      }
+    }
+    return index < result.size();
+  }
+
+  public abstract List<RowRecord> getQueryDataSet() throws MetadataException;
+
+  @Override
+  public RowRecord nextWithoutConstraint() {
+    return result.get(index++);
+  }
+
+  protected void updateRecord(RowRecord record, String s) {
+    if (s == null) {
+      record.addField(null);
+      return;
+    }
+    Field field = new Field(TSDataType.TEXT);
+    field.setBinaryV(new Binary(s));
+    record.addField(field);
+  }
+
+  protected void putRecord(RowRecord newRecord) {
+    result.add(newRecord);
+  }
+}
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
new file mode 100644
index 0000000..95c14d7
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowDevicesDataSet.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.dataset;
+
+import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_DEVICES;
+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;
+import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+
+public class ShowDevicesDataSet extends ShowDataSet {
+
+  private static final Path[] resourcePaths = {new PartialPath(COLUMN_DEVICES, 
false)};
+  private static final TSDataType[] resourceTypes = {TSDataType.TEXT};
+
+  public ShowDevicesDataSet(ShowDevicesPlan showDevicesPlan) throws 
MetadataException {
+    super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes));
+    this.plan = showDevicesPlan;
+    hasLimit = plan.hasLimit();
+    getQueryDataSet();
+  }
+
+  public List<RowRecord> getQueryDataSet() throws MetadataException {
+    Set<PartialPath> devicesSet = 
IoTDB.metaManager.getDevices((ShowDevicesPlan) plan);
+    List<RowRecord> records = new ArrayList<>();
+    for (PartialPath path : devicesSet) {
+      RowRecord record = new RowRecord(0);
+      updateRecord(record, path.getFullPath());
+      records.add(record);
+      putRecord(record);
+    }
+    return records;
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java
 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java
index 481e223..582d5f4 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java
@@ -28,7 +28,6 @@ import static 
org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSI
 import static 
org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE;
 import static 
org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -40,21 +39,13 @@ import 
org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.read.common.Field;
 import org.apache.iotdb.tsfile.read.common.Path;
 import org.apache.iotdb.tsfile.read.common.RowRecord;
-import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
-import org.apache.iotdb.tsfile.utils.Binary;
 
-public class ShowTimeseriesDataSet extends QueryDataSet {
+public class ShowTimeseriesDataSet extends ShowDataSet {
 
-  private final ShowTimeSeriesPlan plan;
-  private List<RowRecord> result = new ArrayList<>();
-  private int index = 0;
   private final QueryContext context;
 
-  public boolean hasLimit;
-
   private static final Path[] resourcePaths = {new 
PartialPath(COLUMN_TIMESERIES, false),
       new PartialPath(COLUMN_TIMESERIES_ALIAS, false),
       new PartialPath(COLUMN_STORAGE_GROUP, false),
@@ -76,7 +67,7 @@ public class ShowTimeseriesDataSet extends QueryDataSet {
   }
 
   public List<RowRecord> getQueryDataSet() throws MetadataException {
-    List<ShowTimeSeriesResult> timeseriesList = 
IoTDB.metaManager.showTimeseries(plan, context);
+    List<ShowTimeSeriesResult> timeseriesList = 
IoTDB.metaManager.showTimeseries((ShowTimeSeriesPlan) plan, context);
     List<RowRecord> records = new ArrayList<>();
     for (ShowTimeSeriesResult result : timeseriesList) {
       RowRecord record = new RowRecord(0);
@@ -101,37 +92,4 @@ public class ShowTimeseriesDataSet extends QueryDataSet {
 
     updateRecord(record, text.length() == 0 ? null : "{" + text + "}");
   }
-
-  private void updateRecord(RowRecord record, String s) {
-    if (s == null) {
-      record.addField(null);
-      return;
-    }
-    Field field = new Field(TSDataType.TEXT);
-    field.setBinaryV(new Binary(s));
-    record.addField(field);
-  }
-
-  @Override
-  public boolean hasNextWithoutConstraint() throws IOException {
-    if (index == result.size() && !hasLimit && result.size() == 
plan.getLimit()) {
-      plan.setOffset(plan.getOffset() + plan.getLimit());
-      try {
-        result = getQueryDataSet();
-        index = 0;
-      } catch (MetadataException e) {
-        throw new IOException(e);
-      }
-    }
-    return index < result.size();
-  }
-
-  @Override
-  public RowRecord nextWithoutConstraint() {
-    return result.get(index++);
-  }
-
-  private void putRecord(RowRecord newRecord) {
-    result.add(newRecord);
-  }
 }
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 84d033c..ae9c1af 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
@@ -88,7 +88,6 @@ import 
org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowPlan;
-import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.aggregation.AggregateResult;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
@@ -541,15 +540,6 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
         fetchSize = DEFAULT_FETCH_SIZE;
       }
 
-      if (plan instanceof ShowTimeSeriesPlan) {
-        //If the user does not pass the limit, then set limit = fetchSize and 
haslimit=false,else set haslimit = true
-        if (((ShowTimeSeriesPlan) plan).getLimit() == 0) {
-          ((ShowTimeSeriesPlan) plan).setLimit(fetchSize);
-          ((ShowTimeSeriesPlan) plan).setHasLimit(false);
-        } else {
-          ((ShowTimeSeriesPlan) plan).setHasLimit(true);
-        }
-      }
       if (plan instanceof QueryPlan && !((QueryPlan) plan).isAlignByTime()) {
         if (plan.getOperatorType() == OperatorType.AGGREGATION) {
           throw new QueryProcessException("Aggregation doesn't support disable 
align clause.");
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
index bf53edb..ec92978 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
@@ -722,6 +722,58 @@ public class IoTDBSimpleQueryIT {
   }
 
   @Test
+  public void testShowDevicesWithLimitOffset() 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()) {
+
+      List<String> exps = Arrays
+          .asList("root.sg1.d1", "root.sg1.d2");
+
+      statement.execute("INSERT INTO root.sg1.d0(timestamp, s1) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d1(timestamp, s2) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d2(timestamp, s3) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d3(timestamp, s4) VALUES (5, 
5)");
+
+      int count = 0;
+      try (ResultSet resultSet = statement.executeQuery("show devices limit 2 
offset 1")) {
+        while (resultSet.next()) {
+          Assert.assertEquals(exps.get(count), resultSet.getString(1));
+          ++count;
+        }
+      }
+      Assert.assertEquals(2, count);
+    }
+  }
+
+  @Test
+  public void testShowDevicesWithLimit() 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()) {
+
+      List<String> exps = Arrays
+          .asList("root.sg1.d0", "root.sg1.d1");
+
+      statement.execute("INSERT INTO root.sg1.d0(timestamp, s1) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d1(timestamp, s2) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d2(timestamp, s3) VALUES (5, 
5)");
+      statement.execute("INSERT INTO root.sg1.d3(timestamp, s4) VALUES (5, 
5)");
+
+      int count = 0;
+      try (ResultSet resultSet = statement.executeQuery("show devices limit 
2")) {
+        while (resultSet.next()) {
+          Assert.assertEquals(exps.get(count), resultSet.getString(1));
+          ++count;
+        }
+      }
+      Assert.assertEquals(2, count);
+    }
+  }
+
+  @Test
   public void testFirstOverlappedPageFiltered() 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 f03209b..783dfa8 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
@@ -114,7 +114,7 @@ public class ListDataSetTest {
             "show devices");
     QueryDataSet dataSet = queryExecutor
         .processQuery(plan, EnvironmentUtils.TEST_QUERY_CONTEXT);
-    Assert.assertTrue(dataSet instanceof ListDataSet);
+    Assert.assertTrue(dataSet instanceof ShowDevicesDataSet);
     Assert.assertEquals("[devices]", dataSet.getPaths().toString());
     int i = 0;
     while (dataSet.hasNext()) {

Reply via email to