Skip to content

Commit e32f202

Browse files
committed
Revert "Remove support for geogrid in ST_INTERSECTS"
This reverts commit 6cd7e25.
1 parent 6cd7e25 commit e32f202

File tree

19 files changed

+864
-105
lines changed

19 files changed

+864
-105
lines changed

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

Lines changed: 2 additions & 2 deletions
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_intersects.md

Lines changed: 2 additions & 2 deletions
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/types/st_disjoint.md

Lines changed: 6 additions & 0 deletions
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/types/st_intersects.md

Lines changed: 6 additions & 0 deletions
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_disjoint.json

Lines changed: 124 additions & 16 deletions
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_intersects.json

Lines changed: 124 additions & 16 deletions
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: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,33 @@ count:long | centroid:geo_point | geohashString:keywo
255255
2 | POINT (16.706149326637387 32.37822346854955) | sm | POLYGON((11.25 28.125, 22.5 28.125, 22.5 33.75, 11.25 33.75, 11.25 28.125))
256256
;
257257

258+
gridGeohashDocsFromCell
259+
required_capability: spatial_grid_types
260+
261+
FROM airports
262+
| WHERE ST_INTERSECTS(location, TO_GEOHASH("u1"))
263+
| STATS
264+
count = COUNT(*),
265+
centroid = ST_CENTROID_AGG(location)
266+
;
267+
268+
count:long | centroid:geo_point
269+
8 | POINT (6.351574736181647 51.8981519783847)
270+
;
271+
272+
gridGeohashLiteralFromCell
273+
required_capability: spatial_grid_types
274+
275+
ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (6.351574736181647 51.8981519783847)", "POINT (5.268637698941997 42.747250193330856)"]
276+
| EVAL location = TO_GEOPOINT(location)
277+
| MV_EXPAND location
278+
| WHERE ST_INTERSECTS(location, "u1"::geohash)
279+
;
280+
281+
location:geo_point
282+
POINT (6.351574736181647 51.8981519783847)
283+
;
284+
258285
gridGeohashStatsByWhereUK
259286
required_capability: spatial_grid_types
260287

@@ -563,6 +590,33 @@ count:long | centroid:geo_point | geotileString:keywor
563590
79 | POINT (24.516750878736943 23.93036561181085) | 3/4/3 | POLYGON((0.0 0.0, 45.0 0.0, 45.0 40.979898069620134, 0.0 40.979898069620134, 0.0 0.0))
564591
;
565592

593+
gridGeotileDocsFromCell
594+
required_capability: spatial_grid_types
595+
596+
FROM airports
597+
| WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3"))
598+
| STATS
599+
count = COUNT(*),
600+
centroid = ST_CENTROID_AGG(location)
601+
;
602+
603+
count:long | centroid:geo_point
604+
79 | POINT (24.516750878736943 23.93036561181085)
605+
;
606+
607+
gridGeotileLiteralFromCell
608+
required_capability: spatial_grid_types
609+
610+
ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (24.516750878736943 23.93036561181085)", "POINT (5.268637698941997 42.747250193330856)"]
611+
| EVAL location = TO_GEOPOINT(location)
612+
| MV_EXPAND location
613+
| WHERE ST_INTERSECTS(location, "3/4/3"::geotile)
614+
;
615+
616+
location:geo_point
617+
POINT (24.516750878736943 23.93036561181085)
618+
;
619+
566620
gridGeotileStatsByWhereUK
567621
required_capability: spatial_grid_types
568622

@@ -940,6 +994,34 @@ POINT (13.1442589810713 32.6691695504993) | 813fbffffffffff | 813fbffffffffff
940994
POINT (118.12696884672 24.537192570557) | 8141bffffffffff | null | POLYGON ((121.34751445935747 26.200276060455465, 120.50339385995798 29.892985338693542, 116.26130043917948 31.68090796798786, 112.74092235558841 29.367231998154967, 113.70376749169584 25.199133186716526, 117.99047716641066 23.5089519597363, 119.64146543031175 24.728661050965922, 121.34751445935747 26.200276060455465))
941995
;
942996

