This is an automated email from the ASF dual-hosted git repository.
abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 157fe1bc1f0 fix a mistake in CursorGranularizer to check doneness
after advance (#17175)
157fe1bc1f0 is described below
commit 157fe1bc1f0df933dcb1114960ee56d4b184f0aa
Author: Clint Wylie <[email protected]>
AuthorDate: Thu Sep 26 21:06:05 2024 -0700
fix a mistake in CursorGranularizer to check doneness after advance (#17175)
Fixes a mistake introduced in #16533 which can result in CursorGranularizer
incorrectly trying to get values from a selector after calling cursor.advance
because of a missing check for cursor.isDone
---
.../org/apache/druid/query/CursorGranularizer.java | 8 +-
.../apache/druid/query/CursorGranularizerTest.java | 133 ++++++++++++++++++---
.../org/apache/druid/segment/IndexBuilder.java | 19 ++-
3 files changed, 142 insertions(+), 18 deletions(-)
diff --git
a/processing/src/main/java/org/apache/druid/query/CursorGranularizer.java
b/processing/src/main/java/org/apache/druid/query/CursorGranularizer.java
index fa2defce7f0..6bc387183ba 100644
--- a/processing/src/main/java/org/apache/druid/query/CursorGranularizer.java
+++ b/processing/src/main/java/org/apache/druid/query/CursorGranularizer.java
@@ -147,12 +147,16 @@ public class CursorGranularizer
if (descending) {
while (currentTime >= currentBucketEnd && !cursor.isDone()) {
cursor.advance();
- currentTime = timeSelector.getLong();
+ if (!cursor.isDone()) {
+ currentTime = timeSelector.getLong();
+ }
}
} else {
while (currentTime < currentBucketStart && !cursor.isDone()) {
cursor.advance();
- currentTime = timeSelector.getLong();
+ if (!cursor.isDone()) {
+ currentTime = timeSelector.getLong();
+ }
}
}
diff --git
a/processing/src/test/java/org/apache/druid/query/CursorGranularizerTest.java
b/processing/src/test/java/org/apache/druid/query/CursorGranularizerTest.java
index 863c01bb390..ecb8b7d88b8 100644
---
a/processing/src/test/java/org/apache/druid/query/CursorGranularizerTest.java
+++
b/processing/src/test/java/org/apache/druid/query/CursorGranularizerTest.java
@@ -23,9 +23,11 @@ import com.google.common.collect.ImmutableList;
import org.apache.druid.data.input.ListBasedInputRow;
import org.apache.druid.data.input.impl.DimensionsSpec;
import org.apache.druid.java.util.common.DateTimes;
+import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.java.util.common.granularity.Granularities;
import org.apache.druid.java.util.common.guava.Sequence;
import org.apache.druid.java.util.common.guava.Sequences;
+import org.apache.druid.query.filter.EqualityFilter;
import org.apache.druid.segment.ColumnSelectorFactory;
import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.Cursor;
@@ -65,8 +67,11 @@ public class CursorGranularizerTest extends
InitializedNullHandlingTest
@Before
public void setup() throws IOException
{
- final RowSignature signature = RowSignature.builder().add("x",
ColumnType.STRING).build();
- final List<String> dims = ImmutableList.of("x");
+ final RowSignature signature = RowSignature.builder()
+ .add("x", ColumnType.STRING)
+ .add("y", ColumnType.STRING)
+ .build();
+ final List<String> dims = ImmutableList.of("x", "y");
final IncrementalIndexSchema schema =
IncrementalIndexSchema.builder()
.withDimensionsSpec(DimensionsSpec.builder().useSchemaDiscovery(true).build())
@@ -81,79 +86,79 @@ public class CursorGranularizerTest extends
InitializedNullHandlingTest
signature,
DateTimes.of("2024-01-01T00:00Z"),
dims,
- ImmutableList.of("a")
+ ImmutableList.of("a", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T00:01Z"),
dims,
- ImmutableList.of("b")
+ ImmutableList.of("b", "2")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T00:02Z"),
dims,
- ImmutableList.of("c")
+ ImmutableList.of("c", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T00:03Z"),
dims,
- ImmutableList.of("d")
+ ImmutableList.of("d", "2")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T01:00Z"),
dims,
- ImmutableList.of("e")
+ ImmutableList.of("e", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T01:01Z"),
dims,
- ImmutableList.of("f")
+ ImmutableList.of("f", "2")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T03:04Z"),
dims,
- ImmutableList.of("g")
+ ImmutableList.of("g", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T03:05Z"),
dims,
- ImmutableList.of("h")
+ ImmutableList.of("h", "2")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T03:15Z"),
dims,
- ImmutableList.of("i")
+ ImmutableList.of("i", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T05:03Z"),
dims,
- ImmutableList.of("j")
+ ImmutableList.of("j", "2")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T06:00Z"),
dims,
- ImmutableList.of("k")
+ ImmutableList.of("k", "1")
),
new ListBasedInputRow(
signature,
DateTimes.of("2024-01-01T09:01Z"),
dims,
- ImmutableList.of("l")
+ ImmutableList.of("l", "2")
)
)
)
.tmpDir(temporaryFolder.newFolder());
- final QueryableIndex index = bob.buildMMappedIndex();
+ final QueryableIndex index =
bob.buildMMappedIndex(Intervals.of("2024-01-01T00:00Z/2024-01-02T00:00Z"));
interval = index.getDataInterval();
cursorFactory = new QueryableIndexCursorFactory(index);
timeBoundaryInspector = QueryableIndexTimeBoundaryInspector.create(index);
@@ -261,4 +266,102 @@ public class CursorGranularizerTest extends
InitializedNullHandlingTest
);
}
}
+
+ @Test
+ public void testGranularizeFiltered()
+ {
+ final CursorBuildSpec filtered = CursorBuildSpec.builder()
+ .setFilter(new
EqualityFilter("y", ColumnType.STRING, "1", null))
+ .build();
+ try (CursorHolder cursorHolder = cursorFactory.makeCursorHolder(filtered))
{
+ final Cursor cursor = cursorHolder.asCursor();
+ CursorGranularizer granularizer = CursorGranularizer.create(
+ cursor,
+ timeBoundaryInspector,
+ Order.ASCENDING,
+ Granularities.HOUR,
+ interval
+ );
+
+ final ColumnSelectorFactory selectorFactory =
cursor.getColumnSelectorFactory();
+ final ColumnValueSelector xSelector =
selectorFactory.makeColumnValueSelector("x");
+ final Sequence<List<String>> theSequence =
+ Sequences.simple(granularizer.getBucketIterable())
+ .map(bucketInterval -> {
+ List<String> bucket = new ArrayList<>();
+ if (!granularizer.advanceToBucket(bucketInterval)) {
+ return bucket;
+ }
+ while (!cursor.isDone()) {
+ bucket.add((String) xSelector.getObject());
+ if (!granularizer.advanceCursorWithinBucket()) {
+ break;
+ }
+ }
+ return bucket;
+ });
+
+ List<List<String>> granularized = theSequence.toList();
+ Assert.assertEquals(
+ ImmutableList.of(
+ ImmutableList.of("a", "c"),
+ ImmutableList.of("e"),
+ ImmutableList.of(),
+ ImmutableList.of("g", "i"),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of("k"),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of()
+ ),
+ granularized
+ );
+ }
+ }
+
+ @Test
+ public void testGranularizeFilteredClippedAndPartialOverlap()
+ {
+ final CursorBuildSpec filtered = CursorBuildSpec.builder()
+ .setFilter(new
EqualityFilter("y", ColumnType.STRING, "1", null))
+ .build();
+ try (CursorHolder cursorHolder = cursorFactory.makeCursorHolder(filtered))
{
+ final Cursor cursor = cursorHolder.asCursor();
+ CursorGranularizer granularizer = CursorGranularizer.create(
+ cursor,
+ timeBoundaryInspector,
+ Order.ASCENDING,
+ Granularities.HOUR,
+ Intervals.of("2024-01-01T08:00Z/2024-01-03T00:00Z")
+ );
+
+ final ColumnSelectorFactory selectorFactory =
cursor.getColumnSelectorFactory();
+ final ColumnValueSelector xSelector =
selectorFactory.makeColumnValueSelector("x");
+ final Sequence<List<String>> theSequence =
+ Sequences.simple(granularizer.getBucketIterable())
+ .map(bucketInterval -> {
+ List<String> bucket = new ArrayList<>();
+ if (!granularizer.advanceToBucket(bucketInterval)) {
+ return bucket;
+ }
+ while (!cursor.isDone()) {
+ bucket.add((String) xSelector.getObject());
+ if (!granularizer.advanceCursorWithinBucket()) {
+ break;
+ }
+ }
+ return bucket;
+ });
+
+ List<List<String>> granularized = theSequence.toList();
+ Assert.assertEquals(
+ ImmutableList.of(
+ ImmutableList.of(),
+ ImmutableList.of()
+ ),
+ granularized
+ );
+ }
+ }
}
diff --git
a/processing/src/test/java/org/apache/druid/segment/IndexBuilder.java
b/processing/src/test/java/org/apache/druid/segment/IndexBuilder.java
index 9c88ab0dc8f..986266015d3 100644
--- a/processing/src/test/java/org/apache/druid/segment/IndexBuilder.java
+++ b/processing/src/test/java/org/apache/druid/segment/IndexBuilder.java
@@ -46,6 +46,7 @@ import org.apache.druid.segment.transform.TransformSpec;
import
org.apache.druid.segment.writeout.OffHeapMemorySegmentWriteOutMediumFactory;
import org.apache.druid.segment.writeout.SegmentWriteOutMediumFactory;
import org.apache.druid.timeline.SegmentId;
+import org.joda.time.Interval;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -235,6 +236,11 @@ public class IndexBuilder
}
public File buildMMappedIndexFile()
+ {
+ return buildMMappedIndexFile(null);
+ }
+
+ public File buildMMappedIndexFile(@Nullable Interval dataInterval)
{
Preconditions.checkNotNull(indexMerger, "indexMerger");
Preconditions.checkNotNull(tmpDir, "tmpDir");
@@ -244,6 +250,7 @@ public class IndexBuilder
indexIO.loadIndex(
indexMerger.persist(
incrementalIndex,
+ dataInterval == null ? incrementalIndex.getInterval() :
dataInterval,
new File(
tmpDir,
StringUtils.format("testIndex-%s",
ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE))
@@ -276,7 +283,17 @@ public class IndexBuilder
public QueryableIndex buildMMappedIndex()
{
try {
- return indexIO.loadIndex(buildMMappedIndexFile());
+ return indexIO.loadIndex(buildMMappedIndexFile(null));
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public QueryableIndex buildMMappedIndex(Interval dataInterval)
+ {
+ try {
+ return indexIO.loadIndex(buildMMappedIndexFile(dataInterval));
}
catch (IOException e) {
throw new RuntimeException(e);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]