You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ha...@apache.org on 2020/12/29 08:47:39 UTC

[iotdb] branch comma_bug created (now 1418da8)

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

haonan pushed a change to branch comma_bug
in repository https://gitbox.apache.org/repos/asf/iotdb.git.


      at 1418da8  [IOTDB-1065] Fix deletion bug while trying to delete data from a timeseries which contains comma (#2306)

This branch includes the following new commits:

     new 1418da8  [IOTDB-1065] Fix deletion bug while trying to delete data from a timeseries which contains comma (#2306)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[iotdb] 01/01: [IOTDB-1065] Fix deletion bug while trying to delete data from a timeseries which contains comma (#2306)

Posted by ha...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

haonan pushed a commit to branch comma_bug
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 1418da80176e24423ae63e04fc25a71f56c57ce3
Author: wshao08 <59...@users.noreply.github.com>
AuthorDate: Tue Dec 29 16:44:51 2020 +0800

    [IOTDB-1065] Fix deletion bug while trying to delete data from a timeseries which contains comma (#2306)
---
 .../io/LocalTextModificationAccessor.java          | 61 ++++++++++++++++------
 .../iotdb/db/integration/IoTDBDeletionIT.java      | 35 +++++++++++++
 2 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java b/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
index 7c41115..8e09964 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/modification/io/LocalTextModificationAccessor.java
@@ -23,6 +23,7 @@ import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import org.apache.iotdb.db.engine.modification.Deletion;
@@ -127,33 +128,63 @@ public class LocalTextModificationAccessor implements ModificationReader, Modifi
         + del.getStartTime() + SEPARATOR + del.getEndTime();
   }
 
+  /**
+   * Decode a range deletion record. E.g. "DELETION,root.ln.wf01.wt01.temperature,111,100,300"
+   * the index of field endTimestamp is length - 1, startTimestamp is length - 2,
+   * versionNum is length - 3. Fields in index range [1, length -3) all belong
+   * to a timeseries path in case when the path contains comma.
+   */
   private static Deletion decodeDeletion(String[] fields) throws IOException {
-    if (fields.length != 5 && fields.length != 4) {
+    if (fields.length < 4) {
       throw new IOException("Incorrect deletion fields number: " + fields.length);
     }
 
-    String path = fields[1];
-    long versionNum;
-    long startTimestamp = Long.MIN_VALUE;
+    String path = "";
+    long startTimestamp;
     long endTimestamp;
+    long versionNum;
     try {
-      versionNum = Long.parseLong(fields[2]);
+      versionNum = Long.parseLong(fields[fields.length - 3]);
     } catch (NumberFormatException e) {
-      throw new IOException("Invalid version number: " + fields[2]);
+      return decodePointDeletion(fields);
     }
 
     try {
-      if (fields.length == 4) {
-        endTimestamp = Long.parseLong(fields[3]);
-
-      } else {
-        startTimestamp = Long.parseLong(fields[3]);
-        endTimestamp = Long.parseLong(fields[4]);
-      }
-      return new Deletion(new PartialPath(path), versionNum, startTimestamp, endTimestamp);
-    } catch (NumberFormatException | IllegalPathException e) {
+      endTimestamp = Long.parseLong(fields[fields.length - 1]);
+      startTimestamp = Long.parseLong(fields[fields.length - 2]);
+    } catch (NumberFormatException e) {
       throw new IOException("Invalid timestamp: " + e.getMessage());
     }
+    try {
+      String[] pathArray = Arrays.copyOfRange(fields, 1, fields.length - 3);
+      path = String.join(SEPARATOR, pathArray);
+      return new Deletion(new PartialPath(path), versionNum, startTimestamp, endTimestamp);
+    } catch (IllegalPathException e) {
+      throw new IOException("Invalid series path: " + path);
+    }
+  }
 
+  /**
+   * Decode a point deletion record. E.g. "DELETION,root.ln.wf01.wt01.temperature,111,300"
+   * the index of field endTimestamp is length - 1, versionNum is length - 2.
+   * Fields in index range [1, length - 2) compose timeseries path.
+   */
+  private static Deletion decodePointDeletion(String[] fields) throws IOException {
+    String path = "";
+    long versionNum;
+    long endTimestamp;
+    try {
+      endTimestamp = Long.parseLong(fields[fields.length - 1]);
+      versionNum = Long.parseLong(fields[fields.length - 2]);
+    } catch (NumberFormatException e) {
+      throw new IOException("Invalid timestamp: " + e.getMessage());
+    }
+    try {
+      String[] pathArray = Arrays.copyOfRange(fields, 1, fields.length - 2);
+      path = String.join(SEPARATOR, pathArray);
+      return new Deletion(new PartialPath(path), versionNum, endTimestamp);
+    } catch (IllegalPathException e) {
+      throw new IOException("Invalid series path: " + path);
+    }
   }
 }
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDeletionIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDeletionIT.java
index 1414d13..77c4f90 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDeletionIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDeletionIT.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -278,6 +279,40 @@ public class IoTDBDeletionIT {
     IoTDBDescriptor.getInstance().getConfig().setMemtableSizeThreshold(size);
   }
 
+  @Test
+  public void testDelSeriesWithSpecialSymbol() throws SQLException {
+    try (Connection connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root",
+            "root");
+         Statement statement = connection.createStatement()) {
+      statement.execute("CREATE TIMESERIES root.ln.d1.\"status,01\" WITH DATATYPE=BOOLEAN,"
+          + " ENCODING=PLAIN");
+      statement.execute("INSERT INTO root.ln.d1(timestamp,\"status,01\") "
+          + "values(300,true)");
+      statement.execute("INSERT INTO root.ln.d1(timestamp,\"status,01\") VALUES(500, false)");
+
+      statement.execute("DELETE FROM root.ln.d1.\"status,01\" WHERE time <= 400");
+
+      try (ResultSet resultSet = statement.executeQuery("select \"status,01\" from root.ln.d1")) {
+        int cnt = 0;
+        while (resultSet.next()) {
+          cnt++;
+        }
+        Assert.assertEquals(1, cnt);
+      }
+
+      statement.execute("DELETE FROM root.ln.d1.\"status,01\"");
+
+      try (ResultSet resultSet = statement.executeQuery("select \"status,01\" from root.ln.d1")) {
+        int cnt = 0;
+        while (resultSet.next()) {
+          cnt++;
+        }
+        Assert.assertEquals(0, cnt);
+      }
+    }
+  }
+
   private static void prepareSeries() {
     try (Connection connection = DriverManager
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root",