Skip to content

Commit 6059e37

Browse files
committed
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
1 parent 1d4d009 commit 6059e37

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

server/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ public static GeoBoundingBoxQueryBuilder fromXContent(XContentParser parser) thr
394394
GeoValidationMethod validationMethod = null;
395395
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
396396

397-
Rectangle bbox = null;
397+
// bottom (minLat), top (maxLat), left (minLon), right (maxLon)
398+
double[] bbox = null;
398399
String type = "memory";
399400

400401
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@@ -429,8 +430,8 @@ public static GeoBoundingBoxQueryBuilder fromXContent(XContentParser parser) thr
429430
throw new ElasticsearchParseException("failed to parse [{}] query. bounding box not provided", NAME);
430431
}
431432

432-
final GeoPoint topLeft = new GeoPoint(bbox.maxLat, bbox.minLon); //just keep the object
433-
final GeoPoint bottomRight = new GeoPoint(bbox.minLat, bbox.maxLon);
433+
final GeoPoint topLeft = new GeoPoint(bbox[1], bbox[2]);
434+
final GeoPoint bottomRight = new GeoPoint(bbox[0], bbox[3]);
434435

435436
GeoBoundingBoxQueryBuilder builder = new GeoBoundingBoxQueryBuilder(fieldName);
436437
builder.setCorners(topLeft, bottomRight);
@@ -465,7 +466,10 @@ public String getWriteableName() {
465466
return NAME;
466467
}
467468

468-
public static Rectangle parseBoundingBox(XContentParser parser) throws IOException, ElasticsearchParseException {
469+
/**
470+
* Parses the bounding box and returns bottom, top, left, right coordinates
471+
*/
472+
public static double[] parseBoundingBox(XContentParser parser) throws IOException, ElasticsearchParseException {
469473
XContentParser.Token token = parser.currentToken();
470474
if (token != XContentParser.Token.START_OBJECT) {
471475
throw new ElasticsearchParseException("failed to parse bounding box. Expected start object but found [{}]", token);
@@ -527,8 +531,8 @@ public static Rectangle parseBoundingBox(XContentParser parser) throws IOExcepti
527531
+ "using well-known text and explicit corners.");
528532
}
529533
org.locationtech.spatial4j.shape.Rectangle r = envelope.build();
530-
return new Rectangle(r.getMinY(), r.getMaxY(), r.getMinX(), r.getMaxX());
534+
return new double[]{r.getMinY(), r.getMaxY(), r.getMinX(), r.getMaxX()};
531535
}
532-
return new Rectangle(bottom, top, left, right);
536+
return new double[]{bottom, top, left, right};
533537
}
534538
}

server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,26 @@ public void testFromWKT() throws IOException {
450450
assertEquals(expectedJson, GeoExecType.MEMORY, parsed.type());
451451
}
452452

453+
public void testHonorsCoercion() throws IOException {
454+
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
455+
String query = "{\n" +
456+
" \"geo_bounding_box\": {\n" +
457+
" \"validation_method\": \"COERCE\",\n" +
458+
" \"" + GEO_POINT_FIELD_NAME + "\": {\n" +
459+
" \"top_left\": {\n" +
460+
" \"lat\": -15.5,\n" +
461+
" \"lon\": 176.5\n" +
462+
" },\n" +
463+
" \"bottom_right\": {\n" +
464+
" \"lat\": -19.6,\n" +
465+
" \"lon\": 181\n" +
466+
" }\n" +
467+
" }\n" +
468+
" }\n" +
469+
"}\n";
470+
assertGeoBoundingBoxQuery(query);
471+
}
472+
453473
@Override
454474
public void testMustRewrite() throws IOException {
455475
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);

0 commit comments

Comments
 (0)