Skip to content

Commit 572349d

Browse files
committed
Initial CSV test working
1 parent b78acc2 commit 572349d

File tree

28 files changed

+667
-13
lines changed

28 files changed

+667
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ server/src/main/resources/transport/definitions/manifest.txt
7676

7777
# JEnv
7878
.java-version
79+
.aider*

.idea/runConfigurations/Debug_Elasticsearch__node_2_.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/src/main/java/org/elasticsearch/index/mapper/BlockLoader.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,8 @@ interface BlockFactory {
483483
SortedSetOrdinalsBuilder sortedSetOrdinalsBuilder(SortedSetDocValues ordinals, int count);
484484

485485
AggregateMetricDoubleBuilder aggregateMetricDoubleBuilder(int count);
486+
487+
DateRangeBuilder dateRangeBuilder(int count);
486488
}
487489

488490
/**
@@ -603,4 +605,10 @@ interface AggregateMetricDoubleBuilder extends Builder {
603605

604606
IntBuilder count();
605607
}
608+
609+
interface DateRangeBuilder extends Builder {
610+
LongBuilder from();
611+
612+
LongBuilder to();
613+
}
606614
}

server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
package org.elasticsearch.index.mapper;
1111

12+
import org.apache.lucene.index.BinaryDocValues;
13+
import org.apache.lucene.index.LeafReaderContext;
1214
import org.apache.lucene.search.Query;
1315
import org.apache.lucene.search.SortField;
1416
import org.apache.lucene.util.BytesRef;
@@ -349,6 +351,98 @@ public Query rangeQuery(
349351
context
350352
);
351353
}
354+
355+
public static class DateRangeDocValuesLoader extends BlockDocValuesReader.DocValuesBlockLoader {
356+
private final String fieldName;
357+
358+
public DateRangeDocValuesLoader(String fieldName) {
359+
this.fieldName = fieldName;
360+
}
361+
362+
@Override
363+
public Builder builder(BlockFactory factory, int expectedCount) {
364+
return factory.longsFromDocValues(expectedCount);
365+
}
366+
367+
@Override
368+
public AllReader reader(LeafReaderContext context) throws IOException {
369+
var docValues = context.reader().getBinaryDocValues(fieldName);
370+
return new DateRangeDocValuesReader(docValues);
371+
/*
372+
if (docValues != null) {
373+
NumericDocValues singleton = DocValues.unwrapSingleton(docValues);
374+
if (singleton != null) {
375+
return new BlockDocValuesReader.SingletonLongs(singleton);
376+
}
377+
return new BlockDocValuesReader.Longs(docValues);
378+
}
379+
NumericDocValues singleton = context.reader().getNumericDocValues(fieldName);
380+
if (singleton != null) {
381+
return new BlockDocValuesReader.SingletonLongs(singleton);
382+
}
383+
return new ConstantNullsReader(); */
384+
}
385+
}
386+
387+
@Override
388+
public BlockLoader blockLoader(BlockLoaderContext blContext) {
389+
if (hasDocValues()) {
390+
return new DateRangeDocValuesLoader(name());
391+
}
392+
throw new IllegalStateException("Cannot load blocks without doc values");
393+
}
394+
}
395+
396+
public static class DateRangeDocValuesReader extends BlockDocValuesReader {
397+
private final BytesRef spare = new BytesRef();
398+
399+
private final BinaryDocValues numericDocValues;
400+
401+
public DateRangeDocValuesReader(BinaryDocValues numericDocValues) {
402+
this.numericDocValues = numericDocValues;
403+
}
404+
405+
@Override
406+
protected int docId() {
407+
return 0;
408+
}
409+
410+
@Override
411+
public String toString() {
412+
return "";
413+
}
414+
415+
@Override
416+
public BlockLoader.Block read(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset, boolean nullsFiltered)
417+
throws IOException {
418+
try (BlockLoader.DateRangeBuilder builder = factory.dateRangeBuilder(docs.count() - offset)) {
419+
for (int i = offset; i < docs.count(); i++) {
420+
int doc = docs.get(i);
421+
read(doc, builder);
422+
}
423+
return builder.build();
424+
}
425+
}
426+
427+
@Override
428+
public void read(int docId, BlockLoader.StoredFields storedFields, BlockLoader.Builder builder) throws IOException {
429+
read(docId, (BlockLoader.DateRangeBuilder) builder);
430+
}
431+
432+
private void read(int doc, BlockLoader.DateRangeBuilder builder) throws IOException {
433+
// WRONG?
434+
if (false == numericDocValues.advanceExact(doc)) {
435+
builder.appendNull();
436+
return;
437+
}
438+
439+
BytesRef ref = numericDocValues.binaryValue();
440+
var ranges = BinaryRangeUtil.decodeLongRanges(ref);
441+
for (var range : ranges) {
442+
builder.from().appendLong((long) range.getFrom());
443+
builder.to().appendLong((long) range.to);
444+
}
445+
}
352446
}
353447

