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

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

commit 542d1fb6a450a402a0415cbbe596a67f800921f6
Author: HTHou <[email protected]>
AuthorDate: Mon Sep 4 17:45:39 2023 +0800

    Support negative timestamp on CLI and fix time partition bug
---
 .../main/java/org/apache/iotdb/rpc/RpcUtils.java   | 29 +++++++++++++++++-----
 .../planner/plan/node/write/InsertTabletNode.java  | 28 +++++++++++++++------
 .../iotdb/db/storageengine/StorageEngine.java      |  4 ++-
 .../apache/iotdb/db/utils/TimePartitionUtils.java  |  6 ++++-
 4 files changed, 51 insertions(+), 16 deletions(-)

diff --git 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
index fbe805bd07f..7df45b5b821 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
@@ -247,9 +247,16 @@ public class RpcUtils {
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity 
warning
   public static String parseLongToDateWithPrecision(
       DateTimeFormatter formatter, long timestamp, ZoneId zoneid, String 
timestampPrecision) {
+    long integerOfDate;
+    StringBuilder digits;
     if ("ms".equals(timestampPrecision)) {
-      long integerOfDate = timestamp / 1000;
-      StringBuilder digits = new StringBuilder(Long.toString(timestamp % 
1000));
+      if (timestamp > 0 || timestamp % 1000 == 0) {
+        integerOfDate = timestamp / 1000;
+        digits = new StringBuilder(Long.toString(timestamp % 1000));
+      } else {
+        integerOfDate = timestamp / 1000 - 1;
+        digits = new StringBuilder(Long.toString(1000 + timestamp % 1000));
+      }
       ZonedDateTime dateTime =
           ZonedDateTime.ofInstant(Instant.ofEpochSecond(integerOfDate), 
zoneid);
       String datetime = dateTime.format(formatter);
@@ -261,8 +268,13 @@ public class RpcUtils {
       }
       return formatDatetimeStr(datetime, digits);
     } else if ("us".equals(timestampPrecision)) {
-      long integerOfDate = timestamp / 1000_000;
-      StringBuilder digits = new StringBuilder(Long.toString(timestamp % 
1000_000));
+      if (timestamp > 0 || timestamp % 1000_000 == 0) {
+        integerOfDate = timestamp / 1000_000;
+        digits = new StringBuilder(Long.toString(timestamp % 1000_000));
+      } else {
+        integerOfDate = timestamp / 1000_000 - 1;
+        digits = new StringBuilder(Long.toString(1000_000 + timestamp % 
1000_000));
+      }
       ZonedDateTime dateTime =
           ZonedDateTime.ofInstant(Instant.ofEpochSecond(integerOfDate), 
zoneid);
       String datetime = dateTime.format(formatter);
@@ -274,8 +286,13 @@ public class RpcUtils {
       }
       return formatDatetimeStr(datetime, digits);
     } else {
-      long integerOfDate = timestamp / 1000_000_000L;
-      StringBuilder digits = new StringBuilder(Long.toString(timestamp % 
1000_000_000L));
+      if (timestamp > 0 || timestamp % 1000_000_000L == 0) {
+        integerOfDate = timestamp / 1000_000_000L;
+        digits = new StringBuilder(Long.toString(timestamp % 1000_000_000L));
+      } else {
+        integerOfDate = timestamp / 1000_000_000L - 1;
+        digits = new StringBuilder(Long.toString(1000_000_000L + timestamp % 
1000_000_000L));
+      }
       ZonedDateTime dateTime =
           ZonedDateTime.ofInstant(Instant.ofEpochSecond(integerOfDate), 
zoneid);
       String datetime = dateTime.format(formatter);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
index c19b4f037d0..034267eb85e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
@@ -190,10 +190,16 @@ public class InsertTabletNode extends InsertNode 
implements WALEntryValue {
     if (times.length == 0) {
       return Collections.emptyList();
     }
-    long startTime =
-        (times[0] / TimePartitionUtils.timePartitionInterval)
-            * TimePartitionUtils.timePartitionInterval; // included
-    long endTime = startTime + TimePartitionUtils.timePartitionInterval; // 
excluded
+    long endTime;
+    if (times[0] > 0 || times[0] % TimePartitionUtils.timePartitionInterval == 
0) {
+      endTime =
+          (times[0] / TimePartitionUtils.timePartitionInterval + 1)
+              * TimePartitionUtils.timePartitionInterval; // excluded
+    } else {
+      endTime =
+          (times[0] / TimePartitionUtils.timePartitionInterval)
+              * TimePartitionUtils.timePartitionInterval; // excluded
+    }
     TTimePartitionSlot timePartitionSlot = 
TimePartitionUtils.getTimePartition(times[0]);
     int startLoc = 0; // included
 
@@ -208,10 +214,16 @@ public class InsertTabletNode extends InsertNode 
implements WALEntryValue {
         timePartitionSlots.add(timePartitionSlot);
         // next init
         startLoc = i;
-        startTime = endTime;
-        endTime =
-            (times[i] / TimePartitionUtils.timePartitionInterval + 1)
-                * TimePartitionUtils.timePartitionInterval;
+        if (times[0] > 0 || times[0] % 
TimePartitionUtils.timePartitionInterval == 0) {
+          endTime =
+              (times[i] / TimePartitionUtils.timePartitionInterval + 1)
+                  * TimePartitionUtils.timePartitionInterval;
+        } else {
+          endTime =
+              (times[i] / TimePartitionUtils.timePartitionInterval)
+                  * TimePartitionUtils.timePartitionInterval;
+        }
+
         timePartitionSlot = TimePartitionUtils.getTimePartition(times[i]);
       }
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
index d1b8cd8c1ff..1cbdf6e7397 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
@@ -163,7 +163,9 @@ public class StorageEngine implements IService {
     if (timePartitionInterval == -1) {
       initTimePartition();
     }
-    return time / timePartitionInterval;
+    return time > 0 || time % timePartitionInterval == 0
+        ? time / timePartitionInterval
+        : time / timePartitionInterval - 1;
   }
 
   /** block insertion if the insertion is rejected by memory control */
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TimePartitionUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TimePartitionUtils.java
index 3b5e0f8177e..608bac34e7f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TimePartitionUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TimePartitionUtils.java
@@ -28,7 +28,11 @@ public class TimePartitionUtils {
 
   public static TTimePartitionSlot getTimePartition(long time) {
     TTimePartitionSlot timePartitionSlot = new TTimePartitionSlot();
-    timePartitionSlot.setStartTime(time - time % timePartitionInterval);
+    if (time > 0 || time % timePartitionInterval == 0) {
+      timePartitionSlot.setStartTime(time / timePartitionInterval * 
timePartitionInterval);
+    } else {
+      timePartitionSlot.setStartTime((time / timePartitionInterval - 1) * 
timePartitionInterval);
+    }
     return timePartitionSlot;
   }
 

Reply via email to