Skip to content

Commit da95df1

Browse files
authored
Fix BlockHash DirectEncoder (#108283) (#108329)
The DirectEncoder currently returns the incorrect value for the positionCount() method, which should be the number of positions ready in the current batch. We need to keep track of whether a position is loaded via encodeNextBatch() and consumed via the read() method. However, we can always return 1 for positionCount(), indicating that one position is already loaded. Our tests failed to catch this because mv_ordering wasn't enabled when generating test blocks, effectively disabling the DirectEncoders. Closes #108268
1 parent a928c58 commit da95df1

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

docs/changelog/108283.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 108283
2+
summary: Fix `BlockHash` `DirectEncoder`
3+
area: ES|QL
4+
type: bug
5+
issues:
6+
- 108268

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/BatchEncoder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,13 @@ public final void encodeNextBatch() {
274274

275275
@Override
276276
public final int positionCount() {
277-
return Math.max(valueCount, 1);
277+
return 1; // always has one position already loaded
278278
}
279279

280280
@Override
281281
public final int valueCount(int positionOffset) {
282282
assert positionOffset == 0 : positionOffset;
283-
return positionCount();
283+
return Math.max(valueCount, 1);
284284
}
285285

286286
@Override

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BasicBlockTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@ public static RandomBlock randomBlock(
895895
int maxDupsPerPosition
896896
) {
897897
List<List<Object>> values = new ArrayList<>();
898+
Block.MvOrdering mvOrdering = Block.MvOrdering.DEDUPLICATED_AND_SORTED_ASCENDING;
898899
try (var builder = elementType.newBlockBuilder(positionCount, blockFactory)) {
899900
boolean bytesRefFromPoints = randomBoolean();
900901
Supplier<Point> pointSupplier = randomBoolean() ? GeometryTestUtils::randomPoint : ShapeTestUtils::randomPoint;
@@ -955,6 +956,19 @@ public static RandomBlock randomBlock(
955956
if (valueCount != 1 || dupCount != 0) {
956957
builder.endPositionEntry();
957958
}
959+
if (dupCount > 0) {
960+
mvOrdering = Block.MvOrdering.UNORDERED;
961+
} else if (mvOrdering != Block.MvOrdering.UNORDERED) {
962+
List<Object> dedupedAndSortedList = valuesAtPosition.stream().sorted().distinct().toList();
963+
if (dedupedAndSortedList.size() != valuesAtPosition.size()) {
964+
mvOrdering = Block.MvOrdering.UNORDERED;
965+
} else if (dedupedAndSortedList.equals(valuesAtPosition) == false) {
966+
mvOrdering = Block.MvOrdering.DEDUPLICATED_UNORDERD;
967+
}
968+
}
969+
}
970+
if (randomBoolean()) {
971+
builder.mvOrdering(mvOrdering);
958972
}
959973
return new RandomBlock(values, builder.build());
960974
}

0 commit comments

Comments
 (0)