354448
private final RangeType type;
@@ -420,10 +514,14 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
420514

421515
private Range parseRange(XContentParser parser) throws IOException {
422516
final XContentParser.Token start = parser.currentToken();
423-
if (fieldType().rangeType == RangeType.IP && start == XContentParser.Token.VALUE_STRING) {
424-
return parseIpRangeFromCidr(parser);
425-
}
517+
return (start != XContentParser.Token.VALUE_STRING) ? parseGeneralRange(parser, start) : switch (fieldType().rangeType) {
518+
case RangeType.IP -> parseIpRangeFromCidr(parser);
519+
case RangeType.DATE -> parseDateRange(parser.text());
520+
default -> parseGeneralRange(parser, start);
521+
};
522+
}
426523

524+
private Range parseGeneralRange(XContentParser parser, XContentParser.Token start) throws IOException {
427525
if (start != XContentParser.Token.START_OBJECT) {
428526
throw new DocumentParsingException(
429527
parser.getTokenLocation(),
@@ -483,6 +581,14 @@ private static Range parseIpRangeFromCidr(final XContentParser parser) throws IO
483581
return new Range(RangeType.IP, range.lowerBound(), range.upperBound(), true, true);
484582
}
485583

584+
private static Range parseDateRange(String s) throws IOException {
585+
var nums = s.split("-");
586+
assert nums.length == 2 : "Expected two numbers in the date range string: " + s;
587+
var from = Long.parseLong(nums[0].trim());
588+
var to = Long.parseLong(nums[1].trim());
589+
return new Range(RangeType.DATE, from, to, true, false);
590+
}
591+
486592
@Override
487593
protected SyntheticSourceSupport syntheticSourceSupport() {
488594
if (hasDocValues) {

test/framework/src/main/java/org/elasticsearch/index/mapper/TestBlock.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,15 @@ public SortedSetOrdinalBuilder appendOrd(int value) {
372372
return new SortedSetOrdinalBuilder();
373373
}
374374

375+
@Override
375376
public BlockLoader.AggregateMetricDoubleBuilder aggregateMetricDoubleBuilder(int expectedSize) {
376377
return new AggregateMetricDoubleBlockBuilder(expectedSize);
377378
}
379+
380+
@Override
381+
public BlockLoader.DateRangeBuilder dateRangeBuilder(int expectedSize) {
382+
return new DateRangeBuilder(expectedSize);
383+
}
378384
};
379385
}
380386

@@ -582,4 +588,61 @@ public void close() {
582588

583589
}
584590
}
591+
592+
public static class DateRangeBuilder implements BlockLoader.DateRangeBuilder {
593+
private final LongBuilder from;
594+
private final LongBuilder to;
595+
596+
DateRangeBuilder(int expectedSize) {
597+
from = new LongBuilder(expectedSize);
598+
to = new LongBuilder(expectedSize);
599+
}
600+
601+
@Override
602+
public BlockLoader.LongBuilder from() {
603+
return null;
604+
}
605+
606+
@Override
607+
public BlockLoader.LongBuilder to() {
608+
return null;
609+
}
610+
611+
@Override
612+
public BlockLoader.Block build() {
613+
return null;
614+
}
615+
616+
@Override
617+
public BlockLoader.Builder appendNull() {
618+
return null;
619+
}
620+
621+
@Override
622+
public BlockLoader.Builder beginPositionEntry() {
623+
return null;
624+
}
625+
626+
@Override
627+
public BlockLoader.Builder endPositionEntry() {
628+
return null;
629+
}
630+
631+
@Override
632+
public void close() {
633+
634+
}
635+
636+
private static class LongBuilder extends TestBlock.Builder implements BlockLoader.LongBuilder {
637+
private LongBuilder(int expectedSize) {
638+
super(expectedSize);
639+
}
640+
641+
@Override
642+
public BlockLoader.LongBuilder appendLong(long value) {
643+
add(value);
644+
return null;
645+
}
646+
}
647+
};
585648
}

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/plugin/EsqlCorePlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ public class EsqlCorePlugin extends Plugin implements ExtensiblePlugin {
1515

1616
public static final FeatureFlag AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG = new FeatureFlag("esql_aggregate_metric_double");
1717
public static final FeatureFlag DENSE_VECTOR_FEATURE_FLAG = new FeatureFlag("esql_dense_vector");
18+
public static final FeatureFlag DATE_RANGE_FEATURE_FLAG = new FeatureFlag("esql_date_range");
1819
}

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,13 @@ public enum DataType {
310310
/**
311311
* Fields with this type are dense vectors, represented as an array of double values.
312312
*/
313-
DENSE_VECTOR(builder().esType("dense_vector").unknownSize());
313+
DENSE_VECTOR(builder().esType("dense_vector").unknownSize()),
314+
315+
/**
316+
* Fields with this type are used to represent a range of dates.
317+
* This is an under-construction type, and is not yet fully supported.
318+
*/
319+
DATE_RANGE(builder().esType("date_range").typeName("DATE_RANGE").estimatedSize(2 * Long.BYTES));
314320

315321
/**
316322
* Types that are actively being built. These types are
@@ -331,7 +337,8 @@ public enum DataType {
331337
*/
332338
public static final Map<DataType, FeatureFlag> UNDER_CONSTRUCTION = Map.ofEntries(
333339
Map.entry(AGGREGATE_METRIC_DOUBLE, EsqlCorePlugin.AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG),
334-
Map.entry(DENSE_VECTOR, EsqlCorePlugin.DENSE_VECTOR_FEATURE_FLAG)
340+
Map.entry(DENSE_VECTOR, EsqlCorePlugin.DENSE_VECTOR_FEATURE_FLAG),
341+
Map.entry(DATE_RANGE, EsqlCorePlugin.DATE_RANGE_FEATURE_FLAG)
335342
);
336343

337344
private final String typeName;

x-pack/plugin/esql/compute/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
requires org.elasticsearch.geo;
2222
requires org.elasticsearch.xcore;
2323
requires hppc;
24+
requires com.ibm.icu;
2425

2526
exports org.elasticsearch.compute;
2627
exports org.elasticsearch.compute.aggregation;

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ public final AggregateMetricDoubleBlock newAggregateMetricDoubleBlock(
481481
return new AggregateMetricDoubleArrayBlock(min, max, sum, count);
482482
}
483483

484+
public DateRangeBlockBuilder newDateRangeBlockBuilder(int estimatedSize) {
485+
return new DateRangeBlockBuilder(estimatedSize, this);
486+
}
487+
484488
/**
485489
* Returns the maximum number of bytes that a Block should be backed by a primitive array before switching to using BigArrays.
486490
*/

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockUtils.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ yield new AggregateMetricDoubleLiteral(
299299
aggBlock.countBlock().getInt(offset)
300300
);
301301
}
302+
case DATE_RANGE -> {
303+
DateRangeBlock b = (DateRangeBlock) block;
304+
LongBlock fromBlock = b.getFromBlock();
305+
LongBlock toBlock = b.getToBlock();
306+
yield new DateRangeBlockBuilder.DateRangeLiteral(fromBlock.getLong(offset), toBlock.getLong(offset));
307+
}
302308
case UNKNOWN -> throw new IllegalArgumentException("can't read values from [" + block + "]");
303309
};
304310
}

0 commit comments

Comments
 (0)