Skip to content

Commit 74324c5

Browse files
committed
Read dimension fields
1 parent f7a7f0b commit 74324c5

File tree

5 files changed

+83
-16
lines changed

5 files changed

+83
-16
lines changed

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/ShardContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,10 @@ public interface ShardContext {
5353
* Returns something to load values from this field into a {@link Block}.
5454
*/
5555
BlockLoader blockLoader(String name, boolean asUnsupportedSource, MappedFieldType.FieldExtractPreference fieldExtractPreference);
56+
57+
/**
58+
* Returns the {@link MappedFieldType} for the given field name.
59+
* By default, this delegate to {@link org.elasticsearch.index.query.SearchExecutionContext#getFieldType(String)}
60+
*/
61+
MappedFieldType fieldType(String name);
5662
}

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/TimeSeriesSourceOperator.java

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,12 @@ public Page getCheckedOutput() throws IOException {
133133
if (docCollector != null) {
134134
blocks[blockIndex++] = docCollector.build().asBlock();
135135
}
136-
blocks[blockIndex++] = tsHashesBuilder.build().asBlock();
136+
OrdinalBytesRefVector tsidVector = tsHashesBuilder.build();
137+
blocks[blockIndex++] = tsidVector.asBlock();
137138
tsHashesBuilder = new TsidBuilder(blockFactory, Math.min(remainingDocs, maxPageSize));
138139
blocks[blockIndex++] = timestampsBuilder.build().asBlock();
139140
timestampsBuilder = blockFactory.newLongVectorBuilder(Math.min(remainingDocs, maxPageSize));
140-
System.arraycopy(fieldsReader.buildBlocks(), 0, blocks, blockIndex, fieldsToExtracts.size());
141+
System.arraycopy(fieldsReader.buildBlocks(tsidVector.getOrdinalsVector()), 0, blocks, blockIndex, fieldsToExtracts.size());
141142
page = new Page(currentPagePos, blocks);
142143
currentPagePos = 0;
143144
}
@@ -217,6 +218,7 @@ void readDocsForNextPage() throws IOException {
217218
}
218219

