Fix coerce validation_method in GeoBoundingBoxQueryBuilder (#31747)

The Rectangle constructor validates bounds before coerce has a chance
to normalize coordinates so it cannot be used as intermittent storage.
This commit removes the Rectangle as an intermittent storage for the
bounding box coordinates.

Fixes #31718
This commit is contained in:
Igor Motov 2018-07-03 08:08:40 -07:00 committed by GitHub
parent 1d114071da
commit 396c578066
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 6 deletions

View File

@ -389,7 +389,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
GeoValidationMethod validationMethod = null;
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
Rectangle bbox = null;
// bottom (minLat), top (maxLat), left (minLon), right (maxLon)
double[] bbox = null;
String type = "memory";
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@ -424,8 +425,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
throw new ElasticsearchParseException("failed to parse [{}] query. bounding box not provided", NAME);
}
final GeoPoint topLeft = new GeoPoint(bbox.maxLat, bbox.minLon); //just keep the object
final GeoPoint bottomRight = new GeoPoint(bbox.minLat, bbox.maxLon);
final GeoPoint topLeft = new GeoPoint(bbox[1], bbox[2]);
final GeoPoint bottomRight = new GeoPoint(bbox[0], bbox[3]);
GeoBoundingBoxQueryBuilder builder = new GeoBoundingBoxQueryBuilder(fieldName);
builder.setCorners(topLeft, bottomRight);
@ -460,7 +461,10 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
return NAME;
}
public static Rectangle parseBoundingBox(XContentParser parser) throws IOException, ElasticsearchParseException {
/**
* Parses the bounding box and returns bottom, top, left, right coordinates
*/
public static double[] parseBoundingBox(XContentParser parser) throws IOException, ElasticsearchParseException {
XContentParser.Token token = parser.currentToken();
if (token != XContentParser.Token.START_OBJECT) {
throw new ElasticsearchParseException("failed to parse bounding box. Expected start object but found [{}]", token);
@ -521,8 +525,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
+ "using well-known text and explicit corners.");
}
org.locationtech.spatial4j.shape.Rectangle r = envelope.build();
return new Rectangle(r.getMinY(), r.getMaxY(), r.getMinX(), r.getMaxX());
return new double[]{r.getMinY(), r.getMaxY(), r.getMinX(), r.getMaxX()};
}
return new Rectangle(bottom, top, left, right);
return new double[]{bottom, top, left, right};
}
}

View File

@ -509,6 +509,26 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
assertThat(e1.getMessage(), containsString("Conflicting definition found using well-known text and explicit corners."));
}
public void testHonorsCoercion() throws IOException {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
String query = "{\n" +
" \"geo_bounding_box\": {\n" +
" \"validation_method\": \"COERCE\",\n" +
" \"" + GEO_POINT_FIELD_NAME + "\": {\n" +
" \"top_left\": {\n" +
" \"lat\": -15.5,\n" +
" \"lon\": 176.5\n" +
" },\n" +
" \"bottom_right\": {\n" +
" \"lat\": -19.6,\n" +
" \"lon\": 181\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n";
assertGeoBoundingBoxQuery(query);
}
@Override
public void testMustRewrite() throws IOException {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);