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/04/17 01:34:00 UTC

[incubator-iotdb] branch master updated: Fix Nullpointer bug in Previous Fill (#1062)

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/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new a0c49d5  Fix Nullpointer bug in Previous Fill (#1062)
a0c49d5 is described below

commit a0c49d56b020aad8e095d597ed0d1f14a9a1ed73
Author: wshao08 <59...@users.noreply.github.com>
AuthorDate: Fri Apr 17 09:33:49 2020 +0800

    Fix Nullpointer bug in Previous Fill (#1062)
    
    * Fix Nullpointer bug in Previous Fill
---
 .../apache/iotdb/db/query/fill/PreviousFill.java   | 38 ++++-------
 .../apache/iotdb/db/integration/IoTDBFillIT.java   | 77 ++++++++++++++++++++++
 2 files changed, 89 insertions(+), 26 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java b/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
index b209c58..28bd1c1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
@@ -141,8 +141,7 @@ public class PreviousFill extends IFill {
           FileLoaderUtils.loadTimeSeriesMetadata(
               resource, seriesPath, context, timeFilter, allSensors);
       if (timeseriesMetadata != null) {
-        if (timeseriesMetadata.getStatistics().canUseStatistics()
-            && endtimeContainedByTimeFilter(timeseriesMetadata.getStatistics())) {
+        if (endtimeContainedByTimeFilter(timeseriesMetadata.getStatistics())) {
           return constructLastPair(
               timeseriesMetadata.getStatistics().getEndTime(),
               timeseriesMetadata.getStatistics().getLastValue(),
@@ -172,36 +171,23 @@ public class PreviousFill extends IFill {
     PriorityQueue<TsFileResource> unseqFileResource =
         sortUnSeqFileResourcesInDecendingOrder(dataSource.getUnseqResources());
 
-    while (!unseqFileResource.isEmpty()) {
-      // The very end time of unseq files is smaller than lBoundTime,
-      // then skip all the rest unseq files
-      if (unseqFileResource.peek().getEndTimeMap().get(seriesPath.getDevice()) < lBoundTime) {
-        return;
-      }
-      TimeseriesMetadata timeseriesMetadata =
-          FileLoaderUtils.loadTimeSeriesMetadata(
-              unseqFileResource.poll(), seriesPath, context, timeFilter, allSensors);
-      if (timeseriesMetadata != null && timeseriesMetadata.getStatistics().canUseStatistics()
-          && lBoundTime <= timeseriesMetadata.getStatistics().getEndTime()) {
-        // The last timeseriesMetadata will be used as a pivot to filter the rest unseq files.
-        // Update lBoundTime with the last timeseriesMetadata's start time
-        lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getStartTime());
-        unseqTimeseriesMetadataList.add(timeseriesMetadata);
-        break;
-      }
-    }
-
-    // unpack all overlapped unseq files and fill unseqTimeseriesMetadata list
     while (!unseqFileResource.isEmpty()
         && (lBoundTime <= unseqFileResource.peek().getEndTimeMap().get(seriesPath.getDevice()))) {
       TimeseriesMetadata timeseriesMetadata =
           FileLoaderUtils.loadTimeSeriesMetadata(
               unseqFileResource.poll(), seriesPath, context, timeFilter, allSensors);
+
+      if (timeseriesMetadata == null || (timeseriesMetadata.getStatistics().canUseStatistics()
+          && timeseriesMetadata.getStatistics().getEndTime() < lBoundTime)) {
+        continue;
+      }
       unseqTimeseriesMetadataList.add(timeseriesMetadata);
-      // update lBoundTime if current unseq timeseriesMetadata's last point is a valid result
-      if (timeseriesMetadata.getStatistics().canUseStatistics()
-          && endtimeContainedByTimeFilter(timeseriesMetadata.getStatistics())) {
-        lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getEndTime());
+      if (timeseriesMetadata.getStatistics().canUseStatistics()) {
+        if (endtimeContainedByTimeFilter(timeseriesMetadata.getStatistics())) {
+          lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getEndTime());
+        } else {
+          lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getStartTime());
+        }
       }
     }
   }
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBFillIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBFillIT.java
index 4bcf9dd..134d815 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBFillIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBFillIT.java
@@ -568,6 +568,83 @@ Statement statement = connection.createStatement()) {
     }
   }
 
+  @Test
+  public void PreviousFillWithNullUnseqFilesTest() throws SQLException {
+    String[] retArray1 = new String[]{
+        "990,1020.5,true",
+    };
+    try (Connection connection = DriverManager.
+        getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+        Statement statement = connection.createStatement()) {
+
+      int cnt = 0;
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp, temperature, status) values(1030, 21.6, true)");
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp,status) values(940, true)");
+      statement.execute("flush");
+
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp,status) values(740, false)");
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp,status) values(980, true)");
+      statement.execute("flush");
+
+      {
+        ResultSet resultSet = statement.executeQuery(
+            "select temperature,status from root.ln.wf01.wt02 where time = 990 "
+                + "Fill(double[previous])");
+
+        while (resultSet.next()) {
+          String ans = resultSet.getString(TIMESTAMP_STR) + ","
+              + resultSet.getString(TEMPERATURE_STR_2) + ","
+              + resultSet.getString(STATUS_STR_2);
+          Assert.assertEquals(retArray1[cnt], ans);
+          cnt++;
+        }
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void PreviousFillWithDeletionTest() throws SQLException {
+    String[] retArray1 = new String[]{
+        "1080,21.6,true",
+    };
+    try (Connection connection = DriverManager.
+        getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+        Statement statement = connection.createStatement()) {
+
+      int cnt = 0;
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp, temperature, status) values(1030, 21.6, true)");
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp, temperature, status) values(940, 188.2, false)");
+
+
+      statement.execute("DELETE FROM root.ln.wf01.wt02.temperature WHERE time < 1000");
+      statement.execute("flush");
+      statement.execute("INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status) values(980, 47.22, true)");
+      statement.execute("flush");
+
+      {
+        ResultSet resultSet = statement.executeQuery(
+            "select temperature,status from root.ln.wf01.wt02 where time = 1080 "
+                + "Fill(double[previous])");
+
+        while (resultSet.next()) {
+          String ans = resultSet.getString(TIMESTAMP_STR) + ","
+              + resultSet.getString(TEMPERATURE_STR_2) + ","
+              + resultSet.getString(STATUS_STR_2);
+          Assert.assertEquals(retArray1[cnt], ans);
+          cnt++;
+        }
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
   private void prepareData() {
     try (Connection connection = DriverManager
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root",