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 2020/06/23 06:45:46 UTC

[incubator-iotdb] branch rel/0.9 updated: [IOTDB-779] To support "s ", "s 2", "s .2", "s.2" measurement. (#1402)

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

qiaojialin pushed a commit to branch rel/0.9
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/rel/0.9 by this push:
     new 6f1d44a  [IOTDB-779] To support "s ", "s 2", "s .2", "s.2" measurement. (#1402)
6f1d44a is described below

commit 6f1d44a64343ae038ce642776ccff9217f89a453
Author: Boris <zh...@gmail.com>
AuthorDate: Tue Jun 23 14:44:40 2020 +0800

    [IOTDB-779] To support "s ", "s 2", "s .2", "s.2" measurement. (#1402)
---
 .../java/org/apache/iotdb/db/metadata/MTree.java   |  8 +-------
 .../org/apache/iotdb/db/metadata/MetaUtils.java    | 10 ++++++++--
 .../iotdb/db/qp/executor/QueryProcessExecutor.java |  4 +++-
 .../iotdb/db/qp/strategy/LogicalGenerator.java     |  3 ---
 .../iotdb/db/integration/IoTDBQuotedPathIT.java    | 22 +++++++++++-----------
 .../main/java/org/apache/iotdb/session/Config.java | 15 +++++++++++++--
 .../java/org/apache/iotdb/session/Session.java     |  6 ++----
 .../org/apache/iotdb/session/IoTDBSessionIT.java   | 12 +++++++++---
 .../tsfile/common/constant/TsFileConstant.java     |  3 ++-
 .../org/apache/iotdb/tsfile/read/common/Path.java  | 12 ++++++------
 .../apache/iotdb/tsfile/read/common/PathTest.java  |  8 ++++----
 11 files changed, 59 insertions(+), 44 deletions(-)

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 135d436..56d972a 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
@@ -931,13 +931,7 @@ public class MTree implements Serializable {
     if (node.isLeaf()) {
       if (nodes.length <= idx) {
         String fileName = node.getDataFileName();
-        String nodeName;
-        if (node.getName().contains(TsFileConstant.PATH_SEPARATOR)) {
-          nodeName = "\"" + node + "\"";
-        } else {
-          nodeName = "" + node;
-        }
-        String nodePath = parent + nodeName;
+        String nodePath = parent + node;
         putAPath(paths, fileName, nodePath);
       }
       return;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
index 6899c2f..b542b81 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
@@ -18,19 +18,25 @@
  */
 package org.apache.iotdb.db.metadata;
 
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+
 public class MetaUtils {
+
+  private MetaUtils() { throw new IllegalStateException("Utility class"); }
+
   public static String[] getNodeNames(String path, String separator) {
     String[] nodeNames;
-    path = path.trim();
     if (path.contains("\"") || path.contains("\'")) {
       String[] deviceAndMeasurement;
+      String measurement;
       if (path.contains("\"")) {
         deviceAndMeasurement = path.split("\"");
+        measurement = TsFileConstant.DOUBLE_QUOTATION + deviceAndMeasurement[1] + TsFileConstant.DOUBLE_QUOTATION;
       } else {
         deviceAndMeasurement = path.split("\'");
+        measurement = TsFileConstant.SINGLE_QUOTATION + deviceAndMeasurement[1] + TsFileConstant.SINGLE_QUOTATION;
       }
       String device = deviceAndMeasurement[0];
-      String measurement = deviceAndMeasurement[1];
       String[] deviceNodeName = device.split(separator);
       int nodeNumber = deviceNodeName.length + 1;
       nodeNames = new String[nodeNumber];
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
index c267a9f..ead210f 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
@@ -68,6 +68,7 @@ import org.apache.iotdb.db.query.fill.IFill;
 import org.apache.iotdb.db.utils.AuthUtils;
 import org.apache.iotdb.db.utils.TypeInferenceUtils;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.exception.cache.CacheException;
 import org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
@@ -706,7 +707,8 @@ public class QueryProcessExecutor extends AbstractQueryProcessExecutor {
    */
   private void addPathToMTree(String deviceId, String measurementId, TSDataType dataType)
       throws PathException, MetadataException, StorageEngineException {
-    String fullPath = deviceId + IoTDBConstant.PATH_SEPARATOR + measurementId;
+    String fullPath;
+    fullPath = deviceId + IoTDBConstant.PATH_SEPARATOR + measurementId;
     TSEncoding defaultEncoding = getDefaultEncoding(dataType);
     CompressionType defaultCompressor =
         CompressionType.valueOf(TSFileDescriptor.getInstance().getConfig().getCompressor());
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
index 928b21b..fe596c0 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
@@ -581,9 +581,6 @@ public class LogicalGenerator {
     String[] measurementList = new String[astNode.getChild(1).getChildCount() - 1];
     for (int i = 1; i < astNode.getChild(1).getChildCount(); i++) {
       String measurement = astNode.getChild(1).getChild(i).getText();
-      if (measurement.contains("\"") || measurement.contains("\'")) {
-        measurement = measurement.substring(1, measurement.length() - 1);
-      }
       measurementList[i - 1] = measurement;
     }
     insertOp.setMeasurementList(measurementList);
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBQuotedPathIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBQuotedPathIT.java
index 6e86112..2c91d2d 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBQuotedPathIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBQuotedPathIT.java
@@ -53,21 +53,21 @@ public class IoTDBQuotedPathIT {
   @Test
   public void test() throws SQLException {
     try(Connection connection = DriverManager
-            .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();){
       String[] exp = new String[]{
-              "1509465600000,true",
-              "1509465600001,true",
-              "1509465600002,false",
-              "1509465600003,false"
+          "1509465600000,true",
+          "1509465600001,true",
+          "1509465600002,false",
+          "1509465600003,false"
       };
       statement.execute("SET STORAGE GROUP TO root.ln.wf01.wt01");
       statement.execute("CREATE TIMESERIES root.ln.wf01.wt01.\"status.2.3\" WITH DATATYPE=BOOLEAN, ENCODING=PLAIN");
       statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\"status.2.3\") values(1509465600000,true)");
-      statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\'status.2.3\') values(1509465600001,true)");
+      statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\"status.2.3\") values(1509465600001,true)");
       statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\"status.2.3\") values(1509465600002,false)");
-      statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\'status.2.3\') values(1509465600003,false)");
+      statement.execute("INSERT INTO root.ln.wf01.wt01(timestamp,\"status.2.3\") values(1509465600003,false)");
       statement.execute("SET STORAGE GROUP TO root.ln.wf01.wt02");
       statement.execute("CREATE TIMESERIES root.ln.wf01.wt02.\"abd\" WITH DATATYPE=BOOLEAN, ENCODING=PLAIN");
       statement.execute("CREATE TIMESERIES root.ln.wf01.wt02.\"asf.asd.sdf\" WITH DATATYPE=BOOLEAN, ENCODING=PLAIN");
@@ -89,11 +89,11 @@ public class IoTDBQuotedPathIT {
         assertEquals(exp[i], ans.get(i));
       }
 
-      hasResultSet = statement.execute("SELECT  * FROM root.ln.wf01.wt01 WHERE \'status.2.3\' = false");
+      hasResultSet = statement.execute("SELECT  * FROM root.ln.wf01.wt01 WHERE \"status.2.3\" = false");
       assertTrue(hasResultSet);
       exp = new String[]{
-              "1509465600002,false",
-              "1509465600003,false"
+          "1509465600002,false",
+          "1509465600003,false"
       };
       ans = new ArrayList<>();
       resultSet = statement.getResultSet();
diff --git a/session/src/main/java/org/apache/iotdb/session/Config.java b/session/src/main/java/org/apache/iotdb/session/Config.java
index daadf4f..5d1c7a5 100644
--- a/session/src/main/java/org/apache/iotdb/session/Config.java
+++ b/session/src/main/java/org/apache/iotdb/session/Config.java
@@ -21,12 +21,23 @@ package org.apache.iotdb.session;
 import static org.apache.iotdb.tsfile.common.constant.TsFileConstant.PATH_ROOT;
 import static org.apache.iotdb.tsfile.common.constant.TsFileConstant.PATH_SEPARATOR;
 
+import java.util.regex.Pattern;
+
 public class Config {
 
   public static final String DEFAULT_USER = "user";
   public static final String DEFAULT_PASSWORD = "password";
 
-  public static final String PATH_MATCHER =
-      PATH_ROOT + "([" + PATH_SEPARATOR + "](([a-zA-Z_][a-zA-Z0-9_-]*)|([+-]?[0-9]+)))+";
+  // e.g., a31+/$%#&[]{}3e4
+  private static final String ID_MATCHER = "(([a-zA-Z_][a-zA-Z0-9_-]*)|([+-]?[0-9]+))";
+
+  // e.g.,  .s1
+  private static final String NODE_MATCHER = "[" + PATH_SEPARATOR + "]" + ID_MATCHER;
+
+  // for path like: root.sg1.d1."1.2.3" or root.sg1.d1.'1.2.3', only occurs in the end of the path and only occurs once
+  private static final String NODE_WITH_QUOTATION_MARK_MATCHER =
+      "[" + PATH_SEPARATOR + "][\"|\']" + ID_MATCHER +"(" + NODE_MATCHER+ ")*[\"|\']";
+  public static final Pattern PATH_PATTERN = Pattern
+      .compile(PATH_ROOT + "(" + NODE_MATCHER + ")+(" + NODE_WITH_QUOTATION_MARK_MATCHER + ")?");
 
 }
diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java
index 31028ec..1b2c57b 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -39,9 +39,7 @@ import org.slf4j.LoggerFactory;
 import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Pattern;
-
-import static org.apache.iotdb.session.Config.PATH_MATCHER;
+import static org.apache.iotdb.session.Config.PATH_PATTERN;
 
 public class Session {
 
@@ -493,7 +491,7 @@ public class Session {
   }
 
   private void checkPathValidity(String path) throws IoTDBSessionException {
-    if (!Pattern.matches(PATH_MATCHER, path)) {
+    if (!PATH_PATTERN.matcher(path).matches()) {
       throw new IoTDBSessionException(
           String.format("Path [%s] is invalid", StringEscapeUtils.escapeJava(path)));
     }
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
index 5a36510..b2db8e0 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
@@ -136,6 +136,8 @@ public class IoTDBSessionIT {
         CompressionType.SNAPPY);
     session.createTimeseries("root.sg1.d1.s3", TSDataType.INT64, TSEncoding.RLE,
         CompressionType.SNAPPY);
+    session.createTimeseries("root.sg1.d1.\"s.4\"", TSDataType.INT64, TSEncoding.RLE,
+        CompressionType.SNAPPY);
     session.createTimeseries("root.sg1.d2.s1", TSDataType.INT64, TSEncoding.RLE,
         CompressionType.SNAPPY);
     session.createTimeseries("root.sg1.d2.s2", TSDataType.INT64, TSEncoding.RLE,
@@ -183,11 +185,13 @@ public class IoTDBSessionIT {
     measurements.add("s1");
     measurements.add("s2");
     measurements.add("s3");
+    measurements.add("\"s.4\"");
     for (long time = 0; time < 100; time++) {
       List<String> values = new ArrayList<>();
       values.add("1");
       values.add("2");
       values.add("3");
+      values.add("4");
       session.insert(deviceId, time, measurements, values);
     }
   }
@@ -226,12 +230,14 @@ public class IoTDBSessionIT {
     String path1 = "root.sg1.d1.s1";
     String path2 = "root.sg1.d1.s2";
     String path3 = "root.sg1.d1.s3";
+    String path4 = "root.sg1.d1.\"s.4\"";
     long deleteTime = 100;
 
     List<String> paths = new ArrayList<>();
     paths.add(path1);
     paths.add(path2);
     paths.add(path3);
+    paths.add(path4);
     session.deleteData(paths, deleteTime);
   }
 
@@ -242,7 +248,7 @@ public class IoTDBSessionIT {
   private void query() throws ClassNotFoundException, SQLException {
     Class.forName(Config.JDBC_DRIVER_NAME);
     String standard =
-        "Time\n" + "root.sg1.d1.s1\n" + "root.sg1.d1.s2\n" + "root.sg1.d1.s3\n"
+        "Time\n" + "root.sg1.d1.s1\n" + "root.sg1.d1.s2\n" + "root.sg1.d1.s3\n" + "root.sg1.d1.\"s.4\"\n"
             + "root.sg1.d2.s1\n" + "root.sg1.d2.s2\n" + "root.sg1.d2.s3\n";
     try (Connection connection = DriverManager
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
@@ -267,7 +273,7 @@ public class IoTDBSessionIT {
   private void query2() throws ClassNotFoundException, SQLException {
     Class.forName(Config.JDBC_DRIVER_NAME);
     String standard =
-        "Time\n" + "root.sg1.d1.s2\n" + "root.sg1.d1.s3\n"
+        "Time\n" + "root.sg1.d1.s2\n" + "root.sg1.d1.s3\n" + "root.sg1.d1.\"s.4\"\n"
             + "root.sg1.d2.s1\n" + "root.sg1.d2.s2\n" + "root.sg1.d2.s3\n";
     try (Connection connection = DriverManager
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
@@ -363,7 +369,7 @@ public class IoTDBSessionIT {
 
   private void insert_via_sql() throws TException, IoTDBRPCException {
     session.executeNonQueryStatement(
-        "insert into root.sg1.d1(timestamp,s1, s2, s3) values(100, 1,2,3)");
+        "insert into root.sg1.d1(timestamp,s1, s2, s3, \"s.4\") values(100, 1,2,3,4)");
   }
 
   @Test
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
index 693c51b..cfa2bc7 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
@@ -27,7 +27,8 @@ public class TsFileConstant {
   public static final String PATH_UPGRADE = "tmp";
   public static final String PATH_SEPARATOR = ".";
   public static final String PATH_SEPARATER_NO_REGEX = "\\.";
-  public static final String DEFAULT_DELTA_TYPE = "default_delta_type";
+  public static final String DOUBLE_QUOTATION = "\"";
+  public static final String SINGLE_QUOTATION = "\'";
 
   private TsFileConstant(){}
 }
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/Path.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/Path.java
index c91b75e..21dfb61 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/Path.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/Path.java
@@ -69,7 +69,7 @@ public class Path implements Serializable {
     }
     this.device = device;
     this.measurement = measurement;
-    this.fullPath = device + TsFileConstant.PATH_SEPARATOR + (measurement.contains(TsFileConstant.PATH_SEPARATOR) ? "\"" + measurement + "\"" : measurement);
+    this.fullPath = device + TsFileConstant.PATH_SEPARATOR + measurement;
   }
 
   /**
@@ -79,7 +79,6 @@ public class Path implements Serializable {
    * @return str[0] is the device string, and str[1] is the measurement string
    */
   private void init(String pathSc) {
-    pathSc = pathSc.trim();
     int i = 0;
     int j = 0;
     for (char c : pathSc.toCharArray()) {
@@ -92,22 +91,23 @@ public class Path implements Serializable {
     if ((i != 2 && i != 0) || (j != 2 && j != 0)) {
       throw new IllegalArgumentException("input pathSc single/double quotes error, not in pair or more than one pair!");
     }
-    if ((i == 2 && pathSc.length() - 1 != pathSc.lastIndexOf("\""))
-            || (j == 2 && pathSc.length() - 1 != pathSc.lastIndexOf("\'"))) {
+    if ((i == 2 && pathSc.length() - 1 != pathSc.lastIndexOf('\"'))
+            || (j == 2 && pathSc.length() - 1 != pathSc.lastIndexOf('\''))) {
       throw new IllegalArgumentException("input pathSc contains quoted string in the middle!");
     }
     String[] subStrs;
     if (i != 0 || j != 0) {
       if (i == 2) {
         subStrs = pathSc.split("\"");
+        measurement = TsFileConstant.DOUBLE_QUOTATION + subStrs[1] + TsFileConstant.DOUBLE_QUOTATION;
       } else {
         subStrs = pathSc.split("\'");
+        measurement = TsFileConstant.SINGLE_QUOTATION + subStrs[1] + TsFileConstant.SINGLE_QUOTATION;
       }
       device = subStrs[0];
-      if (!device.trim().equals("")) {
+      if (!device.equals("")) {
         device = device.substring(0, subStrs[0].length() - 1);
       }
-      measurement = subStrs[1];
       fullPath = pathSc;
     } else {
       StringContainer sc = new StringContainer(pathSc.split(TsFileConstant.PATH_SEPARATER_NO_REGEX), TsFileConstant.PATH_SEPARATOR);
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/read/common/PathTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/read/common/PathTest.java
index d048119..8ea28f9 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/read/common/PathTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/read/common/PathTest.java
@@ -43,7 +43,7 @@ public class PathTest {
     testPath(path, "", "", "");
     // with quote;
     path = new Path("root.d1.r1.\"x1.x2.x3\"");
-    testPath(path, "root.d1.r1", "x1.x2.x3", "root.d1.r1.\"x1.x2.x3\"");
+    testPath(path, "root.d1.r1", "\"x1.x2.x3\"", "root.d1.r1.\"x1.x2.x3\"");
   }
 
   @Test
@@ -66,7 +66,7 @@ public class PathTest {
     Path suffix2 = new Path("d.\"e.f\"");
     testPath(Path.mergePath(prefix, suffix), "a.b.c.d", "e", "a.b.c.d.e");
     testPath(Path.mergePath(prefix, suffix1), "a.b", "c", "a.b.c");
-    testPath(Path.mergePath(prefix, suffix2), "a.b.c.d", "e.f", "a.b.c.d.\"e.f\"");
+    testPath(Path.mergePath(prefix, suffix2), "a.b.c.d", "\"e.f\"", "a.b.c.d.\"e.f\"");
   }
 
   @Test
@@ -83,7 +83,7 @@ public class PathTest {
     Path desc = new Path("a.b.\"c\"");
     Path head = new Path("d.e");
     Path head1 = new Path("");
-    testPath(Path.addPrefixPath(desc, head), "d.e.a.b", "c", "d.e.a.b.\"c\"");
-    testPath(Path.mergePath(desc, head1), "a.b", "c", "a.b.\"c\"");
+    testPath(Path.addPrefixPath(desc, head), "d.e.a.b", "\"c\"", "d.e.a.b.\"c\"");
+    testPath(Path.mergePath(desc, head1), "a.b", "\"c\"", "a.b.\"c\"");
   }
 }
\ No newline at end of file