997+
gridGeohexDocsFromCell
998+
required_capability: spatial_grid_types
999+
1000+
FROM airports
1001+
| WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff"))
1002+
| STATS
1003+
count = COUNT(*),
1004+
centroid = ST_CENTROID_AGG(location)
1005+
;
1006+
1007+
count:long | centroid:geo_point
1008+
7 | POINT (2.475211258445467 41.32352174592337)
1009+
;
1010+
1011+
gridGeohexLiteralFromCell
1012+
required_capability: spatial_grid_types
1013+
1014+
ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (2.475211258445467 41.32352174592337)", "POINT (5.268637698941997 42.747250193330856)"]
1015+
| EVAL location = TO_GEOPOINT(location)
1016+
| MV_EXPAND location
1017+
| WHERE ST_INTERSECTS(location, "81397ffffffffff"::geohex)
1018+
;
1019+
1020+
location:geo_point
1021+
POINT (2.475211258445467 41.32352174592337)
1022+
POINT (5.268637698941997 42.747250193330856)
1023+
;
1024+
9431025
gridGeohexStatsByWhereUK
9441026
required_capability: spatial_grid_types
9451027

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

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import java.io.IOException;
2929
import java.util.Objects;
30+
import java.util.function.Predicate;
3031

3132
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST;
3233
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND;
@@ -55,15 +56,17 @@ protected BinarySpatialFunction(
5556
Expression right,
5657
boolean leftDocValues,
5758
boolean rightDocValues,
58-
boolean pointsOnly
59+
boolean pointsOnly,
60+
boolean supportsGrid
5961
) {
6062
super(source, left, right);
6163
this.leftDocValues = leftDocValues;
6264
this.rightDocValues = rightDocValues;
63-
this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly);
65+
this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly, supportsGrid);
6466
}
6567

66-
protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly) throws IOException {
68+
protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly, boolean supportsGrid)
69+
throws IOException {
6770
// The doc-values fields are only used on data nodes local planning, and therefor never serialized
6871
this(
6972
in.getTransportVersion().onOrAfter(TransportVersions.ESQL_SERIALIZE_SOURCE_FUNCTIONS_WARNINGS)
@@ -73,7 +76,8 @@ protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean r
7376
in.readNamedWriteable(Expression.class),
7477
leftDocValues,
7578
rightDocValues,
76-
pointsOnly
79+
pointsOnly,
80+
supportsGrid
7781
);
7882
}
7983

@@ -119,10 +123,12 @@ protected TypeResolution resolveType() {
119123
static class SpatialTypeResolver {
120124
private final SpatialEvaluatorFactory.SpatialSourceResolution supplier;
121125
private final boolean pointsOnly;
126+
private final boolean supportsGrid;
122127

123-
SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly) {
128+
SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly, boolean supportsGrid) {
124129
this.supplier = supplier;
125130
this.pointsOnly = pointsOnly;
131+
this.supportsGrid = supportsGrid;
126132
}
127133

128134
public Expression left() {
@@ -147,10 +153,16 @@ protected TypeResolution resolveType() {
147153
}
148154
}
149155

150-
protected Expression.TypeResolution isSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) {
156+
protected Expression.TypeResolution isCompatibleSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) {
151157
return pointsOnly
152158
? EsqlTypeResolutions.isSpatialPoint(e, sourceText(), paramOrd)
153-
: EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd);
159+
: (supportsGrid
160+
? EsqlTypeResolutions.isSpatialOrGrid(e, sourceText(), paramOrd)
161+
: EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd));
162+
}
163+
164+
protected Expression.TypeResolution isGeoPoint(Expression e, TypeResolutions.ParamOrdinal paramOrd) {
165+
return isType(e, GEO_POINT::equals, sourceText(), paramOrd, GEO_POINT.typeName());
154166
}
155167

