未验证 提交 686f0663 编写于 作者: Y yhwang-hbl 提交者: GitHub

[IOTDB-876] Add count storage group DDL (#1734)

上级 e9deffff
...@@ -80,6 +80,7 @@ statement ...@@ -80,6 +80,7 @@ statement
| TRACING OFF #tracingOff | TRACING OFF #tracingOff
| COUNT TIMESERIES prefixPath? (GROUP BY LEVEL OPERATOR_EQ INT)? #countTimeseries | COUNT TIMESERIES prefixPath? (GROUP BY LEVEL OPERATOR_EQ INT)? #countTimeseries
| COUNT DEVICES prefixPath? #countDevices | COUNT DEVICES prefixPath? #countDevices
| COUNT STORAGE GROUP prefixPath? #countStorageGroup
| COUNT NODES prefixPath LEVEL OPERATOR_EQ INT #countNodes | COUNT NODES prefixPath LEVEL OPERATOR_EQ INT #countNodes
| LOAD CONFIGURATION (MINUS GLOBAL)? #loadConfigurationStatement | LOAD CONFIGURATION (MINUS GLOBAL)? #loadConfigurationStatement
| {hasSingleQuoteString = true;} LOAD stringLiteral autoCreateSchema?#loadFiles | {hasSingleQuoteString = true;} LOAD stringLiteral autoCreateSchema?#loadFiles
......
...@@ -852,6 +852,18 @@ public class MManager { ...@@ -852,6 +852,18 @@ public class MManager {
} }
} }
/**
* To calculate the count of storage group for given prefix path.
*/
public int getStorageGroupNum(PartialPath prefixPath) throws MetadataException {
lock.readLock().lock();
try {
return mtree.getStorageGroupNum(prefixPath);
} finally {
lock.readLock().unlock();
}
}
/** /**
* To calculate the count of nodes in the given level for given prefix path. * To calculate the count of nodes in the given level for given prefix path.
* *
......
...@@ -662,6 +662,19 @@ public class MTree implements Serializable { ...@@ -662,6 +662,19 @@ public class MTree implements Serializable {
return getDevicesCount(root, nodes, 1); return getDevicesCount(root, nodes, 1);
} }
/**
* Get the count of storage group under the given prefix path.
*
* @param prefixPath a prefix path or a full path, may contain '*'.
*/
int getStorageGroupNum(PartialPath prefixPath) throws MetadataException {
String[] nodes = prefixPath.getNodes();
if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
throw new IllegalPathException(prefixPath.getFullPath());
}
return getStorageGroupCount(root, nodes, 1, "");
}
/** /**
* Get the count of nodes in the given level under the given prefix path. * Get the count of nodes in the given level under the given prefix path.
*/ */
...@@ -735,6 +748,31 @@ public class MTree implements Serializable { ...@@ -735,6 +748,31 @@ public class MTree implements Serializable {
return cnt; return cnt;
} }
/**
* Traverse the MTree to get the count of storage group.
*/
private int getStorageGroupCount(
MNode node, String[] nodes, int idx, String parent) throws MetadataException {
int cnt = 0;
if (node instanceof StorageGroupMNode && idx >= nodes.length) {
cnt++;
return cnt;
}
String nodeReg = MetaUtils.getNodeRegByIdx(idx, nodes);
if (!(PATH_WILDCARD).equals(nodeReg)) {
if (node.hasChild(nodeReg)) {
cnt += getStorageGroupCount(node.getChild(nodeReg),
nodes, idx + 1, parent + node.getName() + PATH_SEPARATOR);
}
} else {
for (MNode child : node.getChildren().values()) {
cnt += getStorageGroupCount(
child, nodes, idx + 1, parent + node.getName() + PATH_SEPARATOR);
}
}
return cnt;
}
/** /**
* Traverse the MTree to get the count of timeseries in the given level. * Traverse the MTree to get the count of timeseries in the given level.
* *
......
...@@ -159,6 +159,7 @@ public class SQLConstant { ...@@ -159,6 +159,7 @@ public class SQLConstant {
public static final int TOK_TRACING = 91; public static final int TOK_TRACING = 91;
public static final int TOK_COUNT_DEVICES = 92; public static final int TOK_COUNT_DEVICES = 92;
public static final int TOK_COUNT_STORAGE_GROUP = 93;
public static final Map<Integer, String> tokenSymbol = new HashMap<>(); public static final Map<Integer, String> tokenSymbol = new HashMap<>();
public static final Map<Integer, String> tokenNames = new HashMap<>(); public static final Map<Integer, String> tokenNames = new HashMap<>();
......
...@@ -386,6 +386,8 @@ public class PlanExecutor implements IPlanExecutor { ...@@ -386,6 +386,8 @@ public class PlanExecutor implements IPlanExecutor {
return processCountNodeTimeSeries((CountPlan) showPlan); return processCountNodeTimeSeries((CountPlan) showPlan);
case COUNT_DEVICES: case COUNT_DEVICES:
return processCountDevices((CountPlan) showPlan); return processCountDevices((CountPlan) showPlan);
case COUNT_STORAGE_GROUP:
return processCountStorageGroup((CountPlan) showPlan);
case COUNT_NODES: case COUNT_NODES:
return processCountNodes((CountPlan) showPlan); return processCountNodes((CountPlan) showPlan);
case MERGE_STATUS: case MERGE_STATUS:
...@@ -445,10 +447,28 @@ public class PlanExecutor implements IPlanExecutor { ...@@ -445,10 +447,28 @@ public class PlanExecutor implements IPlanExecutor {
return singleDataSet; return singleDataSet;
} }
private QueryDataSet processCountStorageGroup(CountPlan countPlan) throws MetadataException {
int num = getStorageGroupNum(countPlan.getPath());
SingleDataSet singleDataSet =
new SingleDataSet(
Collections.singletonList(new PartialPath(COLUMN_STORAGE_GROUP, false)),
Collections.singletonList(TSDataType.INT32));
Field field = new Field(TSDataType.INT32);
field.setIntV(num);
RowRecord record = new RowRecord(0);
record.addField(field);
singleDataSet.setRecord(record);
return singleDataSet;
}
private int getDevicesNum(PartialPath path) throws MetadataException { private int getDevicesNum(PartialPath path) throws MetadataException {
return IoTDB.metaManager.getDevicesNum(path); return IoTDB.metaManager.getDevicesNum(path);
} }
private int getStorageGroupNum(PartialPath path) throws MetadataException {
return IoTDB.metaManager.getStorageGroupNum(path);
}
protected int getPathsNum(PartialPath path) throws MetadataException { protected int getPathsNum(PartialPath path) throws MetadataException {
return IoTDB.metaManager.getAllTimeseriesCount(path); return IoTDB.metaManager.getAllTimeseriesCount(path);
} }
......
...@@ -50,7 +50,7 @@ public class ShowPlan extends PhysicalPlan { ...@@ -50,7 +50,7 @@ public class ShowPlan extends PhysicalPlan {
public enum ShowContentType { public enum ShowContentType {
DYNAMIC_PARAMETER, FLUSH_TASK_INFO, TTL, VERSION, TIMESERIES, STORAGE_GROUP, CHILD_PATH, DEVICES, DYNAMIC_PARAMETER, FLUSH_TASK_INFO, TTL, VERSION, TIMESERIES, STORAGE_GROUP, CHILD_PATH, DEVICES,
COUNT_TIMESERIES, COUNT_NODE_TIMESERIES, COUNT_NODES, MERGE_STATUS, COUNT_DEVICES COUNT_TIMESERIES, COUNT_NODE_TIMESERIES, COUNT_NODES, MERGE_STATUS, COUNT_DEVICES, COUNT_STORAGE_GROUP
} }
} }
...@@ -86,6 +86,7 @@ import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AttributeClausesContext; ...@@ -86,6 +86,7 @@ import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AttributeClausesContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ConstantContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ConstantContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountDevicesContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountDevicesContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountNodesContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountNodesContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountStorageGroupContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountTimeseriesContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountTimeseriesContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateRoleContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateRoleContext;
import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateSnapshotContext; import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateSnapshotContext;
...@@ -230,6 +231,14 @@ public class LogicalGenerator extends SqlBaseBaseListener { ...@@ -230,6 +231,14 @@ public class LogicalGenerator extends SqlBaseBaseListener {
initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_DEVICES, path); initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_DEVICES, path);
} }
@Override
public void enterCountStorageGroup(CountStorageGroupContext ctx) {
super.enterCountStorageGroup(ctx);
PrefixPathContext pathContext = ctx.prefixPath();
PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray()));
initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_STORAGE_GROUP, path);
}
@Override @Override
public void enterFlush(FlushContext ctx) { public void enterFlush(FlushContext ctx) {
super.enterFlush(ctx); super.enterFlush(ctx);
......
...@@ -242,6 +242,9 @@ public class PhysicalGenerator { ...@@ -242,6 +242,9 @@ public class PhysicalGenerator {
case SQLConstant.TOK_COUNT_DEVICES: case SQLConstant.TOK_COUNT_DEVICES:
return new CountPlan( return new CountPlan(
ShowContentType.COUNT_DEVICES, ((CountOperator) operator).getPath()); ShowContentType.COUNT_DEVICES, ((CountOperator) operator).getPath());
case SQLConstant.TOK_COUNT_STORAGE_GROUP:
return new CountPlan(
ShowContentType.COUNT_STORAGE_GROUP, ((CountOperator) operator).getPath());
case SQLConstant.TOK_COUNT_NODE_TIMESERIES: case SQLConstant.TOK_COUNT_NODE_TIMESERIES:
return new CountPlan( return new CountPlan(
ShowContentType.COUNT_NODE_TIMESERIES, ShowContentType.COUNT_NODE_TIMESERIES,
......
...@@ -107,6 +107,10 @@ class StaticResps { ...@@ -107,6 +107,10 @@ class StaticResps {
Collections.singletonList(COLUMN_COUNT), Collections.singletonList(COLUMN_COUNT),
Collections.singletonList(TSDataType.INT32.toString())); Collections.singletonList(TSDataType.INT32.toString()));
static final TSExecuteStatementResp COUNT_STORAGE_GROUP = getNoTimeExecuteResp(
Collections.singletonList(COLUMN_COUNT),
Collections.singletonList(TSDataType.INT32.toString()));
static final TSExecuteStatementResp COUNT_NODES = getNoTimeExecuteResp( static final TSExecuteStatementResp COUNT_NODES = getNoTimeExecuteResp(
Collections.singletonList(COLUMN_COUNT), Collections.singletonList(COLUMN_COUNT),
Collections.singletonList(TSDataType.INT32.toString())); Collections.singletonList(TSDataType.INT32.toString()));
......
...@@ -732,6 +732,8 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext { ...@@ -732,6 +732,8 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
return StaticResps.COUNT_TIMESERIES; return StaticResps.COUNT_TIMESERIES;
case COUNT_DEVICES: case COUNT_DEVICES:
return StaticResps.COUNT_DEVICES; return StaticResps.COUNT_DEVICES;
case COUNT_STORAGE_GROUP:
return StaticResps.COUNT_STORAGE_GROUP;
case MERGE_STATUS: case MERGE_STATUS:
return StaticResps.MERGE_STATUS_RESP; return StaticResps.MERGE_STATUS_RESP;
default: default:
......
...@@ -48,6 +48,7 @@ public class IoTDBMetadataFetchIT { ...@@ -48,6 +48,7 @@ public class IoTDBMetadataFetchIT {
Statement statement = connection.createStatement()) { Statement statement = connection.createStatement()) {
String[] insertSqls = new String[]{"SET STORAGE GROUP TO root.ln.wf01.wt01", String[] insertSqls = new String[]{"SET STORAGE GROUP TO root.ln.wf01.wt01",
"SET STORAGE GROUP TO root.ln1.wf01.wt01", "SET STORAGE GROUP TO root.ln2.wf01.wt01",
"CREATE TIMESERIES root.ln.wf01.wt01.status WITH DATATYPE = BOOLEAN, ENCODING = PLAIN", "CREATE TIMESERIES root.ln.wf01.wt01.status WITH DATATYPE = BOOLEAN, ENCODING = PLAIN",
"CREATE TIMESERIES root.ln.wf01.wt01.status.s1 WITH DATATYPE = BOOLEAN, ENCODING = PLAIN", "CREATE TIMESERIES root.ln.wf01.wt01.status.s1 WITH DATATYPE = BOOLEAN, ENCODING = PLAIN",
"CREATE TIMESERIES root.ln.wf01.wt01.temperature WITH DATATYPE = FLOAT, ENCODING = RLE, " "CREATE TIMESERIES root.ln.wf01.wt01.temperature WITH DATATYPE = FLOAT, ENCODING = RLE, "
...@@ -140,7 +141,8 @@ public class IoTDBMetadataFetchIT { ...@@ -140,7 +141,8 @@ public class IoTDBMetadataFetchIT {
Statement statement = connection.createStatement()) { Statement statement = connection.createStatement()) {
String[] sqls = new String[]{"show storage group", "show storage group root.ln.wf01", String[] sqls = new String[]{"show storage group", "show storage group root.ln.wf01",
"show storage group root.ln.wf01.wt01.status"}; "show storage group root.ln.wf01.wt01.status"};
String[] standards = new String[]{"root.ln.wf01.wt01,\n", "root.ln.wf01.wt01,\n", ""}; String[] standards = new String[]{"root.ln.wf01.wt01,\n" + "root.ln1.wf01.wt01,\n" + "root.ln2.wf01.wt01,\n",
"root.ln.wf01.wt01,\n", ""};
for (int n = 0; n < sqls.length; n++) { for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n]; String sql = sqls[n];
String standard = standards[n]; String standard = standards[n];
...@@ -158,7 +160,7 @@ public class IoTDBMetadataFetchIT { ...@@ -158,7 +160,7 @@ public class IoTDBMetadataFetchIT {
} }
} }
} }
Assert.assertEquals(builder.toString(), standard); Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("showStorageGroupTest() failed", e); logger.error("showStorageGroupTest() failed", e);
fail(e.getMessage()); fail(e.getMessage());
...@@ -199,7 +201,7 @@ public class IoTDBMetadataFetchIT { ...@@ -199,7 +201,7 @@ public class IoTDBMetadataFetchIT {
if (hasResultSet) { if (hasResultSet) {
try (ResultSet resultSet = statement.getResultSet()) { try (ResultSet resultSet = statement.getResultSet()) {
resultSet.next(); resultSet.next();
Assert.assertEquals(resultSet.getString(1), IoTDBConstant.VERSION); Assert.assertEquals(IoTDBConstant.VERSION, resultSet.getString(1));
} }
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -233,7 +235,7 @@ public class IoTDBMetadataFetchIT { ...@@ -233,7 +235,7 @@ public class IoTDBMetadataFetchIT {
} }
} }
} }
Assert.assertEquals(builder.toString(), standard); Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("showDevicesTest() failed", e); logger.error("showDevicesTest() failed", e);
fail(e.getMessage()); fail(e.getMessage());
...@@ -267,7 +269,7 @@ public class IoTDBMetadataFetchIT { ...@@ -267,7 +269,7 @@ public class IoTDBMetadataFetchIT {
} }
} }
} }
Assert.assertEquals(builder.toString(), standard); Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("showChildPaths() failed", e); logger.error("showChildPaths() failed", e);
fail(e.getMessage()); fail(e.getMessage());
...@@ -344,6 +346,41 @@ public class IoTDBMetadataFetchIT { ...@@ -344,6 +346,41 @@ public class IoTDBMetadataFetchIT {
} }
} }
@Test
public void showCountStorageGroup() 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[]{"count storage group root.ln", "count storage group",
"count storage group root.ln.wf01.wt01.status"};
String[] standards = new String[]{"1,\n", "3,\n", "0,\n"};
for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n];
String standard = standards[n];
StringBuilder builder = new StringBuilder();
try {
boolean hasResultSet = statement.execute(sql);
if (hasResultSet) {
try (ResultSet resultSet = statement.getResultSet()) {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()) {
for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
builder.append(resultSet.getString(i)).append(",");
}
builder.append("\n");
}
}
}
Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) {
logger.error("showCountStorageGroup() failed", e);
fail(e.getMessage());
}
}
}
}
@Test @Test
public void showCountTimeSeriesGroupBy() throws SQLException, ClassNotFoundException { public void showCountTimeSeriesGroupBy() throws SQLException, ClassNotFoundException {
Class.forName(Config.JDBC_DRIVER_NAME); Class.forName(Config.JDBC_DRIVER_NAME);
...@@ -351,7 +388,7 @@ public class IoTDBMetadataFetchIT { ...@@ -351,7 +388,7 @@ public class IoTDBMetadataFetchIT {
.getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root"); .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
Statement statement = connection.createStatement()) { Statement statement = connection.createStatement()) {
String[] sqls = new String[]{"COUNT TIMESERIES root group by level=1"}; String[] sqls = new String[]{"COUNT TIMESERIES root group by level=1"};
String[] standards = new String[]{"root.ln,3,\n"}; String[] standards = new String[]{"root.ln,3,\n" + "root.ln1,0,\n" + "root.ln2,0,\n"};
for (int n = 0; n < sqls.length; n++) { for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n]; String sql = sqls[n];
String standard = standards[n]; String standard = standards[n];
...@@ -369,7 +406,7 @@ public class IoTDBMetadataFetchIT { ...@@ -369,7 +406,7 @@ public class IoTDBMetadataFetchIT {
} }
} }
} }
Assert.assertEquals(builder.toString(), standard); Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("showCountTimeSeriesGroupBy() failed", e); logger.error("showCountTimeSeriesGroupBy() failed", e);
fail(e.getMessage()); fail(e.getMessage());
...@@ -385,7 +422,7 @@ public class IoTDBMetadataFetchIT { ...@@ -385,7 +422,7 @@ public class IoTDBMetadataFetchIT {
.getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root"); .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
Statement statement = connection.createStatement()) { Statement statement = connection.createStatement()) {
String[] sqls = new String[]{"COUNT NODES root level=1"}; String[] sqls = new String[]{"COUNT NODES root level=1"};
String[] standards = new String[]{"1,\n"}; String[] standards = new String[]{"3,\n"};
for (int n = 0; n < sqls.length; n++) { for (int n = 0; n < sqls.length; n++) {
String sql = sqls[n]; String sql = sqls[n];
String standard = standards[n]; String standard = standards[n];
...@@ -403,7 +440,7 @@ public class IoTDBMetadataFetchIT { ...@@ -403,7 +440,7 @@ public class IoTDBMetadataFetchIT {
} }
} }
} }
Assert.assertEquals(builder.toString(), standard); Assert.assertEquals(standard, builder.toString());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("showCountNodes() failed", e); logger.error("showCountNodes() failed", e);
fail(e.getMessage()); fail(e.getMessage());
...@@ -423,6 +460,11 @@ public class IoTDBMetadataFetchIT { ...@@ -423,6 +460,11 @@ public class IoTDBMetadataFetchIT {
+ "\n" + "\n"
+ "{\n" + "{\n"
+ "\t\"root\":{\n" + "\t\"root\":{\n"
+ "\t\t\"ln2\":{\n"
+ "\t\t\t\"wf01\":{\n"
+ "\t\t\t\t\"wt01\":{}\n"
+ "\t\t\t}\n"
+ "\t\t},\n"
+ "\t\t\"ln\":{\n" + "\t\t\"ln\":{\n"
+ "\t\t\t\"wf01\":{\n" + "\t\t\t\"wf01\":{\n"
+ "\t\t\t\t\"wt01\":{\n" + "\t\t\t\t\"wt01\":{\n"
...@@ -443,6 +485,11 @@ public class IoTDBMetadataFetchIT { ...@@ -443,6 +485,11 @@ public class IoTDBMetadataFetchIT {
+ "\t\t\t\t\t}\n" + "\t\t\t\t\t}\n"
+ "\t\t\t\t}\n" + "\t\t\t\t}\n"
+ "\t\t\t}\n" + "\t\t\t}\n"
+ "\t\t},\n"
+ "\t\t\"ln1\":{\n"
+ "\t\t\t\"wf01\":{\n"
+ "\t\t\t\t\"wt01\":{}\n"
+ "\t\t\t}\n"
+ "\t\t}\n" + "\t\t}\n"
+ "\t}\n" + "\t}\n"
+ "}"; + "}";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册