219220
private boolean readValuesForOneTsid(PriorityQueue<LeafIterator> sub) throws IOException {
221+
boolean first = true;
220222
do {
221223
LeafIterator top = sub.top();
222224
currentPagePos++;
@@ -226,7 +228,8 @@ private boolean readValuesForOneTsid(PriorityQueue<LeafIterator> sub) throws IOE
226228
}
227229
tsHashesBuilder.appendOrdinal();
228230
timestampsBuilder.appendLong(top.timestamp);
229-
fieldsReader.readValues(top.segmentOrd, top.docID);
231+
fieldsReader.readValues(top.segmentOrd, top.docID, first);
232+
first = false;
230233
if (top.nextDoc()) {
231234
sub.updateTop();
232235
} else if (top.docID == DocIdSetIterator.NO_MORE_DOCS) {
@@ -350,6 +353,7 @@ static final class ShardLevelFieldsReader implements Releasable {
350353
private final BlockLoaderFactory blockFactory;
351354
private final SegmentLevelFieldsReader[] segments;
352355
private final BlockLoader[] loaders;
356+
private final boolean[] dimensions;
353357
private final Block.Builder[] builders;
354358
private final StoredFieldsSpec storedFieldsSpec;
355359
private final SourceLoader sourceLoader;
@@ -377,10 +381,14 @@ static final class ShardLevelFieldsReader implements Releasable {
377381
sourceLoader = null;
378382
}
379383
this.storedFieldsSpec = storedFieldsSpec;
384+
this.dimensions = new boolean[fields.size()];
385+
for (int i = 0; i < fields.size(); i++) {
386+
dimensions[i] = shardContext.fieldType(fields.get(i).name()).isDimension();
387+
}
380388
}
381389

382-
void readValues(int segment, int docID) throws IOException {
383-
segments[segment].read(docID, builders);
390+
void readValues(int segment, int docID, boolean first) throws IOException {
391+
segments[segment].read(docID, builders, first, dimensions);
384392
}
385393

386394
void prepareForReading(int estimatedSize) throws IOException {
@@ -396,9 +404,38 @@ void prepareForReading(int estimatedSize) throws IOException {
396404
}
397405
}
398406

399-
Block[] buildBlocks() {
400-
Block[] blocks = Block.Builder.buildAll(builders);
401-
Arrays.fill(builders, null);
407+
Block[] buildBlocks(IntVector tsidOrdinals) {
408+
final Block[] blocks = new Block[loaders.length];
409+
try {
410+
for (int i = 0; i < builders.length; i++) {
411+
Block values = builders[i].build();
412+
if (dimensions[i]) {
413+
try (values) {
414+
if (values.asVector() instanceof BytesRefVector bytes) {
415+
tsidOrdinals.incRef();
416+
values.incRef();
417+
blocks[i] = new OrdinalBytesRefVector(tsidOrdinals, bytes).asBlock();
418+
} else {
419+
final int positionCount = tsidOrdinals.getPositionCount();
420+
try (var newBuilder = values.elementType().newBlockBuilder(positionCount, blockFactory.factory)) {
421+
for (int p = 0; p < positionCount; p++) {
422+
int pos = tsidOrdinals.getInt(p);
423+
newBuilder.copyFrom(values, pos, pos + 1);
424+
}
425+
blocks[i] = newBuilder.build();
426+
}
427+
}
428+
}
429+
} else {
430+
blocks[i] = values;
431+
}
432+
}
433+
Arrays.fill(builders, null);
434+
} finally {
435+
if (blocks.length > 0 && blocks[blocks.length - 1] == null) {
436+
Releasables.close(blocks);
437+
}
438+
}
402439
return blocks;
403440
}
404441

@@ -435,10 +472,18 @@ private void reinitializeIfNeeded(SourceLoader sourceLoader, StoredFieldsSpec st
435472
}
436473
}
437474

438-
void read(int docId, Block.Builder[] builder) throws IOException {
475+
void read(int docId, Block.Builder[] builder, boolean first, boolean[] dimensions) throws IOException {
439476
storedFields.advanceTo(docId);
440-
for (int i = 0; i < rowStride.length; i++) {
441-
rowStride[i].read(docId, storedFields, builder[i]);
477+
if (first) {
478+
for (int i = 0; i < rowStride.length; i++) {
479+
rowStride[i].read(docId, storedFields, builder[i]);
480+
}
481+
} else {
482+
for (int i = 0; i < rowStride.length; i++) {
483+
if (dimensions[i] == false) {
484+
rowStride[i].read(docId, storedFields, builder[i]);
485+
}
486+
}
442487
}
443488
}
444489
}
@@ -480,9 +525,9 @@ public void close() {
480525
Releasables.close(dictBuilder, ordinalsBuilder);
481526
}
482527

483-
BytesRefVector build() throws IOException {
528+
OrdinalBytesRefVector build() throws IOException {
484529
BytesRefVector dict = null;
485-
BytesRefVector result = null;
530+
OrdinalBytesRefVector result = null;
486531
IntVector ordinals = null;
487532
try {
488533
dict = dictBuilder.build();

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/LuceneSourceOperatorTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,5 +324,10 @@ public Optional<SortAndFormats> buildSort(List<SortBuilder<?>> sorts) {
324324
public String shardIdentifier() {
325325
return "test";
326326
}
327+
328+
@Override
329+
public MappedFieldType fieldType(String name) {
330+
throw new UnsupportedOperationException();
331+
}
327332
}
328333
}

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/lucene/TimeSeriesSourceOperatorTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,17 @@ public static TimeSeriesSourceOperatorFactory createTimeSeriesSourceOperator(
438438
} catch (IOException e) {
439439
throw new UncheckedIOException(e);
440440
}
441-
var ctx = new LuceneSourceOperatorTests.MockShardContext(reader, 0);
441+
var ctx = new LuceneSourceOperatorTests.MockShardContext(reader, 0) {
442+
@Override
443+
public MappedFieldType fieldType(String name) {
444+
for (ExtractField e : extractFields) {
445+
if (e.ft.name().equals(name)) {
446+
return e.ft;
447+
}
448+
}
449+
throw new IllegalArgumentException("Unknown field [" + name + "]");
450+
}
451+
};
442452
Function<ShardContext, Query> queryFunction = c -> new MatchAllDocsQuery();
443453

444454
var fieldInfos = extractFields.stream()

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private static class DefaultShardContextForUnmappedField extends DefaultShardCon
177177
}
178178

179179
@Override
180-
protected @Nullable MappedFieldType fieldType(String name) {
180+
public @Nullable MappedFieldType fieldType(String name) {
181181
var superResult = super.fieldType(name);
182182
return superResult == null && name.equals(unmappedEsField.getName())
183183
? new KeywordFieldMapper.KeywordFieldType(name, false /* isIndexed */, false /* hasDocValues */, Map.of() /* meta */)
@@ -459,7 +459,8 @@ public FieldNamesFieldMapper.FieldNamesFieldType fieldNames() {
459459
return loader;
460460
}
461461

462-
protected @Nullable MappedFieldType fieldType(String name) {
462+
@Override
463+
public @Nullable MappedFieldType fieldType(String name) {
463464
return ctx.getFieldType(name);
464465
}
465466

0 commit comments

Comments
 (0)