156168
private TypeResolution resolveType(
@@ -159,8 +171,8 @@ private TypeResolution resolveType(
159171
TypeResolutions.ParamOrdinal leftOrdinal,
160172
TypeResolutions.ParamOrdinal rightOrdinal
161173
) {
162-
TypeResolution leftResolution = isSpatial(leftExpression, leftOrdinal);
163-
TypeResolution rightResolution = isSpatial(rightExpression, rightOrdinal);
174+
TypeResolution leftResolution = isCompatibleSpatial(leftExpression, leftOrdinal);
175+
TypeResolution rightResolution = isCompatibleSpatial(rightExpression, rightOrdinal);
164176
if (leftResolution.resolved()) {
165177
return resolveType(leftExpression, rightExpression, rightOrdinal);
166178
} else if (rightResolution.resolved()) {
@@ -176,9 +188,16 @@ protected TypeResolution resolveType(
176188
TypeResolutions.ParamOrdinal otherParamOrdinal
177189
) {
178190
if (isNull(spatialExpression.dataType())) {
179-
return isSpatial(otherExpression, otherParamOrdinal);
191+
return isCompatibleSpatial(otherExpression, otherParamOrdinal);
180192
}
181193
TypeResolution resolution = isSameSpatialType(spatialExpression.dataType(), otherExpression, sourceText(), otherParamOrdinal);
194+
// TODO Remove these grid checks once we support geo_shape relation to geoGrid
195+
if (resolution.resolved() && DataType.isGeoGrid(spatialExpression.dataType())) {
196+
resolution = isGeoPoint(otherExpression, otherParamOrdinal);
197+
}
198+
if (resolution.resolved() && DataType.isGeoGrid(otherExpression.dataType())) {
199+
resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST);
200+
}
182201
if (resolution.unresolved()) {
183202
return resolution;
184203
}
@@ -192,15 +211,12 @@ protected TypeResolution isSameSpatialType(
192211
String operationName,
193212
TypeResolutions.ParamOrdinal paramOrd
194213
) {
195-
return pointsOnly
196-
? isType(expression, dt -> dt == spatialDataType, operationName, paramOrd, compatibleTypeNames(spatialDataType))
197-
: isType(
198-
expression,
199-
dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt),
200-
operationName,
201-
paramOrd,
202-
compatibleTypeNames(spatialDataType)
203-
);
214+
Predicate<DataType> isSpatialType = pointsOnly
215+
? dt -> dt == spatialDataType
216+
: (supportsGrid
217+
? dt -> DataType.isSpatialOrGrid(dt) && spatialCRSCompatible(spatialDataType, dt)
218+
: dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt));
219+
return isType(expression, isSpatialType, operationName, paramOrd, compatibleTypeNames(spatialDataType));
204220
}
205221
}
206222

@@ -248,7 +264,7 @@ public enum SpatialCrsType {
248264

249265
public static SpatialCrsType fromDataType(DataType dataType) {
250266
return DataType.isSpatialGeo(dataType) ? SpatialCrsType.GEO
251-
: DataType.isSpatial(dataType) ? SpatialCrsType.CARTESIAN
267+
: DataType.isSpatialOrGrid(dataType) ? SpatialCrsType.CARTESIAN
252268
: SpatialCrsType.UNSPECIFIED;
253269
}
254270
}
@@ -278,8 +294,8 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd
278294
// The use of foldable here instead of SpatialEvaluatorFieldKey.isConstant is intentional to match the behavior of the
279295
// Lucene pushdown code in EsqlTranslationHandler::SpatialRelatesTranslator
280296
// We could enhance both places to support ReferenceAttributes that refer to constants, but that is a larger change
281-
return isPushableSpatialAttribute(left(), pushdownPredicates) && right().foldable()
282-
|| isPushableSpatialAttribute(right(), pushdownPredicates) && left().foldable()
297+
return isPushableSpatialAttribute(left(), pushdownPredicates) && isPushableLiteralAttribute(right())
298+
|| isPushableSpatialAttribute(right(), pushdownPredicates) && isPushableLiteralAttribute(left())
283299
? TranslationAware.Translatable.YES
284300
: TranslationAware.Translatable.NO;
285301

@@ -288,4 +304,9 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd
288304
private static boolean isPushableSpatialAttribute(Expression exp, LucenePushdownPredicates p) {
289305
return exp instanceof FieldAttribute fa && DataType.isSpatial(fa.dataType()) && fa.getExactInfo().hasExact() && p.isIndexed(fa);
290306
}
307+
308+
private static boolean isPushableLiteralAttribute(Expression exp) {
309+
// TODO: Support pushdown of geo-grid queries where the constant is a geo-grid-id literal
310+
return DataType.isSpatial(exp.dataType()) && exp.foldable();
311+
}
291312
}

0 commit comments

Comments
 (0)