Check field data type before casting when applying geo distance sort (#130924)

If a user tries to apply geo distance sorting to a field of the wrong type, they'll get
a 500 error that causes shard failures, because the field data impl gets casted to the
expected type without first checking that the field type is the one expected.
This commit addresses that by returning a 400 error instead.

Closes #129500
This commit is contained in:
Luca Cavanna 2025-07-10 15:49:19 +02:00 committed by GitHub
parent 7380179421
commit 89d84dacd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 1 deletions

View File

@ -0,0 +1,6 @@
pr: 130924
summary: Check field data type before casting when applying geo distance sort
area: Search
type: bug
issues:
- 129500

View File

@ -599,7 +599,13 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
throw new IllegalArgumentException("failed to find mapper for [" + fieldName + "] for geo distance based sort");
}
}
return context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
IndexFieldData<?> indexFieldData = context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
if (indexFieldData instanceof IndexGeoPointFieldData) {
return (IndexGeoPointFieldData) indexFieldData;
}
throw new IllegalArgumentException(
"unable to apply geo distance sort to field [" + fieldName + "] of type [" + fieldType.typeName() + "]"
);
}
private Nested nested(SearchExecutionContext context) throws IOException {

View File

@ -23,6 +23,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.N
import org.elasticsearch.index.mapper.GeoPointFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.NestedPathFieldMapper;
import org.elasticsearch.index.mapper.NumberFieldMapper;
import org.elasticsearch.index.query.GeoValidationMethod;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
@ -99,6 +100,9 @@ public class GeoDistanceSortBuilderTests extends AbstractSortTestCase<GeoDistanc
@Override
protected MappedFieldType provideMappedFieldType(String name) {
if (name.equals("double")) {
return new NumberFieldMapper.NumberFieldType(name, NumberFieldMapper.NumberType.DOUBLE);
}
return new GeoPointFieldMapper.GeoPointFieldType(name);
}
@ -531,6 +535,12 @@ public class GeoDistanceSortBuilderTests extends AbstractSortTestCase<GeoDistanc
);
assertEquals("illegal longitude value [-360.0] for [GeoDistanceSort] for field [fieldName].", ex.getMessage());
}
{
GeoDistanceSortBuilder sortBuilder = new GeoDistanceSortBuilder("double", 0.0, 180.0);
sortBuilder.validation(GeoValidationMethod.STRICT);
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> sortBuilder.build(searchExecutionContext));
assertEquals("unable to apply geo distance sort to field [double] of type [double]", ex.getMessage());
}
}
/**