You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2023/04/26 14:54:27 UTC
[iotdb] branch master updated: [IOTDB-5824] Fix show devices with * cannot display satisfied devices (#9715)
This is an automated email from the ASF dual-hosted git repository.
zyk 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 33f5f6ec78 [IOTDB-5824] Fix show devices with * cannot display satisfied devices (#9715)
33f5f6ec78 is described below
commit 33f5f6ec7888f5c2c2ee539985dc495c3410bf01
Author: Chen YZ <43...@users.noreply.github.com>
AuthorDate: Wed Apr 26 22:54:20 2023 +0800
[IOTDB-5824] Fix show devices with * cannot display satisfied devices (#9715)
---
.../iotdb/confignode/manager/ConfigManager.java | 11 ++---
.../iotdb/db/it/schema/IoTDBMetadataFetchIT.java | 49 ++++++++++++++++++++++
.../org/apache/iotdb/commons/path/PartialPath.java | 40 ++++++++++++++++++
3 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index d3cbaa2518..6d5442e3f1 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -193,7 +193,6 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
import static org.apache.iotdb.commons.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
/** Entry of all management, AssignPartitionManager,AssignRegionManager. */
@@ -589,8 +588,11 @@ public class ConfigManager implements IManager {
if (path.getFullPath().contains(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD)) {
return new ArrayList<>();
}
- // path doesn't contain * so the size of innerPathList should be 1
- PartialPath innerPath = path.alterPrefixPath(database).get(0);
+ List<PartialPath> innerPathList = path.alterPrefixPath(database);
+ if (innerPathList.size() == 0) {
+ return new ArrayList<>();
+ }
+ PartialPath innerPath = innerPathList.get(0);
// The innerPath contains `*` and the only `*` is not in last level
if (innerPath.getDevice().contains(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD)) {
return new ArrayList<>();
@@ -626,8 +628,7 @@ public class ConfigManager implements IManager {
for (int i = 0; i < allDatabases.size(); i++) {
String database = allDatabases.get(i);
PartialPath databasePath = allDatabasePaths.get(i);
- if (path.overlapWith(databasePath.concatNode(MULTI_LEVEL_PATH_WILDCARD))
- && !scanAllRegions.containsKey(database)) {
+ if (path.overlapWithFullPathPrefix(databasePath) && !scanAllRegions.containsKey(database)) {
List<TSeriesPartitionSlot> relatedSlot = calculateRelatedSlot(path, databasePath);
if (relatedSlot.isEmpty()) {
scanAllRegions.put(database, true);
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
index d51e0e4fe5..9c877983a2 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBMetadataFetchIT.java
@@ -275,6 +275,55 @@ public class IoTDBMetadataFetchIT extends AbstractSchemaIT {
}
}
+ @Test
+ public void showDevicesWithWildcardTest() throws SQLException {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ String[] sqls =
+ new String[] {
+ "show devices root.l*.wf01.w*",
+ "show devices root.ln.*f01.*",
+ "show devices root.l*.*f*.*1",
+ };
+ Set<String>[] standards =
+ new Set[] {
+ new HashSet<>(
+ Arrays.asList(
+ "root.ln.wf01.wt01,false,",
+ "root.ln.wf01.wt02,true,",
+ "root.ln1.wf01.wt01,false,",
+ "root.ln2.wf01.wt01,false,")),
+ new HashSet<>(Arrays.asList("root.ln.wf01.wt01,false,", "root.ln.wf01.wt02,true,")),
+ new HashSet<>(
+ Arrays.asList(
+ "root.ln.wf01.wt01,false,",
+ "root.ln1.wf01.wt01,false,",
+ "root.ln2.wf01.wt01,false,"))
+ };
+
+ for (int n = 0; n < sqls.length; n++) {
+ String sql = sqls[n];
+ Set<String> standard = standards[n];
+ try (ResultSet resultSet = statement.executeQuery(sql)) {
+ 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(",");
+ }
+ String string = builder.toString();
+ Assert.assertTrue(standard.contains(string));
+ standard.remove(string);
+ }
+ assertEquals(0, standard.size());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+ }
+ }
+
@Test
public void showChildPaths() throws SQLException {
try (Connection connection = EnvFactory.getEnv().getConnection();
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
index 8eea86c232..d9318996de 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
@@ -457,6 +457,46 @@ public class PartialPath extends Path implements Comparable<Path>, Cloneable {
return this.nodes.length == rNodes.length;
}
+ /**
+ * Test if this path pattern overlaps with input prefix full path. Overlap means the result sets
+ * generated by two path pattern share some common elements. e.g.
+ *
+ * <ul>
+ * <li>"root.sg.**" overlaps with prefix full path "root" because "root.sg.**" share some common
+ * element "root.sg.d" with "root.**"
+ * <li>"root.*.d*.s" overlaps with prefix full path "root.sg" because "root.*.d*.s" share some
+ * common element "root.sg.d1.s" with "root.sg.**"
+ * <li>"root.*.d.s" doesn't overlap with prefix full path "root.sg.d1" because there is no
+ * common element between "root.*.d.s" and "root.sg.d1.**"
+ * </ul>
+ *
+ * @param prefixFullPath prefix full path
+ * @return true if overlapping otherwise return false
+ */
+ public boolean overlapWithFullPathPrefix(PartialPath prefixFullPath) {
+ String[] rNodes = prefixFullPath.getNodes();
+ int rNodesIndex = 0;
+ for (int i = 0; i < this.nodes.length && rNodesIndex < rNodes.length; i++) {
+ // if encounter MULTI_LEVEL_PATH_WILDCARD
+ if (nodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+ return true;
+ } else if (nodes[i].equals(ONE_LEVEL_PATH_WILDCARD)) {
+ rNodesIndex++;
+ } else if (nodes[i].contains(ONE_LEVEL_PATH_WILDCARD)) {
+ if (!Pattern.compile(nodes[i].replace("*", ".*")).matcher(rNodes[rNodesIndex]).matches()) {
+ return false;
+ } else {
+ rNodesIndex++;
+ }
+ } else if (nodes[i].equals(rNodes[rNodesIndex])) {
+ rNodesIndex++;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Try to check overlap between nodes1 and nodes2 with MULTI_LEVEL_PATH_WILDCARD. Time complexity
* O(n^2).