Skip to content

Commit 9cca2b2

Browse files
committed
Disallow any geo_shape bounds other than BBOX
Also enhance tests to validate against actual bounds
1 parent 8af276b commit 9cca2b2

File tree

16 files changed

+165
-51
lines changed

16 files changed

+165
-51
lines changed

docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,36 @@ gridGeohashStatsByBounds
144144
required_capability: spatial_grid
145145

146146
FROM airports
147-
| EVAL geohash = ST_GEOHASH(location, 2, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
147+
| EVAL geohash = ST_GEOHASH(location, 2, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
148+
| WHERE geohash IS NOT NULL
149+
| STATS
150+
count = COUNT(*),
151+
centroid = ST_CENTROID_AGG(location)
152+
BY geohash
153+
| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash)
154+
| KEEP count, centroid, geohashString
155+
| SORT count DESC, geohashString ASC
156+
;
157+
158+
count:long | centroid:geo_point | geohashString:keyword
159+
19 | POINT (6.360728044651057 47.94084087577894) | u0
160+
10 | POINT (15.350638423115015 47.80751353036612) | u2
161+
9 | POINT (18.5217544157058 42.1394603792578) | sr
162+
8 | POINT (6.351574736181647 51.8981519783847) | u1
163+
7 | POINT (5.268637698941997 42.747250193330856) | sp
164+
7 | POINT (17.092350951528974 53.365471504096476) | u3
165+
5 | POINT (16.2651440910995 58.812188878655434) | u6
166+
4 | POINT (7.7012718468904495 36.39783004182391) | sn
167+
3 | POINT (14.222751930356026 37.168446206487715) | sq
168+
3 | POINT (7.318722177296877 59.788265260867774) | u4
169+
2 | POINT (16.706149326637387 32.37822346854955) | sm
170+
;
171+
172+
gridGeohashStatsByBoundsEnvelope
173+
required_capability: spatial_grid
174+
175+
FROM airports
176+
| EVAL geohash = ST_GEOHASH(location, 2, ST_ENVELOPE(TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")))
148177
| WHERE geohash IS NOT NULL
149178
| STATS
150179
count = COUNT(*),
@@ -393,7 +422,27 @@ gridGeotileStatsByBounds
393422
required_capability: spatial_grid
394423

395424
FROM airports
396-
| EVAL geotile = ST_GEOTILE(location, 3, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
425+
| EVAL geotile = ST_GEOTILE(location, 3, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
426+
| WHERE geotile IS NOT NULL
427+
| STATS
428+
count = COUNT(*),
429+
centroid = ST_CENTROID_AGG(location)
430+
BY geotile
431+
| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile)
432+
| SORT count DESC, geotileString ASC
433+
| KEEP count, centroid, geotileString
434+
;
435+
436+
count:long | centroid:geo_point | geotileString:keyword
437+
100 | POINT (18.10569669920951 50.40505832391791) | 3/4/2
438+
79 | POINT (24.516750878736943 23.93036561181085) | 3/4/3
439+
;
440+
441+
gridGeotileStatsByBoundsEnvelope
442+
required_capability: spatial_grid
443+
444+
FROM airports
445+
| EVAL geotile = ST_GEOTILE(location, 3, ST_ENVELOPE(TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")))
397446
| WHERE geotile IS NOT NULL
398447
| STATS
399448
count = COUNT(*),
@@ -630,7 +679,36 @@ gridGeohexStatsByBounds
630679
required_capability: spatial_grid
631680

632681
FROM airports
633-
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
682+
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
683+
| WHERE geohex IS NOT NULL
684+
| STATS
685+
count = COUNT(*),
686+
centroid = ST_CENTROID_AGG(location)
687+
BY geohex
688+
| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)
689+
| SORT count DESC, geohexString ASC
690+
| KEEP count, centroid, geohexString
691+
;
692+
693+
count:long | centroid:geo_point | geohexString:keyword
694+
22 | POINT (7.250850197689777 48.21363834643059) | 811fbffffffffff
695+
17 | POINT (-0.7606179875266903 52.86413913565304) | 81197ffffffffff
696+
7 | POINT (2.475211258445467 41.32352174592337) | 81397ffffffffff
697+
6 | POINT (11.75047050230205 42.351422344800085) | 811ebffffffffff
698+
5 | POINT (18.766171680763364 59.15833930950612) | 8108bffffffffff
699+
5 | POINT (11.404999259859324 54.510593589395285) | 811f3ffffffffff
700+
4 | POINT (5.167026452254504 59.81037143385038) | 8109bffffffffff
701+
4 | POINT (-1.1871178611181676 35.77457194332965) | 81383ffffffffff
702+
3 | POINT (-1.1497433669865131 45.83295159973204) | 81187ffffffffff
703+
3 | POINT (9.197671310976148 36.29719984252006) | 81387ffffffffff
704+
1 | POINT (13.144258903339505 32.66916951164603) | 813fbffffffffff
705+
;
706+
707+
gridGeohexStatsByBoundsEnvelope
708+
required_capability: spatial_grid
709+
710+
FROM airports
711+
| EVAL geohex = ST_GEOHEX(location, 1, ST_ENVELOPE(TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")))
634712
| WHERE geohex IS NOT NULL
635713
| STATS
636714
count = COUNT(*),
@@ -659,7 +737,7 @@ gridGeohexQueryBounds
659737
required_capability: spatial_grid
660738

661739
FROM airports
662-
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
740+
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
663741
| WHERE ST_GEOHEX_TO_STRING(geohex) == "8108bffffffffff"
664742
| EVAL geohexString = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 1))
665743
| KEEP abbrev, location, geohexString
@@ -679,7 +757,7 @@ required_capability: spatial_grid
679757

680758
FROM airports
681759
| WHERE abbrev IN ("RTW", "TIP", "XMN")
682-
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
760+
| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
683761
| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)
684762
| KEEP abbrev, location, geohex, geohexString
685763
| SORT abbrev ASC
@@ -698,7 +776,7 @@ ROW location = ["POINT (46.035023249891 51.5606456508842)", "POINT (13.144258981
698776
| MV_EXPAND location
699777
| EVAL location = TO_GEOPOINT(location)
700778
| EVAL geohex = ST_GEOHEX(location, 1)
701-
| EVAL geohexBounded = ST_GEOHEX(location, 1, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
779+
| EVAL geohexBounded = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)"))
702780
| EVAL geohex = ST_GEOHEX_TO_STRING(geohex)
703781
| EVAL geohexBounded = ST_GEOHEX_TO_STRING(geohexBounded)
704782
| KEEP location, geohex, geohexBounded
@@ -773,7 +851,7 @@ FROM airports
773851
| STATS
774852
count = COUNT(location),
775853
centroid = ST_CENTROID_AGG(location)
776-
BY ST_GEOHEX(location, 2, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))"))
854+
BY ST_GEOHEX(location, 2, ST_ENVELOPE(TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")))
777855
| WHERE count > 3
778856
| SORT count DESC
779857
| KEEP count, centroid

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunction.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.elasticsearch.compute.data.LongBlock;
1717
import org.elasticsearch.geometry.Point;
1818
import org.elasticsearch.geometry.Rectangle;
19-
import org.elasticsearch.geometry.utils.SpatialEnvelopeVisitor;
2019
import org.elasticsearch.xpack.esql.core.expression.Expression;
2120
import org.elasticsearch.xpack.esql.core.expression.function.scalar.ScalarFunction;
2221
import org.elasticsearch.xpack.esql.core.tree.Source;
@@ -125,11 +124,7 @@ protected static Rectangle asRectangle(BytesRef boundsBytesRef) {
125124
if (geometry instanceof Rectangle rectangle) {
126125
return rectangle;
127126
}
128-
var envelope = SpatialEnvelopeVisitor.visitGeo(geometry, SpatialEnvelopeVisitor.WrapLongitude.WRAP);
129-
if (envelope.isPresent()) {
130-
return envelope.get();
131-
}
132-
throw new IllegalArgumentException("Cannot determine envelope of bounds geometry");
127+
throw new IllegalArgumentException("Bounds geometry type '" + geometry.getClass().getSimpleName() + "' is not an envelope");
133128
}
134129

135130
protected static GeoBoundingBox asGeoBoundingBox(Object bounds) {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StEnvelope.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua
9898

9999
@Override
100100
public DataType dataType() {
101+
if (dataType == null) {
102+
resolveType();
103+
}
101104
return dataType;
102105
}
103106

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ public StGeohash(
119119
Expression of type `integer`. If `null`, the function returns `null`.
120120
Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash).""") Expression precision,
121121
@Param(name = "bounds", type = { "geo_shape" }, description = """
122-
Optional bounds to filter the grid tiles, a `geo_shape`.
123-
The envelope of the `geo_shape` is used as bounds.""", optional = true) Expression bounds
122+
Optional bounds to filter the grid tiles, a `geo_shape` of type `BBOX`.
123+
Use [`ST_ENVELOPE`](#esql-st_envelope) if the `geo_shape` is of any other type.""", optional = true) Expression bounds
124124
) {
125125
this(source, field, precision, bounds, false);
126126
}

0 commit comments

Comments
 (0)