-
Notifications
You must be signed in to change notification settings - Fork 25.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL: Improve null handling in Geo Functions #40708
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
ab8e2a3
SQL: Improve null handling in Geo Functions
imotov c7f35ca
Address review comments
imotov dd3e122
Merge remote-tracking branch 'elastic/geosql' into null-handling-for-…
imotov 4004d7a
Address review comments
imotov 8feb38c
Address final review comments
imotov 284ec3b
Address @costin's review comments
imotov e49c1de
Merge remote-tracking branch 'elastic/geosql' into null-handling-for-…
imotov cf96e18
Merge remote-tracking branch 'elastic/geosql' into null-handling-for-…
imotov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
30 changes: 15 additions & 15 deletions
30
x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,33 @@ | ||
{"index":{"_id": "1"}} | ||
{"region": "Americas", "city": "Mountain View", "location": {"lat":"37.386483", "lon":"-122.083843"}, "shape": "POINT (-122.083843 37.386483)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"region": "Americas", "city": "Mountain View", "location": {"lat":"37.386483", "lon":"-122.083843"}, "location_no_dv": {"lat":"37.386483", "lon":"-122.083843"}, "shape": "POINT (-122.083843 37.386483)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"index":{"_id": "2"}} | ||
{"region": "Americas", "city": "Chicago", "location": [-87.637874, 41.888783], "shape": {"type" : "point", "coordinates" : [-87.637874, 41.888783]}, "region_point": "POINT(-105.2551 54.5260)"} | ||
{"region": "Americas", "city": "Chicago", "location": [-87.637874, 41.888783], "location_no_dv": [-87.637874, 41.888783], "shape": {"type" : "point", "coordinates" : [-87.637874, 41.888783]}, "region_point": "POINT(-105.2551 54.5260)"} | ||
{"index":{"_id": "3"}} | ||
{"region": "Americas", "city": "New York", "location": "40.745171,-73.990027", "shape": "POINT (-73.990027 40.745171)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"region": "Americas", "city": "New York", "location": "40.745171,-73.990027", "location_no_dv": "40.745171,-73.990027", "shape": "POINT (-73.990027 40.745171)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"index":{"_id": "4"}} | ||
{"region": "Americas", "city": "San Francisco", "location": "37.789541,-122.394228", "shape": "POINT (-122.394228 37.789541)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"region": "Americas", "city": "San Francisco", "location": "37.789541,-122.394228", "location_no_dv": "37.789541,-122.394228", "shape": "POINT (-122.394228 37.789541)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"index":{"_id": "5"}} | ||
{"region": "Americas", "city": "Phoenix", "location": "33.376242,-111.973505", "shape": "POINT (-111.973505 33.376242)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"region": "Americas", "city": "Phoenix", "location": "33.376242,-111.973505", "location_no_dv": "33.376242,-111.973505", "shape": "POINT (-111.973505 33.376242)", "region_point": "POINT(-105.2551 54.5260)"} | ||
{"index":{"_id": "6"}} | ||
{"region": "Europe", "city": "Amsterdam", "location": "52.347557,4.850312", "shape": "POINT (4.850312 52.347557)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"region": "Europe", "city": "Amsterdam", "location": "52.347557,4.850312", "location_no_dv": "52.347557,4.850312", "shape": "POINT (4.850312 52.347557)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"index":{"_id": "7"}} | ||
{"region": "Europe", "city": "Berlin", "location": "52.486701,13.390889", "shape": "POINT (13.390889 52.486701)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"region": "Europe", "city": "Berlin", "location": "52.486701,13.390889", "location_no_dv": "52.486701,13.390889", "shape": "POINT (13.390889 52.486701)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"index":{"_id": "8"}} | ||
{"region": "Europe", "city": "Munich", "location": "48.146321,11.537505", "shape": "POINT (11.537505 48.146321)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"region": "Europe", "city": "Munich", "location": "48.146321,11.537505", "location_no_dv": "48.146321,11.537505", "shape": "POINT (11.537505 48.146321)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"index":{"_id": "9"}} | ||
{"region": "Europe", "city": "London", "location": "51.510871,-0.121672", "shape": "POINT (-0.121672 51.510871)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"region": "Europe", "city": "London", "location": "51.510871,-0.121672", "location_no_dv": "51.510871,-0.121672", "shape": "POINT (-0.121672 51.510871)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"index":{"_id": "10"}} | ||
{"region": "Europe", "city": "Paris", "location": "48.845538,2.351773", "shape": "POINT (2.351773 48.845538)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"region": "Europe", "city": "Paris", "location": "48.845538,2.351773", "location_no_dv": "48.845538,2.351773", "shape": "POINT (2.351773 48.845538)", "region_point": "POINT(15.2551 54.5260)"} | ||
{"index":{"_id": "11"}} | ||
{"region": "Asia", "city": "Singapore", "location": "1.295868,103.855535", "shape": "POINT (103.855535 1.295868)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"region": "Asia", "city": "Singapore", "location": "1.295868,103.855535", "location_no_dv": "1.295868,103.855535", "shape": "POINT (103.855535 1.295868)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"index":{"_id": "12"}} | ||
{"region": "Asia", "city": "Hong Kong", "location": "22.281397,114.183925", "shape": "POINT (114.183925 22.281397)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"region": "Asia", "city": "Hong Kong", "location": "22.281397,114.183925", "location_no_dv": "22.281397,114.183925", "shape": "POINT (114.183925 22.281397)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"index":{"_id": "13"}} | ||
{"region": "Asia", "city": "Seoul", "location": "37.509132,127.060851", "shape": "POINT (127.060851 37.509132)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"region": "Asia", "city": "Seoul", "location": "37.509132,127.060851", "location_no_dv": "37.509132,127.060851", "shape": "POINT (127.060851 37.509132)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"index":{"_id": "14"}} | ||
{"region": "Asia", "city": "Tokyo", "location": "35.669616,139.76402225", "shape": "POINT (139.76402225 35.669616)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"region": "Asia", "city": "Tokyo", "location": "35.669616,139.76402225", "location_no_dv": "35.669616,139.76402225", "shape": "POINT (139.76402225 35.669616)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"index":{"_id": "15"}} | ||
{"region": "Asia", "city": "Sydney", "location": "-33.863385,151.208629", "shape": "POINT (151.208629 -33.863385)", "region_point": "POINT(100.6197 34.0479)"} | ||
{"region": "Asia", "city": "Sydney", "location": "-33.863385,151.208629", "location_no_dv": "-33.863385,151.208629", "shape": "POINT (151.208629 -33.863385)", "region_point": "POINT(100.6197 34.0479)"} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,43 +127,34 @@ private Object unwrapMultiValue(Object values) { | |
if (values == null) { | ||
return null; | ||
} | ||
if (dataType == DataType.GEO_POINT) { | ||
Object value; | ||
if (values instanceof List && ((List<?>) values).size() == 1) { | ||
value = ((List<?>) values).get(0); | ||
if (values instanceof List) { | ||
List<?> list = (List<?>) values; | ||
if (list.isEmpty()) { | ||
return null; | ||
} else { | ||
value = values; | ||
// let's make sure first that we are not dealing with an geo_point represented as an array | ||
if (isGeoPointArray(list) == false) { | ||
if (list.size() == 1 || arrayLeniency) { | ||
return unwrapMultiValue(list.get(0)); | ||
} else { | ||
throw new SqlIllegalArgumentException("Arrays (returned by [{}]) are not supported", fieldName); | ||
} | ||
} | ||
} | ||
} | ||
if (dataType == DataType.GEO_POINT) { | ||
try { | ||
GeoPoint geoPoint = GeoUtils.parseGeoPoint(value, true); | ||
GeoPoint geoPoint = GeoUtils.parseGeoPoint(values, true); | ||
return new GeoShape(geoPoint.lon(), geoPoint.lat()); | ||
} catch (ElasticsearchParseException ex) { | ||
throw new SqlIllegalArgumentException("Cannot parse geo_point value (returned by [{}])", fieldName); | ||
throw new SqlIllegalArgumentException("Cannot parse geo_point value [{}] (returned by [{}])", values, fieldName); | ||
} | ||
} | ||
if (dataType == DataType.GEO_SHAPE) { | ||
Object value; | ||
if (values instanceof List && ((List<?>) values).size() == 1) { | ||
value = ((List<?>) values).get(0); | ||
} else { | ||
value = values; | ||
} | ||
try { | ||
return new GeoShape(value); | ||
return new GeoShape(values); | ||
} catch (IOException ex) { | ||
throw new SqlIllegalArgumentException("Cannot read geo_shape value (returned by [{}])", fieldName); | ||
} | ||
} | ||
if (values instanceof List) { | ||
List<?> list = (List<?>) values; | ||
if (list.isEmpty()) { | ||
return null; | ||
} else { | ||
if (arrayLeniency || list.size() == 1) { | ||
return unwrapMultiValue(list.get(0)); | ||
} else { | ||
throw new SqlIllegalArgumentException("Arrays (returned by [{}]) are not supported", fieldName); | ||
} | ||
throw new SqlIllegalArgumentException("Cannot read geo_shape value [{}] (returned by [{}])", values, fieldName); | ||
} | ||
} | ||
if (values instanceof Map) { | ||
|
@@ -180,6 +171,17 @@ private Object unwrapMultiValue(Object values) { | |
throw new SqlIllegalArgumentException("Type {} (returned by [{}]) is not supported", values.getClass().getSimpleName(), fieldName); | ||
} | ||
|
||
private boolean isGeoPointArray(List<?> list) { | ||
if (dataType != DataType.GEO_POINT) { | ||
return false; | ||
} | ||
// we expect the point in [lon lat] or [lon lat alt] formats | ||
if (list.size() > 3 || list.size() < 1) { | ||
return false; | ||
} | ||
return list.get(0) instanceof Number; | ||
} | ||
|
||
@SuppressWarnings({ "unchecked", "rawtypes" }) | ||
Object extractFromSource(Map<String, Object> map) { | ||
Object value = null; | ||
|
@@ -204,7 +206,9 @@ Object extractFromSource(Map<String, Object> map) { | |
|
||
if (node instanceof List) { | ||
List listOfValues = (List) node; | ||
if (listOfValues.size() == 1 || arrayLeniency) { | ||
// we can only do this optimization until the last element of our pass since geo points are using arrays | ||
// and we don't want to blindly ignore the second element of array if arrayLeniency is enabled | ||
if ((i < path.length - 1) && (listOfValues.size() == 1 || arrayLeniency)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would appreciate it if you can add a comment reflecting the reasoning behind this change, in the context of GEO and arrays of values. |
||
// this is a List with a size of 1 e.g.: {"a" : [{"b" : "value"}]} meaning the JSON is a list with one element | ||
// or a list of values with one element e.g.: {"a": {"b" : ["value"]}} | ||
// in case of being lenient about arrays, just extract the first value in the array | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move the dataType check below the instanceof checks (like
DATETIME
) to keep the same style.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot. I has to be before check for map because shape can be a map in case of geojson.