Skip to content

Commit f9263c8

Browse files
lktselasticsearchmachine
andauthored
[8.x] Use FallbackSyntheticSourceBlockLoader for shape and geo_shape (#124927) (#125164)
* Use FallbackSyntheticSourceBlockLoader for shape and geo_shape (#124927) (cherry picked from commit 033d28e) # Conflicts: # server/src/test/java/org/elasticsearch/index/mapper/blockloader/BooleanFieldBlockLoaderTests.java # server/src/test/java/org/elasticsearch/index/mapper/blockloader/DateFieldBlockLoaderTests.java # server/src/test/java/org/elasticsearch/index/mapper/blockloader/KeywordFieldBlockLoaderTests.java # test/framework/src/main/java/org/elasticsearch/index/mapper/BlockLoaderTestCase.java # test/framework/src/main/java/org/elasticsearch/index/mapper/NumberFieldBlockLoaderTestCase.java * fix merge * fix * fix more * fix more * properly sync BlockLoaderTestCase * iter * iter * [CI] Auto commit changes from spotless * f * f --------- Co-authored-by: elasticsearchmachine <[email protected]>
1 parent 056ec71 commit f9263c8

File tree

68 files changed

+1017
-135
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1017
-135
lines changed

docs/changelog/124927.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 124927
2+
summary: Use `FallbackSyntheticSourceBlockLoader` for `shape` and `geo_shape`
3+
area: Mapping
4+
type: enhancement
5+
issues: []

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ public Builder builder(BlockFactory factory, int expectedCount) {
342342
private FallbackSyntheticSourceBlockLoader.Reader<?> fallbackSyntheticSourceBlockLoaderReader() {
343343
var nullValueAdjusted = nullValue != null ? adjustSourceValue(nullValue, scalingFactor) : null;
344344

345-
return new FallbackSyntheticSourceBlockLoader.ReaderWithNullValueSupport<Double>(nullValue) {
345+
return new FallbackSyntheticSourceBlockLoader.SingleValueReader<Double>(nullValue) {
346346
@Override
347347
public void convertValue(Object value, List<Double> accumulator) {
348348
if (coerce && value.equals("")) {

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldBlockLoaderTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import java.util.Map;
1919

2020
public class ScaledFloatFieldBlockLoaderTests extends NumberFieldBlockLoaderTestCase<Double> {
21-
public ScaledFloatFieldBlockLoaderTests() {
22-
super(FieldType.SCALED_FLOAT);
21+
public ScaledFloatFieldBlockLoaderTests(Params params) {
22+
super(FieldType.SCALED_FLOAT, params);
2323
}
2424

2525
@Override

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

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package org.elasticsearch.index.mapper;
1010

1111
import org.apache.lucene.search.Query;
12+
import org.apache.lucene.util.BytesRef;
1213
import org.elasticsearch.common.CheckedBiConsumer;
1314
import org.elasticsearch.common.Explicit;
1415
import org.elasticsearch.common.geo.GeometryFormatterFactory;
@@ -67,12 +68,16 @@ public abstract void parse(XContentParser parser, CheckedConsumer<T, IOException
6768

6869
private void fetchFromSource(Object sourceMap, Consumer<T> consumer) {
6970
try (XContentParser parser = wrapObject(sourceMap)) {
70-
parse(parser, v -> consumer.accept(normalizeFromSource(v)), NoopMalformedValueHandler.INSTANCE);
71+
parseFromSource(parser, consumer);
7172
} catch (IOException e) {
7273
throw new UncheckedIOException(e);
7374
}
7475
}
7576

77+
private void parseFromSource(XContentParser parser, Consumer<T> consumer) throws IOException {
78+
parse(parser, v -> consumer.accept(normalizeFromSource(v)), NoopMalformedValueHandler.INSTANCE);
79+
}
80+
7681
/**
7782
* Normalize a geometry when reading from source. When reading from source we can skip
7883
* some expensive steps as the geometry has already been indexed.
@@ -187,6 +192,80 @@ protected BlockLoader blockLoaderFromSource(BlockLoaderContext blContext) {
187192
}
188193

189194
protected abstract Object nullValueAsSource(T nullValue);
195+
196+
protected BlockLoader blockLoaderFromFallbackSyntheticSource(BlockLoaderContext blContext) {
197+
return new FallbackSyntheticSourceBlockLoader(new GeometriesFallbackSyntheticSourceReader(), name()) {
198+
@Override
199+
public Builder builder(BlockFactory factory, int expectedCount) {
200+
return factory.bytesRefs(expectedCount);
201+
}
202+
};
203+
}
204+
205+
private class GeometriesFallbackSyntheticSourceReader implements FallbackSyntheticSourceBlockLoader.Reader<BytesRef> {
206+
private final Function<List<T>, List<Object>> formatter;
207+
208+
private GeometriesFallbackSyntheticSourceReader() {
209+
this.formatter = getFormatter(GeometryFormatterFactory.WKB);
210+
}
211+
212+
@Override
213+
public void convertValue(Object value, List<BytesRef> accumulator) {
214+
final List<T> values = new ArrayList<>();
215+
216+
geometryParser.fetchFromSource(value, v -> {
217+
if (v != null) {
218+
values.add(v);
219+
} else if (nullValue != null) {
220+
values.add(nullValue);
221+
}
222+
});
223+
var formatted = formatter.apply(values);
224+
225+
for (var formattedValue : formatted) {
226+
if (formattedValue instanceof byte[] wkb) {
227+
accumulator.add(new BytesRef(wkb));
228+
} else {
229+
throw new IllegalArgumentException(
230+
"Unsupported source type for spatial geometry: " + formattedValue.getClass().getSimpleName()
231+
);
232+
}
233+
}
234+
}
235+
236+
@Override
237+
public void parse(XContentParser parser, List<BytesRef> accumulator) throws IOException {
238+
final List<T> values = new ArrayList<>();
239+
240+
geometryParser.parseFromSource(parser, v -> {
241+
if (v != null) {
242+
values.add(v);
243+
} else if (nullValue != null) {
244+
values.add(nullValue);
245+
}
246+
});
247+
var formatted = formatter.apply(values);
248+
249+
for (var formattedValue : formatted) {
250+
if (formattedValue instanceof byte[] wkb) {
251+
accumulator.add(new BytesRef(wkb));
252+
} else {
253+
throw new IllegalArgumentException(
254+
"Unsupported source type for spatial geometry: " + formattedValue.getClass().getSimpleName()
255+
);
256+
}
257+
}
258+
}
259+
260+
@Override
261+
public void writeToBlock(List<BytesRef> values, BlockLoader.Builder blockBuilder) {
262+
var bytesRefBuilder = (BlockLoader.BytesRefBuilder) blockBuilder;
263+
264+
for (var value : values) {
265+
bytesRefBuilder.appendBytesRef(value);
266+
}
267+
}
268+
}
190269
}
191270

192271
private final Explicit<Boolean> ignoreMalformed;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ public Builder builder(BlockFactory factory, int expectedCount) {
337337
}
338338

339339
private FallbackSyntheticSourceBlockLoader.Reader<?> fallbackSyntheticSourceBlockLoaderReader() {
340-
return new FallbackSyntheticSourceBlockLoader.ReaderWithNullValueSupport<Boolean>(nullValue) {
340+
return new FallbackSyntheticSourceBlockLoader.SingleValueReader<Boolean>(nullValue) {
341341
@Override
342342
public void convertValue(Object value, List<Boolean> accumulator) {
343343
try {
@@ -366,10 +366,10 @@ protected void parseNonNullValue(XContentParser parser, List<Boolean> accumulato
366366

367367
@Override
368368
public void writeToBlock(List<Boolean> values, BlockLoader.Builder blockBuilder) {
369-
var longBuilder = (BlockLoader.BooleanBuilder) blockBuilder;
369+
var booleanBuilder = (BlockLoader.BooleanBuilder) blockBuilder;
370370

371371
for (var value : values) {
372-
longBuilder.appendBoolean(value);
372+
booleanBuilder.appendBoolean(value);
373373
}
374374
}
375375
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ public Builder builder(BlockFactory factory, int expectedCount) {
871871
private FallbackSyntheticSourceBlockLoader.Reader<?> fallbackSyntheticSourceBlockLoaderReader() {
872872
Function<String, Long> dateParser = this::parse;
873873

874-
return new FallbackSyntheticSourceBlockLoader.ReaderWithNullValueSupport<Long>(nullValue) {
874+
return new FallbackSyntheticSourceBlockLoader.SingleValueReader<Long>(nullValue) {
875875
@Override
876876
public void convertValue(Object value, List<Long> accumulator) {
877877
try {

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,6 @@ private void parseFieldFromParent(IgnoredSourceFieldMapper.NameValue nameValue,
235235
}
236236

237237
private void parseWithReader(XContentParser parser, List<T> blockValues) throws IOException {
238-
if (parser.currentToken() == XContentParser.Token.START_ARRAY) {
239-
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
240-
reader.parse(parser, blockValues);
241-
}
242-
return;
243-
}
244-
245238
reader.parse(parser, blockValues);
246239
}
247240

@@ -274,10 +267,15 @@ public interface Reader<T> {
274267
void writeToBlock(List<T> values, Builder blockBuilder);
275268
}
276269

277-
public abstract static class ReaderWithNullValueSupport<T> implements Reader<T> {
270+
/**
271+
* Reader for field types that don't parse arrays (arrays are always treated as multiple values)
272+
* as opposed to field types that treat arrays as special cases (for example point).
273+
* @param <T>
274+
*/
275+
public abstract static class SingleValueReader<T> implements Reader<T> {
278276
private final Object nullValue;
279277

280-
public ReaderWithNullValueSupport(Object nullValue) {
278+
public SingleValueReader(Object nullValue) {
281279
this.nullValue = nullValue;
282280
}
283281

@@ -289,6 +287,18 @@ public void parse(XContentParser parser, List<T> accumulator) throws IOException
289287
}
290288
return;
291289
}
290+
if (parser.currentToken() == XContentParser.Token.START_ARRAY) {
291+
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
292+
if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
293+
if (nullValue != null) {
294+
convertValue(nullValue, accumulator);
295+
}
296+
} else {
297+
parseNonNullValue(parser, accumulator);
298+
}
299+
}
300+
return;
301+
}
292302

293303
parseNonNullValue(parser, accumulator);
294304
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ public Builder builder(BlockFactory factory, int expectedCount) {
669669

670670
private FallbackSyntheticSourceBlockLoader.Reader<?> fallbackSyntheticSourceBlockLoaderReader() {
671671
var nullValueBytes = nullValue != null ? new BytesRef(nullValue) : null;
672-
return new FallbackSyntheticSourceBlockLoader.ReaderWithNullValueSupport<BytesRef>(nullValueBytes) {
672+
return new FallbackSyntheticSourceBlockLoader.SingleValueReader<BytesRef>(nullValueBytes) {
673673
@Override
674674
public void convertValue(Object value, List<BytesRef> accumulator) {
675675
String stringValue = ((BytesRef) value).utf8ToString();

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,8 +1738,7 @@ public Builder builder(BlockFactory factory, int expectedCount) {
17381738
};
17391739
}
17401740

1741-
abstract static class NumberFallbackSyntheticSourceReader extends FallbackSyntheticSourceBlockLoader.ReaderWithNullValueSupport<
1742-
Number> {
1741+
abstract static class NumberFallbackSyntheticSourceReader extends FallbackSyntheticSourceBlockLoader.SingleValueReader<Number> {
17431742
private final NumberType type;
17441743
private final Number nullValue;
17451744
private final boolean coerce;

server/src/test/java/org/elasticsearch/index/mapper/blockloader/BooleanFieldBlockLoaderTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
import java.util.Objects;
1818

1919
public class BooleanFieldBlockLoaderTests extends BlockLoaderTestCase {
20-
public BooleanFieldBlockLoaderTests() {
21-
super(FieldType.BOOLEAN);
20+
public BooleanFieldBlockLoaderTests(Params params) {
21+
super(FieldType.BOOLEAN.toString(), params);
2222
}
2323

2424
@Override
2525
@SuppressWarnings("unchecked")
26-
protected Object expected(Map<String, Object> fieldMapping, Object value, boolean syntheticSource) {
26+
protected Object expected(Map<String, Object> fieldMapping, Object value) {
2727
var rawNullValue = fieldMapping.get("null_value");
2828

2929
Boolean nullValue;

0 commit comments

Comments
 (0)