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/12/29 08:45:12 UTC

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

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

qiaojialin 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 7c2628e  [IOTDB-1065] Fix deletion bug while trying to delete data from a timeseries which contains comma (#2306)
7c2628e is described below

commit 7c2628e95473aaded1f1e27a3f2c2650d7ba2ad0
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 e84d55e..f62170c 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",