You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2022/12/13 08:21:58 UTC

[iotdb] branch master updated: [IOTDB-5119] fix bug that M4 throws exception when the window is empty

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

jackietien 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 4a68677055 [IOTDB-5119] fix bug that M4 throws exception when the window is empty
4a68677055 is described below

commit 4a68677055aaa281801222baa16948eb6d312fcd
Author: Rui,Lei <33...@users.noreply.github.com>
AuthorDate: Tue Dec 13 16:21:53 2022 +0800

    [IOTDB-5119] fix bug that M4 throws exception when the window is empty
---
 .../org/apache/iotdb/db/it/udf/IoTDBUDFM4IT.java   |  45 +++-
 .../apache/iotdb/commons/udf/builtin/UDTFM4.java   | 272 +++++++++++----------
 2 files changed, 177 insertions(+), 140 deletions(-)

diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFM4IT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFM4IT.java
index 6c62e55f63..36b028f326 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFM4IT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFM4IT.java
@@ -69,11 +69,43 @@ public class IoTDBUDFM4IT {
         .setUdfReaderMemoryBudgetInMB(100);
   }
 
+  @Test
+  public void test_M4_firstWindowEmpty() {
+    String[] res = new String[] {"120,8.0"};
+
+    String sql =
+        String.format(
+            "select M4(s1, '%s'='%s','%s'='%s','%s'='%s','%s'='%s') from root.vehicle.d1",
+            TIME_INTERVAL_KEY,
+            25,
+            SLIDING_STEP_KEY,
+            25,
+            DISPLAY_WINDOW_BEGIN_KEY,
+            75,
+            DISPLAY_WINDOW_END_KEY,
+            150);
+
+    try (Connection conn = EnvFactory.getEnv().getConnection();
+        Statement statement = conn.createStatement()) {
+      ResultSet resultSet = statement.executeQuery(sql);
+      int count = 0;
+      while (resultSet.next()) {
+        String str = resultSet.getString(1) + "," + resultSet.getString(2);
+        Assert.assertEquals(res[count], str);
+        count++;
+      }
+      Assert.assertEquals(res.length, count);
+    } catch (SQLException throwable) {
+      fail(throwable.getMessage());
+    }
+  }
+
   @Test
   public void test_M4_slidingTimeWindow() {
     String[] res =
         new String[] {
-          "1,5.0", "10,30.0", "20,20.0", "25,8.0", "30,40.0", "45,30.0", "52,8.0", "54,18.0"
+          "1,5.0", "10,30.0", "20,20.0", "25,8.0", "30,40.0", "45,30.0", "52,8.0", "54,18.0",
+          "120,8.0"
         };
 
     String sql =
@@ -86,7 +118,7 @@ public class IoTDBUDFM4IT {
             DISPLAY_WINDOW_BEGIN_KEY,
             0,
             DISPLAY_WINDOW_END_KEY,
-            100);
+            150);
 
     try (Connection conn = EnvFactory.getEnv().getConnection();
         Statement statement = conn.createStatement()) {
@@ -105,8 +137,7 @@ public class IoTDBUDFM4IT {
 
   @Test
   public void test_M4_slidingSizeWindow() {
-    String[] res =
-        new String[] {"1,5.0", "30,40.0", "33,9.0", "35,10.0", "45,30.0", "52,8.0", "54,18.0"};
+    String[] res = new String[] {"1,5.0", "30,40.0", "33,9.0", "35,10.0", "45,30.0", "120,8.0"};
 
     String sql =
         String.format(
@@ -168,7 +199,7 @@ public class IoTDBUDFM4IT {
   public void test_EQUAL_SIZE_BUCKET_M4_SAMPLE() {
     String[] res =
         new String[] {
-          "1,5.0", "8,8.0", "10,30.0", "27,20.0", "30,40.0", "45,30.0", "52,8.0", "54,18.0"
+          "1,5.0", "8,8.0", "10,30.0", "27,20.0", "30,40.0", "45,30.0", "52,8.0", "120,8.0"
         };
 
     String sql = "select EQUAL_SIZE_BUCKET_M4_SAMPLE(s1,'proportion'='0.5') from root.vehicle.d1";
@@ -240,7 +271,6 @@ public class IoTDBUDFM4IT {
   private static void generateData() {
     // data:
     // https://user-images.githubusercontent.com/33376433/151985070-73158010-8ba0-409d-a1c1-df69bad1aaee.png
-    // NOTE: The last point (120,8) is commented out, because bug#7738 has not been fixed
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
 
@@ -249,8 +279,7 @@ public class IoTDBUDFM4IT {
       statement.execute(String.format(Locale.ENGLISH, insertTemplate, "s1", 20, 1));
       statement.execute(String.format(Locale.ENGLISH, insertTemplate, "s1", 25, 8));
       statement.execute(String.format(Locale.ENGLISH, insertTemplate, "s1", 54, 3));
-      //      statement.execute(String.format(Locale.ENGLISH, insertTemplate, 120, 8)); // TODO add
-      // back after fixing bug#7738
+      statement.execute(String.format(Locale.ENGLISH, insertTemplate, "s1", 120, 8));
       statement.execute("FLUSH");
 
       statement.execute(String.format(Locale.ENGLISH, insertTemplate, "s1", 5, 10));
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFM4.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFM4.java
index 6351e548b3..134d5a2649 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFM4.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFM4.java
@@ -150,162 +150,170 @@ public class UDTFM4 implements UDTF {
   }
 
   public void transformInt(RowWindow rowWindow, PointCollector collector) throws IOException {
-    int firstValue = rowWindow.getRow(0).getInt(0);
-    int lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getInt(0);
-
-    int minValue = Math.min(firstValue, lastValue);
-    int maxValue = Math.max(firstValue, lastValue);
-    int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
-    int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
-
-    for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
-      int value = rowWindow.getRow(i).getInt(0);
-      if (value < minValue) {
-        minValue = value;
-        minIndex = i;
+    if (rowWindow.windowSize() > 0) { // else empty window do nothing
+      int firstValue = rowWindow.getRow(0).getInt(0);
+      int lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getInt(0);
+
+      int minValue = Math.min(firstValue, lastValue);
+      int maxValue = Math.max(firstValue, lastValue);
+      int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
+      int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
+
+      for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
+        int value = rowWindow.getRow(i).getInt(0);
+        if (value < minValue) {
+          minValue = value;
+          minIndex = i;
+        }
+        if (value > maxValue) {
+          maxValue = value;
+          maxIndex = i;
+        }
       }
-      if (value > maxValue) {
-        maxValue = value;
-        maxIndex = i;
-      }
-    }
-
-    Row row = rowWindow.getRow(0);
-    collector.putInt(row.getTime(), row.getInt(0));
 
-    int smallerIndex = Math.min(minIndex, maxIndex);
-    int largerIndex = Math.max(minIndex, maxIndex);
-    if (smallerIndex > 0) {
-      row = rowWindow.getRow(smallerIndex);
+      Row row = rowWindow.getRow(0);
       collector.putInt(row.getTime(), row.getInt(0));
-    }
-    if (largerIndex > smallerIndex) {
-      row = rowWindow.getRow(largerIndex);
-      collector.putInt(row.getTime(), row.getInt(0));
-    }
-    if (largerIndex < rowWindow.windowSize() - 1) {
-      row = rowWindow.getRow(rowWindow.windowSize() - 1);
-      collector.putInt(row.getTime(), row.getInt(0));
-    }
-  }
 
-  public void transformLong(RowWindow rowWindow, PointCollector collector) throws IOException {
-    long firstValue = rowWindow.getRow(0).getLong(0);
-    long lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getLong(0);
-
-    long minValue = Math.min(firstValue, lastValue);
-    long maxValue = Math.max(firstValue, lastValue);
-    int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
-    int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
-
-    for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
-      long value = rowWindow.getRow(i).getLong(0);
-      if (value < minValue) {
-        minValue = value;
-        minIndex = i;
+      int smallerIndex = Math.min(minIndex, maxIndex);
+      int largerIndex = Math.max(minIndex, maxIndex);
+      if (smallerIndex > 0) {
+        row = rowWindow.getRow(smallerIndex);
+        collector.putInt(row.getTime(), row.getInt(0));
+      }
+      if (largerIndex > smallerIndex) {
+        row = rowWindow.getRow(largerIndex);
+        collector.putInt(row.getTime(), row.getInt(0));
       }
-      if (value > maxValue) {
-        maxValue = value;
-        maxIndex = i;
+      if (largerIndex < rowWindow.windowSize() - 1) {
+        row = rowWindow.getRow(rowWindow.windowSize() - 1);
+        collector.putInt(row.getTime(), row.getInt(0));
       }
     }
+  }
 
-    Row row = rowWindow.getRow(0);
-    collector.putLong(row.getTime(), row.getLong(0));
+  public void transformLong(RowWindow rowWindow, PointCollector collector) throws IOException {
+    if (rowWindow.windowSize() > 0) { // else empty window do nothing
+      long firstValue = rowWindow.getRow(0).getLong(0);
+      long lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getLong(0);
+
+      long minValue = Math.min(firstValue, lastValue);
+      long maxValue = Math.max(firstValue, lastValue);
+      int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
+      int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
+
+      for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
+        long value = rowWindow.getRow(i).getLong(0);
+        if (value < minValue) {
+          minValue = value;
+          minIndex = i;
+        }
+        if (value > maxValue) {
+          maxValue = value;
+          maxIndex = i;
+        }
+      }
 
-    int smallerIndex = Math.min(minIndex, maxIndex);
-    int largerIndex = Math.max(minIndex, maxIndex);
-    if (smallerIndex > 0) {
-      row = rowWindow.getRow(smallerIndex);
+      Row row = rowWindow.getRow(0);
       collector.putLong(row.getTime(), row.getLong(0));
-    }
-    if (largerIndex > smallerIndex) {
-      row = rowWindow.getRow(largerIndex);
-      collector.putLong(row.getTime(), row.getLong(0));
-    }
-    if (largerIndex < rowWindow.windowSize() - 1) {
-      row = rowWindow.getRow(rowWindow.windowSize() - 1);
-      collector.putLong(row.getTime(), row.getLong(0));
-    }
-  }
 
-  public void transformFloat(RowWindow rowWindow, PointCollector collector) throws IOException {
-    float firstValue = rowWindow.getRow(0).getFloat(0);
-    float lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getFloat(0);
-
-    float minValue = Math.min(firstValue, lastValue);
-    float maxValue = Math.max(firstValue, lastValue);
-    int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
-    int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
-
-    for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
-      float value = rowWindow.getRow(i).getFloat(0);
-      if (value < minValue) {
-        minValue = value;
-        minIndex = i;
+      int smallerIndex = Math.min(minIndex, maxIndex);
+      int largerIndex = Math.max(minIndex, maxIndex);
+      if (smallerIndex > 0) {
+        row = rowWindow.getRow(smallerIndex);
+        collector.putLong(row.getTime(), row.getLong(0));
+      }
+      if (largerIndex > smallerIndex) {
+        row = rowWindow.getRow(largerIndex);
+        collector.putLong(row.getTime(), row.getLong(0));
       }
-      if (value > maxValue) {
-        maxValue = value;
-        maxIndex = i;
+      if (largerIndex < rowWindow.windowSize() - 1) {
+        row = rowWindow.getRow(rowWindow.windowSize() - 1);
+        collector.putLong(row.getTime(), row.getLong(0));
       }
     }
+  }
 
-    Row row = rowWindow.getRow(0);
-    collector.putFloat(row.getTime(), row.getFloat(0));
+  public void transformFloat(RowWindow rowWindow, PointCollector collector) throws IOException {
+    if (rowWindow.windowSize() > 0) { // else empty window do nothing
+      float firstValue = rowWindow.getRow(0).getFloat(0);
+      float lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getFloat(0);
+
+      float minValue = Math.min(firstValue, lastValue);
+      float maxValue = Math.max(firstValue, lastValue);
+      int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
+      int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
+
+      for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
+        float value = rowWindow.getRow(i).getFloat(0);
+        if (value < minValue) {
+          minValue = value;
+          minIndex = i;
+        }
+        if (value > maxValue) {
+          maxValue = value;
+          maxIndex = i;
+        }
+      }
 
-    int smallerIndex = Math.min(minIndex, maxIndex);
-    int largerIndex = Math.max(minIndex, maxIndex);
-    if (smallerIndex > 0) {
-      row = rowWindow.getRow(smallerIndex);
+      Row row = rowWindow.getRow(0);
       collector.putFloat(row.getTime(), row.getFloat(0));
-    }
-    if (largerIndex > smallerIndex) {
-      row = rowWindow.getRow(largerIndex);
-      collector.putFloat(row.getTime(), row.getFloat(0));
-    }
-    if (largerIndex < rowWindow.windowSize() - 1) {
-      row = rowWindow.getRow(rowWindow.windowSize() - 1);
-      collector.putFloat(row.getTime(), row.getFloat(0));
-    }
-  }
 
-  public void transformDouble(RowWindow rowWindow, PointCollector collector) throws IOException {
-    double firstValue = rowWindow.getRow(0).getDouble(0);
-    double lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getDouble(0);
-
-    double minValue = Math.min(firstValue, lastValue);
-    double maxValue = Math.max(firstValue, lastValue);
-    int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
-    int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
-
-    for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
-      double value = rowWindow.getRow(i).getDouble(0);
-      if (value < minValue) {
-        minValue = value;
-        minIndex = i;
+      int smallerIndex = Math.min(minIndex, maxIndex);
+      int largerIndex = Math.max(minIndex, maxIndex);
+      if (smallerIndex > 0) {
+        row = rowWindow.getRow(smallerIndex);
+        collector.putFloat(row.getTime(), row.getFloat(0));
+      }
+      if (largerIndex > smallerIndex) {
+        row = rowWindow.getRow(largerIndex);
+        collector.putFloat(row.getTime(), row.getFloat(0));
       }
-      if (value > maxValue) {
-        maxValue = value;
-        maxIndex = i;
+      if (largerIndex < rowWindow.windowSize() - 1) {
+        row = rowWindow.getRow(rowWindow.windowSize() - 1);
+        collector.putFloat(row.getTime(), row.getFloat(0));
       }
     }
+  }
 
-    Row row = rowWindow.getRow(0);
-    collector.putDouble(row.getTime(), row.getDouble(0));
+  public void transformDouble(RowWindow rowWindow, PointCollector collector) throws IOException {
+    if (rowWindow.windowSize() > 0) { // else empty window do nothing
+      double firstValue = rowWindow.getRow(0).getDouble(0);
+      double lastValue = rowWindow.getRow(rowWindow.windowSize() - 1).getDouble(0);
+
+      double minValue = Math.min(firstValue, lastValue);
+      double maxValue = Math.max(firstValue, lastValue);
+      int minIndex = (firstValue < lastValue) ? 0 : rowWindow.windowSize() - 1;
+      int maxIndex = (firstValue > lastValue) ? 0 : rowWindow.windowSize() - 1;
+
+      for (int i = 1; i < rowWindow.windowSize() - 1; i++) {
+        double value = rowWindow.getRow(i).getDouble(0);
+        if (value < minValue) {
+          minValue = value;
+          minIndex = i;
+        }
+        if (value > maxValue) {
+          maxValue = value;
+          maxIndex = i;
+        }
+      }
 
-    int smallerIndex = Math.min(minIndex, maxIndex);
-    int largerIndex = Math.max(minIndex, maxIndex);
-    if (smallerIndex > 0) {
-      row = rowWindow.getRow(smallerIndex);
-      collector.putDouble(row.getTime(), row.getDouble(0));
-    }
-    if (largerIndex > smallerIndex) {
-      row = rowWindow.getRow(largerIndex);
-      collector.putDouble(row.getTime(), row.getDouble(0));
-    }
-    if (largerIndex < rowWindow.windowSize() - 1) {
-      row = rowWindow.getRow(rowWindow.windowSize() - 1);
+      Row row = rowWindow.getRow(0);
       collector.putDouble(row.getTime(), row.getDouble(0));
+
+      int smallerIndex = Math.min(minIndex, maxIndex);
+      int largerIndex = Math.max(minIndex, maxIndex);
+      if (smallerIndex > 0) {
+        row = rowWindow.getRow(smallerIndex);
+        collector.putDouble(row.getTime(), row.getDouble(0));
+      }
+      if (largerIndex > smallerIndex) {
+        row = rowWindow.getRow(largerIndex);
+        collector.putDouble(row.getTime(), row.getDouble(0));
+      }
+      if (largerIndex < rowWindow.windowSize() - 1) {
+        row = rowWindow.getRow(rowWindow.windowSize() - 1);
+        collector.putDouble(row.getTime(), row.getDouble(0));
+      }
     }
   }
 }