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/05/30 08:27:40 UTC

[iotdb] branch IOTDB-3319 created (now 3e56d58316)

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

jackietien pushed a change to branch IOTDB-3319
in repository https://gitbox.apache.org/repos/asf/iotdb.git


      at 3e56d58316 [IOTDB-3319] fix IndexOutOfBoundsException when executing linear fill in group by query

This branch includes the following new commits:

     new 3e56d58316 [IOTDB-3319] fix IndexOutOfBoundsException when executing linear fill in group by query

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-3319] fix IndexOutOfBoundsException when executing linear fill in group by query

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

jackietien pushed a commit to branch IOTDB-3319
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 3e56d5831613907ef4d3e8e5c1ba7c2216654435
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Mon May 30 16:27:04 2022 +0800

    [IOTDB-3319] fix IndexOutOfBoundsException when executing linear fill in group by query
---
 .../operator/process/LinearFillOperator.java       |   3 +-
 .../execution/operator/LinearFillOperatorTest.java | 113 ++++++++++++++++++++-
 2 files changed, 111 insertions(+), 5 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/LinearFillOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/LinearFillOperator.java
index 35277da1ae..dbbe1b638a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/LinearFillOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/LinearFillOperator.java
@@ -125,7 +125,8 @@ public class LinearFillOperator implements ProcessOperator {
     TsBlock result =
         new TsBlock(originTsBlock.getPositionCount(), originTsBlock.getTimeColumn(), columns);
     for (int i = 0; i < outputColumnCount; i++) {
-      nextTsBlockIndex[i]--;
+      // make sure nextTsBlockIndex for each column >= 1
+      nextTsBlockIndex[i] = Math.max(1, nextTsBlockIndex[i] - 1);
     }
     return result;
   }
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/LinearFillOperatorTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/LinearFillOperatorTest.java
index 6c17c09d4f..2fb9898418 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/LinearFillOperatorTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/LinearFillOperatorTest.java
@@ -233,8 +233,8 @@ public class LinearFillOperatorTest {
       }
 
       assertTrue(fillOperator.isFinished());
-      assertEquals(3, count);
-      assertEquals(4, nullBlockIndex);
+      assertEquals(res.length, count);
+      assertEquals(nullBlock.length, nullBlockIndex);
 
     } finally {
       instanceNotificationExecutor.shutdown();
@@ -431,8 +431,113 @@ public class LinearFillOperatorTest {
       }
 
       assertTrue(fillOperator.isFinished());
-      assertEquals(3, count);
-      assertEquals(5, nullBlockIndex);
+      assertEquals(res.length, count);
+      assertEquals(nullBlock.length, nullBlockIndex);
+
+    } finally {
+      instanceNotificationExecutor.shutdown();
+    }
+  }
+
+  @Test
+  public void batchLinearFillTest3() {
+    ExecutorService instanceNotificationExecutor =
+        IoTDBThreadPoolFactory.newFixedThreadPool(1, "test-instance-notification");
+    try {
+      QueryId queryId = new QueryId("stub_query");
+      FragmentInstanceId instanceId =
+          new FragmentInstanceId(new PlanFragmentId(queryId, 0), "stub-instance");
+      FragmentInstanceStateMachine stateMachine =
+          new FragmentInstanceStateMachine(instanceId, instanceNotificationExecutor);
+      FragmentInstanceContext fragmentInstanceContext =
+          createFragmentInstanceContext(instanceId, stateMachine);
+      PlanNodeId planNodeId1 = new PlanNodeId("1");
+      fragmentInstanceContext.addOperatorContext(
+          1, planNodeId1, LinearFillOperator.class.getSimpleName());
+
+      LinearFill[] fillArray = new LinearFill[] {new FloatLinearFill()};
+      LinearFillOperator fillOperator =
+          new LinearFillOperator(
+              fragmentInstanceContext.getOperatorContexts().get(0),
+              fillArray,
+              new Operator() {
+                private int index = 0;
+                private final float[][][] value =
+                    new float[][][] {
+                      {{0.0f}}, {{2.0f}}, {{3.0f}}, {{4.0f}}, {{0.0f}}, {{0.0f}}, {{0.0f}}
+                    };
+                final boolean[][][] isNull =
+                    new boolean[][][] {
+                      {{true}}, {{false}}, {{false}}, {{false}}, {{true}}, {{true}}, {{true}}
+                    };
+
+                @Override
+                public OperatorContext getOperatorContext() {
+                  return null;
+                }
+
+                @Override
+                public TsBlock next() {
+                  TsBlockBuilder builder = new TsBlockBuilder(ImmutableList.of(TSDataType.FLOAT));
+                  for (int i = 0; i < 1; i++) {
+                    builder.getTimeColumnBuilder().writeLong(i + index);
+                    for (int j = 0; j < 1; j++) {
+                      if (isNull[index][i][j]) {
+                        builder.getColumnBuilder(j).appendNull();
+                      } else {
+                        builder.getColumnBuilder(j).writeFloat(value[index][i][j]);
+                      }
+                    }
+                    builder.declarePosition();
+                  }
+                  index++;
+                  return builder.build();
+                }
+
+                @Override
+                public boolean hasNext() {
+                  return index < 7;
+                }
+
+                @Override
+                public boolean isFinished() {
+                  return index >= 7;
+                }
+              });
+
+      int count = 0;
+      float[][][] res =
+          new float[][][] {{{0.0f}}, {{2.0f}}, {{3.0f}}, {{4.0f}}, {{0.0f}}, {{0.0f}}, {{0.0f}}};
+      boolean[][][] isNull =
+          new boolean[][][] {
+            {{true}}, {{false}}, {{false}}, {{false}}, {{true}}, {{true}}, {{true}}
+          };
+
+      boolean[] nullBlock =
+          new boolean[] {true, false, false, false, false, true, true, true, false, false, false};
+      int nullBlockIndex = 0;
+      while (fillOperator.hasNext()) {
+        TsBlock block = fillOperator.next();
+        assertEquals(nullBlock[nullBlockIndex++], block == null);
+        if (block == null) {
+          continue;
+        }
+        for (int i = 0; i < block.getPositionCount(); i++) {
+          long expectedTime = i + count;
+          assertEquals(expectedTime, block.getTimeByIndex(i));
+          for (int j = 0; j < 1; j++) {
+            assertEquals(isNull[count][i][j], block.getColumn(j).isNull(i));
+            if (!isNull[count][i][j]) {
+              assertEquals(res[count][i][j], block.getColumn(j).getFloat(i), 0.00001f);
+            }
+          }
+        }
+        count++;
+      }
+
+      assertTrue(fillOperator.isFinished());
+      assertEquals(res.length, count);
+      assertEquals(nullBlock.length, nullBlockIndex);
 
     } finally {
       instanceNotificationExecutor.shutdown();