From bf5c14561632a342275d0c34470d5767a5096761 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 17 Jun 2025 18:02:24 +0200 Subject: [PATCH 01/47] Support geohash, geotile and geohex grid types --- .../functions/description/st_geohash.md | 2 +- .../description/st_geohash_to_long.md | 6 - .../description/st_geohash_to_string.md | 6 - .../functions/description/st_geohex.md | 2 +- .../description/st_geohex_to_long.md | 6 - .../description/st_geohex_to_string.md | 6 - .../functions/description/st_geotile.md | 2 +- .../description/st_geotile_to_long.md | 6 - .../description/st_geotile_to_string.md | 6 - .../functions/examples/st_geohash.md | 2 +- .../functions/examples/st_geohash_to_long.md | 14 - .../examples/st_geohash_to_string.md | 14 - .../_snippets/functions/examples/st_geohex.md | 2 +- .../functions/examples/st_geohex_to_long.md | 14 - .../functions/examples/st_geohex_to_string.md | 14 - .../functions/examples/st_geotile.md | 2 +- .../functions/examples/st_geotile_to_long.md | 14 - .../examples/st_geotile_to_string.md | 14 - .../functions/layout/st_geohash_to_long.md | 23 - .../functions/layout/st_geohash_to_string.md | 23 - .../functions/layout/st_geohex_to_long.md | 23 - .../functions/layout/st_geohex_to_string.md | 23 - .../functions/layout/st_geotile_to_long.md | 23 - .../functions/layout/st_geotile_to_string.md | 23 - .../functions/parameters/st_disjoint.md | 4 +- .../parameters/st_geohash_to_long.md | 7 - .../parameters/st_geohash_to_string.md | 7 - .../functions/parameters/st_geohex_to_long.md | 7 - .../parameters/st_geohex_to_string.md | 7 - .../parameters/st_geotile_to_long.md | 7 - .../parameters/st_geotile_to_string.md | 7 - .../functions/parameters/st_intersects.md | 4 +- .../esql/_snippets/functions/types/case.md | 6 + .../_snippets/functions/types/mv_append.md | 3 + .../_snippets/functions/types/mv_count.md | 3 + .../_snippets/functions/types/mv_dedupe.md | 3 + .../_snippets/functions/types/mv_first.md | 3 + .../esql/_snippets/functions/types/mv_last.md | 3 + .../_snippets/functions/types/mv_slice.md | 3 + .../_snippets/functions/types/st_disjoint.md | 6 + .../_snippets/functions/types/st_geohash.md | 4 +- .../functions/types/st_geohash_to_long.md | 9 - .../functions/types/st_geohash_to_string.md | 9 - .../_snippets/functions/types/st_geohex.md | 4 +- .../functions/types/st_geohex_to_long.md | 9 - .../functions/types/st_geohex_to_string.md | 9 - .../_snippets/functions/types/st_geotile.md | 4 +- .../functions/types/st_geotile_to_long.md | 9 - .../functions/types/st_geotile_to_string.md | 9 - .../functions/types/st_intersects.md | 6 + .../_snippets/functions/types/to_geoshape.md | 3 + .../esql/_snippets/functions/types/to_long.md | 3 + .../_snippets/functions/types/to_string.md | 3 + .../esql/_snippets/functions/types/values.md | 3 + .../esql/_snippets/operators/types/equals.md | 3 + .../_snippets/operators/types/is_not_null.md | 3 + .../esql/_snippets/operators/types/is_null.md | 3 + .../_snippets/operators/types/not_equals.md | 3 + .../_snippets/operators/types/predicates.md | 3 + .../esql/images/functions/st_geohash.svg | 2 +- .../images/functions/st_geohash_to_long.svg | 1 - .../images/functions/st_geohash_to_string.svg | 1 - .../images/functions/st_geohex_to_long.svg | 1 - .../images/functions/st_geohex_to_string.svg | 1 - .../images/functions/st_geotile_to_long.svg | 1 - .../images/functions/st_geotile_to_string.svg | 1 - .../kibana/definition/functions/case.json | 126 ++++ .../definition/functions/mv_append.json | 54 ++ .../kibana/definition/functions/mv_count.json | 36 + .../definition/functions/mv_dedupe.json | 36 + .../kibana/definition/functions/mv_first.json | 36 + .../kibana/definition/functions/mv_last.json | 36 + .../kibana/definition/functions/mv_slice.json | 72 ++ .../definition/functions/st_disjoint.json | 140 +++- .../definition/functions/st_geohash.json | 12 +- .../functions/st_geohash_to_long.json | 37 - .../functions/st_geohash_to_string.json | 37 - .../definition/functions/st_geohex.json | 8 +- .../functions/st_geohex_to_long.json | 37 - .../functions/st_geohex_to_string.json | 37 - .../definition/functions/st_geotile.json | 8 +- .../functions/st_geotile_to_long.json | 37 - .../functions/st_geotile_to_string.json | 37 - .../definition/functions/st_intersects.json | 140 +++- .../definition/functions/to_geoshape.json | 36 + .../kibana/definition/functions/to_long.json | 36 + .../definition/functions/to_string.json | 36 + .../kibana/definition/functions/values.json | 36 + .../kibana/definition/operators/equals.json | 54 ++ .../definition/operators/is_not_null.json | 36 + .../kibana/definition/operators/is_null.json | 36 + .../definition/operators/not_equals.json | 54 ++ .../definition/operators/predicates.json | 36 + .../esql/kibana/docs/functions/st_geohash.md | 6 +- .../docs/functions/st_geohash_to_long.md | 9 - .../docs/functions/st_geohash_to_string.md | 9 - .../esql/kibana/docs/functions/st_geohex.md | 6 +- .../docs/functions/st_geohex_to_long.md | 9 - .../docs/functions/st_geohex_to_string.md | 9 - .../esql/kibana/docs/functions/st_geotile.md | 6 +- .../docs/functions/st_geotile_to_long.md | 9 - .../docs/functions/st_geotile_to_string.md | 9 - .../xpack/esql/core/type/DataType.java | 23 +- .../elasticsearch/xpack/esql/CsvAssert.java | 9 + .../xpack/esql/CsvTestUtils.java | 8 + .../xpack/esql/EsqlTestUtils.java | 15 + .../src/main/resources/spatial-grid.csv-spec | 647 ++++++++++++------ .../ToGeoShapeFromGeoGridEvaluator.java} | 75 +- .../ToGeohashFromStringEvaluator.java} | 66 +- .../ToGeohexFromStringEvaluator.java} | 66 +- .../ToGeotileFromStringEvaluator.java} | 66 +- .../ToStringFromGeoGridEvaluator.java} | 33 +- ...ointDocValuesAndConstantGridEvaluator.java | 127 ++++ ...oPointDocValuesAndSourceGridEvaluator.java | 133 ++++ ...ointGeoSourceAndConstantGridEvaluator.java | 127 ++++ ...sjointGeoSourceAndSourceGridEvaluator.java | 133 ++++ ...ointDocValuesAndConstantGridEvaluator.java | 127 ++++ ...oPointDocValuesAndSourceGridEvaluator.java | 133 ++++ ...ectsGeoSourceAndConstantGridEvaluator.java | 127 ++++ ...rsectsGeoSourceAndSourceGridEvaluator.java | 133 ++++ .../StGeohexToStringFromLongEvaluator.java | 124 ---- .../xpack/esql/action/PositionToXContent.java | 9 + .../xpack/esql/action/ResponseValueUtils.java | 2 + .../xpack/esql/analysis/Verifier.java | 3 + .../esql/expression/EsqlTypeResolutions.java | 15 + .../esql/expression/ExpressionWritables.java | 14 +- .../function/EsqlFunctionRegistry.java | 26 +- .../expression/function/aggregate/Values.java | 9 + .../function/scalar/conditional/Case.java | 6 + .../function/scalar/convert/ToGeoShape.java | 15 +- .../ToGeohash.java} | 53 +- .../ToGeohex.java} | 55 +- .../ToGeotile.java} | 53 +- .../function/scalar/convert/ToLong.java | 13 +- .../function/scalar/convert/ToString.java | 16 + .../function/scalar/multivalue/MvAppend.java | 9 + .../function/scalar/multivalue/MvCount.java | 3 + .../function/scalar/multivalue/MvDedupe.java | 6 + .../function/scalar/multivalue/MvFirst.java | 6 + .../function/scalar/multivalue/MvLast.java | 6 + .../function/scalar/multivalue/MvMax.java | 4 +- .../function/scalar/multivalue/MvMin.java | 4 +- .../function/scalar/multivalue/MvSlice.java | 6 + .../function/scalar/nulls/Coalesce.java | 18 +- .../scalar/spatial/BinarySpatialFunction.java | 56 +- .../scalar/spatial/SpatialDisjoint.java | 115 +++- .../spatial/SpatialEvaluatorFactory.java | 21 + .../scalar/spatial/SpatialIntersects.java | 115 +++- .../spatial/SpatialRelatesFunction.java | 107 ++- .../scalar/spatial/SpatialRelatesUtils.java | 16 +- .../function/scalar/spatial/StDistance.java | 6 +- .../function/scalar/spatial/StGeohash.java | 17 +- .../scalar/spatial/StGeohashToString.java | 94 --- .../function/scalar/spatial/StGeohex.java | 36 +- .../scalar/spatial/StGeohexToString.java | 94 --- .../function/scalar/spatial/StGeotile.java | 26 +- .../scalar/spatial/StGeotileToString.java | 94 --- .../predicate/operator/comparison/Equals.java | 3 + .../predicate/operator/comparison/In.java | 6 +- .../operator/comparison/NotEquals.java | 3 + .../xpack/esql/plan/logical/join/Join.java | 6 + .../esql/planner/LocalExecutionPlanner.java | 2 +- .../xpack/esql/planner/PlannerUtils.java | 4 +- .../esql/type/EsqlDataTypeConverter.java | 35 +- .../esql/action/EsqlQueryResponseTests.java | 23 + .../xpack/esql/analysis/AnalyzerTests.java | 2 +- .../xpack/esql/analysis/VerifierTests.java | 23 +- .../function/MultiRowTestCaseSupplier.java | 34 + .../expression/function/TestCaseSupplier.java | 49 +- .../function/aggregate/ValuesTests.java | 5 +- .../scalar/conditional/CaseTests.java | 3 + .../scalar/convert/ToGeoShapeErrorTests.java | 3 +- .../scalar/convert/ToGeoShapeTests.java | 13 + .../scalar/convert/ToLongErrorTests.java | 11 +- .../function/scalar/convert/ToLongTests.java | 5 + .../scalar/convert/ToStringTests.java | 12 + .../AbstractMultivalueFunctionTestCase.java | 96 +++ .../scalar/multivalue/MvAppendTests.java | 53 +- .../scalar/multivalue/MvCountTests.java | 3 + .../scalar/multivalue/MvDedupeTests.java | 3 + .../scalar/multivalue/MvFirstTests.java | 3 + .../scalar/multivalue/MvLastTests.java | 3 + .../scalar/multivalue/MvSliceTests.java | 79 +-- .../BinarySpatialFunctionTestCase.java | 114 ++- .../scalar/spatial/SpatialDisjointTests.java | 8 + .../spatial/SpatialGridFunctionTestCase.java | 6 +- .../spatial/SpatialIntersectsTests.java | 10 +- .../SpatialRelatesFunctionTestCase.java | 8 +- .../scalar/spatial/StDistanceTests.java | 2 +- .../scalar/spatial/StGeohashTests.java | 4 +- .../scalar/spatial/StGeohashToLongTests.java | 63 -- .../spatial/StGeohashToStringTests.java | 64 -- .../scalar/spatial/StGeohexTests.java | 4 +- .../scalar/spatial/StGeohexToLongTests.java | 63 -- .../scalar/spatial/StGeohexToStringTests.java | 64 -- .../scalar/spatial/StGeotileTests.java | 5 +- .../scalar/spatial/StGeotileToLongTests.java | 63 -- .../spatial/StGeotileToStringTests.java | 64 -- .../operator/comparison/EqualsTests.java | 16 + .../operator/comparison/NotEqualsTests.java | 16 + .../TestPhysicalOperationProviders.java | 4 +- 201 files changed, 4059 insertions(+), 2136 deletions(-) delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg delete mode 100644 docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json delete mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md delete mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md rename x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeohashToStringFromLongEvaluator.java => convert/ToGeoShapeFromGeoGridEvaluator.java} (57%) rename x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeotileToLongFromStringEvaluator.java => convert/ToGeohashFromStringEvaluator.java} (64%) rename x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeohashToLongFromStringEvaluator.java => convert/ToGeohexFromStringEvaluator.java} (64%) rename x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeohexToLongFromStringEvaluator.java => convert/ToGeotileFromStringEvaluator.java} (64%) rename x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeotileToStringFromLongEvaluator.java => convert/ToStringFromGeoGridEvaluator.java} (78%) create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndConstantGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndSourceGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndConstantGridEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndSourceGridEvaluator.java delete mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringFromLongEvaluator.java rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeohashToLong.java => convert/ToGeohash.java} (57%) rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeohexToLong.java => convert/ToGeohex.java} (56%) rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/{spatial/StGeotileToLong.java => convert/ToGeotile.java} (57%) delete mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToString.java delete mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToString.java delete mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToString.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongTests.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringTests.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongTests.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringTests.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongTests.java delete mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringTests.java diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash.md index 1ca47a3a95d9a..9941e64a5c187 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash.md +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash.md @@ -2,5 +2,5 @@ **Description** -Calculates the `geohash` of the supplied geo_point at the specified precision. The result is long encoded. Use [ST_GEOHASH_TO_STRING](#esql-st_geohash_to_string) to convert the result to a string. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation.md). +Calculates the `geohash` of the supplied geo_point at the specified precision. The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation.md). diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md deleted file mode 100644 index 2abb0c416addb..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a geohash grid-ID in string format into a long. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md deleted file mode 100644 index 5e1cc240c4731..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a geohash grid-ID in long format into a string. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex.md index f67a0e38754e2..d4d05a693f947 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex.md +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex.md @@ -2,5 +2,5 @@ **Description** -Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision. The result is long encoded. Use [ST_GEOHEX_TO_STRING](#esql-st_geohex_to_string) to convert the result to a string. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation.md). +Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision. The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation.md). diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md deleted file mode 100644 index b391ae1d685eb..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a geohex grid-ID in string format into a long. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md deleted file mode 100644 index 7915ff0170e05..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a Geohex grid-ID in long format into a string. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile.md index a6d5381e90555..b027eb86edf60 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile.md +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile.md @@ -2,5 +2,5 @@ **Description** -Calculates the `geotile` of the supplied geo_point at the specified precision. The result is long encoded. Use [ST_GEOTILE_TO_STRING](#esql-st_geotile_to_string) to convert the result to a string. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation.md). +Calculates the `geotile` of the supplied geo_point at the specified precision. The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation.md). diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md deleted file mode 100644 index 7ebe7a08d2a4d..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a geotile grid-ID in string format into a long. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md deleted file mode 100644 index 71fd355372975..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md +++ /dev/null @@ -1,6 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Description** - -Converts an input value representing a geotile grid-ID in long format into a string. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md index f9fab4135d31f..e3085daab4534 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md @@ -10,7 +10,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL geohashString = TO_STRING(geohash) | KEEP count, centroid, geohashString | SORT count DESC, geohashString ASC ``` diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md deleted file mode 100644 index a5dd10b329f6f..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geohash = "u3bu" -| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash) -``` - -| geohash:keyword | geohashLong:long | -| --- | --- | -| u3bu | 13686180 | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md deleted file mode 100644 index dd6327499254f..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geohash = TO_LONG(13686180) -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -``` - -| geohash:long | geohashString:keyword | -| --- | --- | -| 13686180 | u3bu | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md index 875add22968d6..d62de506442b6 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md @@ -10,7 +10,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) | KEEP count, centroid, geohexString | SORT count DESC, geohexString ASC ``` diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md deleted file mode 100644 index be94b611917aa..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geohex = "841f059ffffffff" -| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex) -``` - -| geohex:keyword | geohexLong:long | -| --- | --- | -| 841f059ffffffff | 595020895127339007 | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md deleted file mode 100644 index b3eabacd5ec14..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geohex = 595020895127339007 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -``` - -| geohex:long | geohexString:keyword | -| --- | --- | -| 595020895127339007 | 841f059ffffffff | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md index 0653f55c969c7..c1d19e448efcc 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md @@ -9,7 +9,7 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) | SORT count DESC, geotileString ASC | KEEP count, centroid, geotileString ``` diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md deleted file mode 100644 index 995f04ee6f355..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geotile = "4/8/5" -| EVAL geotileLong = ST_GEOTILE_TO_LONG(geotile) -``` - -| geotile:keyword | geotileLong:long | -| --- | --- | -| 4/8/5 | 1152921508901814277 | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md deleted file mode 100644 index 6e7a95b6ff342..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md +++ /dev/null @@ -1,14 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Example** - -```esql -ROW geotile = 1152921508901814277 -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) -``` - -| geotile:long | geotileString:keyword | -| --- | --- | -| 1152921508901814277 | 4/8/5 | - - diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md deleted file mode 100644 index e9f37660cedf9..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOHASH_TO_LONG` [esql-st_geohash_to_long] - -**Syntax** - -:::{image} ../../../images/functions/st_geohash_to_long.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geohash_to_long.md -::: - -:::{include} ../description/st_geohash_to_long.md -::: - -:::{include} ../types/st_geohash_to_long.md -::: - -:::{include} ../examples/st_geohash_to_long.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md deleted file mode 100644 index cfed286eeee68..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOHASH_TO_STRING` [esql-st_geohash_to_string] - -**Syntax** - -:::{image} ../../../images/functions/st_geohash_to_string.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geohash_to_string.md -::: - -:::{include} ../description/st_geohash_to_string.md -::: - -:::{include} ../types/st_geohash_to_string.md -::: - -:::{include} ../examples/st_geohash_to_string.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md deleted file mode 100644 index 6fe48a030d188..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOHEX_TO_LONG` [esql-st_geohex_to_long] - -**Syntax** - -:::{image} ../../../images/functions/st_geohex_to_long.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geohex_to_long.md -::: - -:::{include} ../description/st_geohex_to_long.md -::: - -:::{include} ../types/st_geohex_to_long.md -::: - -:::{include} ../examples/st_geohex_to_long.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md deleted file mode 100644 index be1b882a50676..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOHEX_TO_STRING` [esql-st_geohex_to_string] - -**Syntax** - -:::{image} ../../../images/functions/st_geohex_to_string.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geohex_to_string.md -::: - -:::{include} ../description/st_geohex_to_string.md -::: - -:::{include} ../types/st_geohex_to_string.md -::: - -:::{include} ../examples/st_geohex_to_string.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md deleted file mode 100644 index eb5828218376d..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOTILE_TO_LONG` [esql-st_geotile_to_long] - -**Syntax** - -:::{image} ../../../images/functions/st_geotile_to_long.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geotile_to_long.md -::: - -:::{include} ../description/st_geotile_to_long.md -::: - -:::{include} ../types/st_geotile_to_long.md -::: - -:::{include} ../examples/st_geotile_to_long.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md deleted file mode 100644 index b1481b33788a4..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md +++ /dev/null @@ -1,23 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### `ST_GEOTILE_TO_STRING` [esql-st_geotile_to_string] - -**Syntax** - -:::{image} ../../../images/functions/st_geotile_to_string.svg -:alt: Embedded -:class: text-center -::: - - -:::{include} ../parameters/st_geotile_to_string.md -::: - -:::{include} ../description/st_geotile_to_string.md -::: - -:::{include} ../types/st_geotile_to_string.md -::: - -:::{include} ../examples/st_geotile_to_string.md -::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md index 0cead33e5e7dd..9aa696450bbf5 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md @@ -3,8 +3,8 @@ **Parameters** `geomA` -: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. +: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. `geomB` -: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. +: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md deleted file mode 100644 index 5db5ddfdfcd2c..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input geohash grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md deleted file mode 100644 index 5db5ddfdfcd2c..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input geohash grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md deleted file mode 100644 index e86ac82e67003..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input geohex grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md deleted file mode 100644 index cb78878f500bf..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input Geohex grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md deleted file mode 100644 index 4a16a5a87faad..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input geotile grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md deleted file mode 100644 index 4a16a5a87faad..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md +++ /dev/null @@ -1,7 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Parameters** - -`grid_id` -: Input geotile grid-id. The input can be a single- or multi-valued column or an expression. - diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md index 0cead33e5e7dd..9aa696450bbf5 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md @@ -3,8 +3,8 @@ **Parameters** `geomA` -: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. +: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. `geomB` -: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. +: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/case.md b/docs/reference/query-languages/esql/_snippets/functions/types/case.md index 7ad667add42b8..0aae7b9f85e60 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/case.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/case.md @@ -20,6 +20,12 @@ | boolean | geo_point | | geo_point | | boolean | geo_shape | geo_shape | geo_shape | | boolean | geo_shape | | geo_shape | +| boolean | geohash | geohash | geohash | +| boolean | geohash | | geohash | +| boolean | geohex | geohex | geohex | +| boolean | geohex | | geohex | +| boolean | geotile | geotile | geotile | +| boolean | geotile | | geotile | | boolean | integer | integer | integer | | boolean | integer | | integer | | boolean | ip | ip | ip | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_append.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_append.md index de780bf38e00c..3e0edaa9e2beb 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_append.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_append.md @@ -12,6 +12,9 @@ | double | double | double | | geo_point | geo_point | geo_point | | geo_shape | geo_shape | geo_shape | +| geohash | geohash | geohash | +| geohex | geohex | geohex | +| geotile | geotile | geotile | | integer | integer | integer | | ip | ip | ip | | keyword | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_count.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_count.md index 61393a2b13a0d..4248cd5651c28 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_count.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_count.md @@ -12,6 +12,9 @@ | double | integer | | geo_point | integer | | geo_shape | integer | +| geohash | integer | +| geohex | integer | +| geotile | integer | | integer | integer | | ip | integer | | keyword | integer | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_dedupe.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_dedupe.md index b01bf30263c1e..0ff590b610391 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_dedupe.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_dedupe.md @@ -12,6 +12,9 @@ | double | double | | geo_point | geo_point | | geo_shape | geo_shape | +| geohash | geohash | +| geohex | geohex | +| geotile | geotile | | integer | integer | | ip | ip | | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_first.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_first.md index b01bf30263c1e..0ff590b610391 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_first.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_first.md @@ -12,6 +12,9 @@ | double | double | | geo_point | geo_point | | geo_shape | geo_shape | +| geohash | geohash | +| geohex | geohex | +| geotile | geotile | | integer | integer | | ip | ip | | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_last.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_last.md index b01bf30263c1e..0ff590b610391 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_last.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_last.md @@ -12,6 +12,9 @@ | double | double | | geo_point | geo_point | | geo_shape | geo_shape | +| geohash | geohash | +| geohex | geohex | +| geotile | geotile | | integer | integer | | ip | ip | | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_slice.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_slice.md index b2f8f1553d6fe..df1a63d8dd91b 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_slice.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_slice.md @@ -12,6 +12,9 @@ | double | integer | integer | double | | geo_point | integer | integer | geo_point | | geo_shape | integer | integer | geo_shape | +| geohash | integer | integer | geohash | +| geohex | integer | integer | geohex | +| geotile | integer | integer | geotile | | integer | integer | integer | integer | | ip | integer | integer | ip | | keyword | integer | integer | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md index b03e441655ea2..73d01c0eb4943 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md @@ -10,6 +10,12 @@ | cartesian_shape | cartesian_shape | boolean | | geo_point | geo_point | boolean | | geo_point | geo_shape | boolean | +| geo_point | geohash | boolean | +| geo_point | geohex | boolean | +| geo_point | geotile | boolean | | geo_shape | geo_point | boolean | | geo_shape | geo_shape | boolean | +| geohash | geo_point | boolean | +| geohex | geo_point | boolean | +| geotile | geo_point | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md index 3c07efc4e3fd1..99a707a6a50ca 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md @@ -4,6 +4,6 @@ | geometry | precision | bounds | result | | --- | --- | --- | --- | -| geo_point | integer | geo_shape | long | -| geo_point | integer | | long | +| geo_point | integer | geo_shape | geohash | +| geo_point | integer | | geohash | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md deleted file mode 100644 index fb31bb5d9f657..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | long | -| long | long | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md deleted file mode 100644 index 5d10b76e7bd09..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | keyword | -| long | keyword | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex.md index 3c07efc4e3fd1..e4efdc58a3de8 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex.md @@ -4,6 +4,6 @@ | geometry | precision | bounds | result | | --- | --- | --- | --- | -| geo_point | integer | geo_shape | long | -| geo_point | integer | | long | +| geo_point | integer | geo_shape | geohex | +| geo_point | integer | | geohex | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md deleted file mode 100644 index fb31bb5d9f657..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | long | -| long | long | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md deleted file mode 100644 index 5d10b76e7bd09..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | keyword | -| long | keyword | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile.md index 3c07efc4e3fd1..5cd0382057dd7 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile.md @@ -4,6 +4,6 @@ | geometry | precision | bounds | result | | --- | --- | --- | --- | -| geo_point | integer | geo_shape | long | -| geo_point | integer | | long | +| geo_point | integer | geo_shape | geotile | +| geo_point | integer | | geotile | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md deleted file mode 100644 index fb31bb5d9f657..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | long | -| long | long | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md deleted file mode 100644 index 5d10b76e7bd09..0000000000000 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -**Supported types** - -| grid_id | result | -| --- | --- | -| keyword | keyword | -| long | keyword | - diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md index b03e441655ea2..73d01c0eb4943 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md @@ -10,6 +10,12 @@ | cartesian_shape | cartesian_shape | boolean | | geo_point | geo_point | boolean | | geo_point | geo_shape | boolean | +| geo_point | geohash | boolean | +| geo_point | geohex | boolean | +| geo_point | geotile | boolean | | geo_shape | geo_point | boolean | | geo_shape | geo_shape | boolean | +| geohash | geo_point | boolean | +| geohex | geo_point | boolean | +| geotile | geo_point | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geoshape.md index 0a8f43fc64cd0..145932493553b 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_geoshape.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geoshape.md @@ -6,6 +6,9 @@ | --- | --- | | geo_point | geo_shape | | geo_shape | geo_shape | +| geohash | geo_shape | +| geohex | geo_shape | +| geotile | geo_shape | | keyword | geo_shape | | text | geo_shape | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_long.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_long.md index 39784918e1e9e..0ac584cd80bfb 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_long.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_long.md @@ -10,6 +10,9 @@ | date | long | | date_nanos | long | | double | long | +| geohash | long | +| geohex | long | +| geotile | long | | integer | long | | keyword | long | | long | long | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_string.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_string.md index b09ebd9812033..6bb98e5d9318b 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_string.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_string.md @@ -12,6 +12,9 @@ | double | keyword | | geo_point | keyword | | geo_shape | keyword | +| geohash | keyword | +| geohex | keyword | +| geotile | keyword | | integer | keyword | | ip | keyword | | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/values.md b/docs/reference/query-languages/esql/_snippets/functions/types/values.md index b12103f6f0ab7..66a236e7d4980 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/values.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/values.md @@ -12,6 +12,9 @@ | double | double | | geo_point | geo_point | | geo_shape | geo_shape | +| geohash | geohash | +| geohex | geohex | +| geotile | geotile | | integer | integer | | ip | ip | | keyword | keyword | diff --git a/docs/reference/query-languages/esql/_snippets/operators/types/equals.md b/docs/reference/query-languages/esql/_snippets/operators/types/equals.md index 9026a298fefd6..64729ef48e07f 100644 --- a/docs/reference/query-languages/esql/_snippets/operators/types/equals.md +++ b/docs/reference/query-languages/esql/_snippets/operators/types/equals.md @@ -16,6 +16,9 @@ | double | long | boolean | | geo_point | geo_point | boolean | | geo_shape | geo_shape | boolean | +| geohash | geohash | boolean | +| geohex | geohex | boolean | +| geotile | geotile | boolean | | integer | double | boolean | | integer | integer | boolean | | integer | long | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/operators/types/is_not_null.md b/docs/reference/query-languages/esql/_snippets/operators/types/is_not_null.md index 986c99c3cb457..d9c62d47fb745 100644 --- a/docs/reference/query-languages/esql/_snippets/operators/types/is_not_null.md +++ b/docs/reference/query-languages/esql/_snippets/operators/types/is_not_null.md @@ -12,6 +12,9 @@ | double | boolean | | geo_point | boolean | | geo_shape | boolean | +| geohash | boolean | +| geohex | boolean | +| geotile | boolean | | integer | boolean | | ip | boolean | | keyword | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/operators/types/is_null.md b/docs/reference/query-languages/esql/_snippets/operators/types/is_null.md index 986c99c3cb457..d9c62d47fb745 100644 --- a/docs/reference/query-languages/esql/_snippets/operators/types/is_null.md +++ b/docs/reference/query-languages/esql/_snippets/operators/types/is_null.md @@ -12,6 +12,9 @@ | double | boolean | | geo_point | boolean | | geo_shape | boolean | +| geohash | boolean | +| geohex | boolean | +| geotile | boolean | | integer | boolean | | ip | boolean | | keyword | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/operators/types/not_equals.md b/docs/reference/query-languages/esql/_snippets/operators/types/not_equals.md index 9026a298fefd6..64729ef48e07f 100644 --- a/docs/reference/query-languages/esql/_snippets/operators/types/not_equals.md +++ b/docs/reference/query-languages/esql/_snippets/operators/types/not_equals.md @@ -16,6 +16,9 @@ | double | long | boolean | | geo_point | geo_point | boolean | | geo_shape | geo_shape | boolean | +| geohash | geohash | boolean | +| geohex | geohex | boolean | +| geotile | geotile | boolean | | integer | double | boolean | | integer | integer | boolean | | integer | long | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/operators/types/predicates.md b/docs/reference/query-languages/esql/_snippets/operators/types/predicates.md index 986c99c3cb457..d9c62d47fb745 100644 --- a/docs/reference/query-languages/esql/_snippets/operators/types/predicates.md +++ b/docs/reference/query-languages/esql/_snippets/operators/types/predicates.md @@ -12,6 +12,9 @@ | double | boolean | | geo_point | boolean | | geo_shape | boolean | +| geohash | boolean | +| geohex | boolean | +| geotile | boolean | | integer | boolean | | ip | boolean | | keyword | boolean | diff --git a/docs/reference/query-languages/esql/images/functions/st_geohash.svg b/docs/reference/query-languages/esql/images/functions/st_geohash.svg index 231866d25d521..2867f072e1a8e 100644 --- a/docs/reference/query-languages/esql/images/functions/st_geohash.svg +++ b/docs/reference/query-languages/esql/images/functions/st_geohash.svg @@ -1 +1 @@ -ST_GEOHASH(geometry,precision,bounds) \ No newline at end of file +ST_GEOHASH(geometry,precision,bounds) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg b/docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg deleted file mode 100644 index 869af17d522de..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOHASH_TO_LONG(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg b/docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg deleted file mode 100644 index dcb7e909d81dd..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOHASH_TO_STRING(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg b/docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg deleted file mode 100644 index 39181484ebe7a..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOHEX_TO_LONG(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg b/docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg deleted file mode 100644 index 3d96677e1f87e..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOHEX_TO_STRING(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg b/docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg deleted file mode 100644 index 8ac85e2baa2d4..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOTILE_TO_LONG(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg b/docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg deleted file mode 100644 index cbe406dd19211..0000000000000 --- a/docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg +++ /dev/null @@ -1 +0,0 @@ -ST_GEOTILE_TO_STRING(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/case.json b/docs/reference/query-languages/esql/kibana/definition/functions/case.json index 1c6631a1be848..3dc58051d1914 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/case.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/case.json @@ -340,6 +340,132 @@ "variadic" : true, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geohash", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + } + ], + "variadic" : true, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geohash", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + }, + { + "name" : "elseValue", + "type" : "geohash", + "optional" : true, + "description" : "The value that’s returned when no condition evaluates to `true`." + } + ], + "variadic" : true, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geohex", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + } + ], + "variadic" : true, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geohex", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + }, + { + "name" : "elseValue", + "type" : "geohex", + "optional" : true, + "description" : "The value that’s returned when no condition evaluates to `true`." + } + ], + "variadic" : true, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geotile", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + } + ], + "variadic" : true, + "returnType" : "geotile" + }, + { + "params" : [ + { + "name" : "condition", + "type" : "boolean", + "optional" : false, + "description" : "A condition." + }, + { + "name" : "trueValue", + "type" : "geotile", + "optional" : false, + "description" : "The value that’s returned when the corresponding condition is the first to evaluate to `true`. The default value is returned when no condition matches." + }, + { + "name" : "elseValue", + "type" : "geotile", + "optional" : true, + "description" : "The value that’s returned when no condition evaluates to `true`." + } + ], + "variadic" : true, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_append.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_append.json index 898f2edf23ce9..d9b386d60d9ef 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_append.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_append.json @@ -148,6 +148,60 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field1", + "type" : "geohash", + "optional" : false, + "description" : "" + }, + { + "name" : "field2", + "type" : "geohash", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field1", + "type" : "geohex", + "optional" : false, + "description" : "" + }, + { + "name" : "field2", + "type" : "geohex", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field1", + "type" : "geotile", + "optional" : false, + "description" : "" + }, + { + "name" : "field2", + "type" : "geotile", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_count.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_count.json index ceda3879abbe1..be4b9aa5c9487 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_count.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_count.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "integer" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "integer" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "integer" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "integer" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_dedupe.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_dedupe.json index 76774d50c3e8f..abbfb61fe881c 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_dedupe.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_dedupe.json @@ -101,6 +101,42 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_first.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_first.json index 6bd512388380f..d3ea63552891f 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_first.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_first.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_last.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_last.json index 21d8d669dce7c..cfda34ed79bc6 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_last.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_last.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_slice.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_slice.json index 149e309249bd9..c8ed705465b6e 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_slice.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_slice.json @@ -196,6 +196,78 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression. If `null`, the function returns `null`." + }, + { + "name" : "start", + "type" : "integer", + "optional" : false, + "description" : "Start position. If `null`, the function returns `null`. The start argument can be negative. An index of -1 is used to specify the last value in the list." + }, + { + "name" : "end", + "type" : "integer", + "optional" : true, + "description" : "End position(included). Optional; if omitted, the position at `start` is returned. The end argument can be negative. An index of -1 is used to specify the last value in the list." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression. If `null`, the function returns `null`." + }, + { + "name" : "start", + "type" : "integer", + "optional" : false, + "description" : "Start position. If `null`, the function returns `null`. The start argument can be negative. An index of -1 is used to specify the last value in the list." + }, + { + "name" : "end", + "type" : "integer", + "optional" : true, + "description" : "End position(included). Optional; if omitted, the position at `start` is returned. The end argument can be negative. An index of -1 is used to specify the last value in the list." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression. If `null`, the function returns `null`." + }, + { + "name" : "start", + "type" : "integer", + "optional" : false, + "description" : "Start position. If `null`, the function returns `null`. The start argument can be negative. An index of -1 is used to specify the last value in the list." + }, + { + "name" : "end", + "type" : "integer", + "optional" : true, + "description" : "End position(included). Optional; if omitted, the position at `start` is returned. The end argument can be negative. An index of -1 is used to specify the last value in the list." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json index 9e00ced00220e..b36ea8180a4c3 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json @@ -10,13 +10,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -28,13 +28,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -46,13 +46,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -64,13 +64,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -82,13 +82,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -100,13 +100,67 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geohash", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geohex", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geotile", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -118,13 +172,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -136,13 +190,67 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geohash", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geohex", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geotile", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json index 85827c862e741..37a2f486d8f12 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json @@ -2,7 +2,7 @@ "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", "type" : "scalar", "name" : "st_geohash", - "description" : "Calculates the `geohash` of the supplied geo_point at the specified precision.\nThe result is long encoded. Use ST_GEOHASH_TO_STRING to convert the result to a string.\n\nThese functions are related to the `geo_grid` query\nand the `geohash_grid` aggregation.", + "description" : "Calculates the `geohash` of the supplied geo_point at the specified precision.\nThe result is long encoded. Use TO_STRING to convert the result to a string,\nTO_LONG to convert it to a `long`, or TO_GEOSHAPE to calculate\nthe `geo_shape` bounding geometry.\n\nThese functions are related to the `geo_grid` query\nand the `geohash_grid` aggregation.", "signatures" : [ { "params" : [ @@ -15,12 +15,12 @@ { "name" : "precision", "type" : "integer", - "optional" : false, + "optional" : true, "description" : "Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash)." } ], "variadic" : false, - "returnType" : "long" + "returnType" : "geohash" }, { "params" : [ @@ -33,7 +33,7 @@ { "name" : "precision", "type" : "integer", - "optional" : false, + "optional" : true, "description" : "Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash)." }, { @@ -44,11 +44,11 @@ } ], "variadic" : false, - "returnType" : "long" + "returnType" : "geohash" } ], "examples" : [ - "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" + "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" ], "preview" : false, "snapshot_only" : false diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json deleted file mode 100644 index f6b14f780e955..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geohash_to_long", - "description" : "Converts an input value representing a geohash grid-ID in string format into a long.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - } - ], - "examples" : [ - "ROW geohash = \"u3bu\"\n| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json deleted file mode 100644 index d6b55c483ced5..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geohash_to_string", - "description" : "Converts an input value representing a geohash grid-ID in long format into a string.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - } - ], - "examples" : [ - "ROW geohash = TO_LONG(13686180)\n| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json index 998a5f27921fa..fec0068fe3462 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json @@ -3,7 +3,7 @@ "type" : "scalar", "name" : "st_geohex", "license" : "PLATINUM", - "description" : "Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision.\nThe result is long encoded. Use ST_GEOHEX_TO_STRING to convert the result to a string.\n\nThese functions are related to the `geo_grid` query\nand the `geohex_grid` aggregation.", + "description" : "Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision.\nThe result is long encoded. Use TO_STRING to convert the result to a string,\nTO_LONG to convert it to a `long`, or TO_GEOSHAPE to calculate\nthe `geo_shape` bounding geometry.\n\nThese functions are related to the `geo_grid` query\nand the `geohex_grid` aggregation.", "signatures" : [ { "params" : [ @@ -22,7 +22,7 @@ ], "license" : "PLATINUM", "variadic" : false, - "returnType" : "long" + "returnType" : "geohex" }, { "params" : [ @@ -47,11 +47,11 @@ ], "license" : "PLATINUM", "variadic" : false, - "returnType" : "long" + "returnType" : "geohex" } ], "examples" : [ - "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" + "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" ], "preview" : false, "snapshot_only" : false diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json deleted file mode 100644 index 474c4f63ea8a6..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geohex_to_long", - "description" : "Converts an input value representing a geohex grid-ID in string format into a long.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input geohex grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input geohex grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - } - ], - "examples" : [ - "ROW geohex = \"841f059ffffffff\"\n| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json deleted file mode 100644 index 0d83038db609e..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geohex_to_string", - "description" : "Converts an input value representing a Geohex grid-ID in long format into a string.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input Geohex grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input Geohex grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - } - ], - "examples" : [ - "ROW geohex = 595020895127339007\n| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json index 09feed6845f24..2a7f872dfb978 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json @@ -2,7 +2,7 @@ "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", "type" : "scalar", "name" : "st_geotile", - "description" : "Calculates the `geotile` of the supplied geo_point at the specified precision.\nThe result is long encoded. Use ST_GEOTILE_TO_STRING to convert the result to a string.\n\nThese functions are related to the `geo_grid` query\nand the `geotile_grid` aggregation.", + "description" : "Calculates the `geotile` of the supplied geo_point at the specified precision.\nThe result is long encoded. Use TO_STRING to convert the result to a string,\nTO_LONG to convert it to a `long`, or TO_GEOSHAPE to calculate\nthe `geo_shape` bounding geometry.\n\nThese functions are related to the `geo_grid` query\nand the `geotile_grid` aggregation.", "signatures" : [ { "params" : [ @@ -20,7 +20,7 @@ } ], "variadic" : false, - "returnType" : "long" + "returnType" : "geotile" }, { "params" : [ @@ -44,11 +44,11 @@ } ], "variadic" : false, - "returnType" : "long" + "returnType" : "geotile" } ], "examples" : [ - "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" + "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" ], "preview" : false, "snapshot_only" : false diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json deleted file mode 100644 index e2aefafa33fdc..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geotile_to_long", - "description" : "Converts an input value representing a geotile grid-ID in string format into a long.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "long" - } - ], - "examples" : [ - "ROW geotile = \"4/8/5\"\n| EVAL geotileLong = ST_GEOTILE_TO_LONG(geotile)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json deleted file mode 100644 index effe374bab93c..0000000000000 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", - "type" : "scalar", - "name" : "st_geotile_to_string", - "description" : "Converts an input value representing a geotile grid-ID in long format into a string.", - "signatures" : [ - { - "params" : [ - { - "name" : "grid_id", - "type" : "keyword", - "optional" : false, - "description" : "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - }, - { - "params" : [ - { - "name" : "grid_id", - "type" : "long", - "optional" : false, - "description" : "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - } - ], - "variadic" : false, - "returnType" : "keyword" - } - ], - "examples" : [ - "ROW geotile = 1152921508901814277\n| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile)" - ], - "preview" : false, - "snapshot_only" : false -} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json index 6b7d5e844b42a..f5e2a2faf8e93 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json @@ -10,13 +10,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -28,13 +28,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -46,13 +46,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -64,13 +64,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -82,13 +82,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -100,13 +100,67 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geohash", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geohex", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geotile", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -118,13 +172,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -136,13 +190,67 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geohash", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geohex", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "geomA", + "type" : "geotile", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + }, + { + "name" : "geomB", + "type" : "geo_point", + "optional" : false, + "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geoshape.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geoshape.json index bfc6f6c2d437f..5c238d6c7f010 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_geoshape.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geoshape.json @@ -28,6 +28,42 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geo_shape" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geo_shape" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geo_shape" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_long.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_long.json index 05b2682bb364a..7e133cbef238a 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_long.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_long.json @@ -76,6 +76,42 @@ "variadic" : false, "returnType" : "long" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "long" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_string.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_string.json index 4dccefb59c436..87e1e40074e7c 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_string.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_string.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "keyword" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/values.json b/docs/reference/query-languages/esql/kibana/definition/functions/values.json index 6ee883d6fd280..a4db9139d612b 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/values.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/values.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/equals.json b/docs/reference/query-languages/esql/kibana/definition/operators/equals.json index a77e8574f72d7..6fc8242f9a8b4 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/equals.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/equals.json @@ -222,6 +222,60 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geohash", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geohash", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geohex", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geohex", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geotile", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geotile", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json b/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json index 385d375853683..1ffd18abf14c0 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json @@ -101,6 +101,42 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json b/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json index e1411c65ef3f4..4b98b70ffa1d2 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json @@ -101,6 +101,42 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/not_equals.json b/docs/reference/query-languages/esql/kibana/definition/operators/not_equals.json index de839329765bf..ccbade1486d67 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/not_equals.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/not_equals.json @@ -222,6 +222,60 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geohash", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geohash", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geohex", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geohex", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "lhs", + "type" : "geotile", + "optional" : false, + "description" : "An expression." + }, + { + "name" : "rhs", + "type" : "geotile", + "optional" : false, + "description" : "An expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/predicates.json b/docs/reference/query-languages/esql/kibana/definition/operators/predicates.json index db08e7acc0094..4a429ad68e712 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/predicates.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/predicates.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md index 30a8a13049f21..3752dd81fe9a4 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md @@ -2,7 +2,9 @@ ### ST GEOHASH Calculates the `geohash` of the supplied geo_point at the specified precision. -The result is long encoded. Use [ST_GEOHASH_TO_STRING](#esql-st_geohash_to_string) to convert the result to a string. +The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, +[TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate +the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geohash_grid` aggregation](https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation). @@ -15,7 +17,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL geohashString = TO_STRING(geohash) | KEEP count, centroid, geohashString | SORT count DESC, geohashString ASC ``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md deleted file mode 100644 index f949358288160..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOHASH TO LONG -Converts an input value representing a geohash grid-ID in string format into a long. - -```esql -ROW geohash = "u3bu" -| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash) -``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md deleted file mode 100644 index fbd7dbd3d4d0a..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOHASH TO STRING -Converts an input value representing a geohash grid-ID in long format into a string. - -```esql -ROW geohash = TO_LONG(13686180) -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md index e5b9bf818dfdd..fba6e9319aa63 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md @@ -2,7 +2,9 @@ ### ST GEOHEX Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision. -The result is long encoded. Use [ST_GEOHEX_TO_STRING](#esql-st_geohex_to_string) to convert the result to a string. +The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, +[TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate +the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geohex_grid` aggregation](https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation). @@ -15,7 +17,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) | KEEP count, centroid, geohexString | SORT count DESC, geohexString ASC ``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md deleted file mode 100644 index 393cde5be1e99..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOHEX TO LONG -Converts an input value representing a geohex grid-ID in string format into a long. - -```esql -ROW geohex = "841f059ffffffff" -| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex) -``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md deleted file mode 100644 index ba06c681d5af3..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOHEX TO STRING -Converts an input value representing a Geohex grid-ID in long format into a string. - -```esql -ROW geohex = 595020895127339007 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md index 6097cab00c96c..34a291cd28e9c 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md @@ -2,7 +2,9 @@ ### ST GEOTILE Calculates the `geotile` of the supplied geo_point at the specified precision. -The result is long encoded. Use [ST_GEOTILE_TO_STRING](#esql-st_geotile_to_string) to convert the result to a string. +The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, +[TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate +the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geotile_grid` aggregation](https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation). @@ -14,7 +16,7 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) | SORT count DESC, geotileString ASC | KEEP count, centroid, geotileString ``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md deleted file mode 100644 index 75f42b84ae03e..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOTILE TO LONG -Converts an input value representing a geotile grid-ID in string format into a long. - -```esql -ROW geotile = "4/8/5" -| EVAL geotileLong = ST_GEOTILE_TO_LONG(geotile) -``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md deleted file mode 100644 index 620047aa7ccc2..0000000000000 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md +++ /dev/null @@ -1,9 +0,0 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. - -### ST GEOTILE TO STRING -Converts an input value representing a geotile grid-ID in long format into a string. - -```esql -ROW geotile = 1152921508901814277 -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) -``` diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java index bde8af3c4e6d1..7e1b7eb5bad25 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java @@ -276,6 +276,9 @@ public enum DataType { // wild estimate for size, based on some test data (airport_city_boundaries) CARTESIAN_SHAPE(builder().esType("cartesian_shape").estimatedSize(200).docValues()), GEO_SHAPE(builder().esType("geo_shape").estimatedSize(200).docValues()), + GEOHASH(builder().esType("geohash").typeName("GEOHASH").estimatedSize(Long.BYTES)), + GEOTILE(builder().esType("geotile").typeName("GEOTILE").estimatedSize(Long.BYTES)), + GEOHEX(builder().esType("geohex").typeName("GEOHEX").estimatedSize(Long.BYTES)), /** * Fields with this type represent a Lucene doc id. This field is a bit magic in that: @@ -567,19 +570,33 @@ public static boolean isSpatialPoint(DataType t) { } public static boolean isSpatialShape(DataType t) { - return t == GEO_SHAPE || t == CARTESIAN_SHAPE; + return t == GEO_SHAPE || t == CARTESIAN_SHAPE || t == GEOHASH || t == GEOTILE || t == GEOHEX; } public static boolean isSpatialGeo(DataType t) { - return t == GEO_POINT || t == GEO_SHAPE; + return t == GEO_POINT || t == GEO_SHAPE || t == GEOHASH || t == GEOTILE || t == GEOHEX; } public static boolean isSpatial(DataType t) { return t == GEO_POINT || t == CARTESIAN_POINT || t == GEO_SHAPE || t == CARTESIAN_SHAPE; } + public static boolean isSpatialAndGrid(DataType t) { + return t == GEO_POINT + || t == CARTESIAN_POINT + || t == GEO_SHAPE + || t == CARTESIAN_SHAPE + || t == GEOHASH + || t == GEOTILE + || t == GEOHEX; + } + + public static boolean isGeoGrid(DataType t) { + return t == GEOHASH || t == GEOTILE || t == GEOHEX; + } + public static boolean isSortable(DataType t) { - return false == (t == SOURCE || isCounter(t) || isSpatial(t) || t == AGGREGATE_METRIC_DOUBLE); + return false == (t == SOURCE || isCounter(t) || isSpatialAndGrid(t) || t == AGGREGATE_METRIC_DOUBLE); } public String nameUpper() { diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java index cac61d9acd434..05d6b08b61ff2 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java @@ -12,8 +12,11 @@ import org.elasticsearch.common.time.DateFormatter; import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder; import org.elasticsearch.compute.data.Page; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.logging.Logger; import org.elasticsearch.search.DocValueFormat; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.ListMatcher; import org.elasticsearch.xpack.esql.CsvTestUtils.ActualResults; import org.elasticsearch.xpack.versionfield.Version; @@ -135,6 +138,9 @@ private static void assertMetadata( || expectedType == Type.DATE_NANOS || expectedType == Type.GEO_POINT || expectedType == Type.CARTESIAN_POINT + || expectedType == Type.GEOHASH + || expectedType == Type.GEOTILE + || expectedType == Type.GEOHEX || expectedType == UNSIGNED_LONG)) { continue; } @@ -412,6 +418,9 @@ private static Object convertExpectedValue(Type expectedType, Object expectedVal BytesRef.class, x -> CARTESIAN.wkbToWkt((BytesRef) x) ); + case Type.GEOHASH -> rebuildExpected(expectedValue, Long.class, x -> Geohash.stringEncode((long) x)); + case Type.GEOTILE -> rebuildExpected(expectedValue, Long.class, x -> GeoTileUtils.stringEncode((long) x)); + case Type.GEOHEX -> rebuildExpected(expectedValue, Long.class, x -> H3.h3ToString((long) x)); case Type.IP -> // convert BytesRef-packed IP to String, allowing subsequent comparison with what's expected rebuildExpected(expectedValue, BytesRef.class, x -> DocValueFormat.IP.format((BytesRef) x)); case Type.VERSION -> // convert BytesRef-packed Version to String diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java index 3a6f623c6dec1..d5b359d4f79a9 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java @@ -27,7 +27,10 @@ import org.elasticsearch.core.Releasables; import org.elasticsearch.core.Strings; import org.elasticsearch.core.Tuple; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.logging.Logger; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.VersionUtils; import org.elasticsearch.xpack.esql.action.ResponseValueUtils; import org.elasticsearch.xpack.esql.core.type.DataType; @@ -487,6 +490,11 @@ public enum Type { CARTESIAN_POINT(x -> x == null ? null : CARTESIAN.wktToWkb(x), BytesRef.class), GEO_SHAPE(x -> x == null ? null : GEO.wktToWkb(x), BytesRef.class), CARTESIAN_SHAPE(x -> x == null ? null : CARTESIAN.wktToWkb(x), BytesRef.class), + GEOHASH(x -> x == null ? null : Geohash.longEncode(x), Long.class), + GEOTILE(x -> x == null ? null : GeoTileUtils.longEncode(x), (l, r) -> { + return 0; + }, Long.class), + GEOHEX(x -> x == null ? null : H3.stringToH3(x), Long.class), AGGREGATE_METRIC_DOUBLE( x -> x == null ? null : stringToAggregateMetricDoubleLiteral(x), AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral.class diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java index 7b5843704eac8..9f85f1aba1afe 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java @@ -37,9 +37,12 @@ import org.elasticsearch.core.Tuple; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.index.IndexMode; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.search.SearchService; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.tasks.TaskCancelledException; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.RemoteTransportException; @@ -64,6 +67,9 @@ import org.elasticsearch.xpack.esql.core.util.DateUtils; import org.elasticsearch.xpack.esql.core.util.StringUtils; import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile; import org.elasticsearch.xpack.esql.expression.function.scalar.string.regex.RLike; import org.elasticsearch.xpack.esql.expression.function.scalar.string.regex.WildcardLike; import org.elasticsearch.xpack.esql.expression.predicate.Range; @@ -824,6 +830,15 @@ public static Literal randomLiteral(DataType type) { case CARTESIAN_POINT -> CARTESIAN.asWkb(ShapeTestUtils.randomPoint()); case GEO_SHAPE -> GEO.asWkb(GeometryTestUtils.randomGeometry(randomBoolean())); case CARTESIAN_SHAPE -> CARTESIAN.asWkb(ShapeTestUtils.randomGeometry(randomBoolean())); + case GEOHASH -> StGeohash.unboundedGrid.calculateGridId( + GeometryTestUtils.randomPoint(), + randomIntBetween(1, Geohash.PRECISION) + ); + case GEOTILE -> StGeotile.unboundedGrid.calculateGridId( + GeometryTestUtils.randomPoint(), + randomIntBetween(0, GeoTileUtils.MAX_ZOOM) + ); + case GEOHEX -> StGeohex.unboundedGrid.calculateGridId(GeometryTestUtils.randomPoint(), randomIntBetween(0, H3.MAX_H3_RES)); case AGGREGATE_METRIC_DOUBLE -> new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral( randomDouble(), randomDouble(), diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index a694f0ca48afe..9279c58019e1d 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -2,27 +2,43 @@ # Tests for geo_grid function: ST_GEOHASH ############################################### -geohashStringToLong +toGeohash required_capability: spatial_grid -// tag::geohash_to_long[] -ROW geohash = "u3bu" -| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash) -// end::geohash_to_long[] +// tag::to_geohash[] +ROW string = "u3bu" +| EVAL geohash = TO_GEOHASH(string) +// end::to_geohash[] ; -// tag::geohash_to_long-result[] -geohash:keyword | geohashLong:long -u3bu | 13686180 -// end::geohash_to_long-result[] +// tag::to_geohash-result[] +string:keyword | geohash:geohash +u3bu | u3bu +// end::to_geohash-result[] +; + +toGeohashToLong +required_capability: spatial_grid + +// tag::to_geohash_to_long[] +ROW string = "u3bu" +| EVAL geohash = TO_GEOHASH(string) +| EVAL geohashLong = TO_LONG(geohash) +// end::to_geohash_to_long[] +; + +// tag::to_geohash_to_long-result[] +string:keyword | geohash:geohash | geohashLong:long +u3bu | u3bu | 13686180 +// end::to_geohash_to_long-result[] ; geohashLongToString required_capability: spatial_grid // tag::geohash_to_string[] -ROW geohash = TO_LONG(13686180) -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +ROW geohash = 13686180::long +| EVAL geohashString = TO_STRING(TO_GEOHASH(geohash)) // end::geohash_to_string[] ; @@ -32,50 +48,89 @@ geohash:long | geohashString:keyword // end::geohash_to_string-result[] ; +geohashStringToGeoShape +required_capability: spatial_grid + +// tag::geohash_to_geoshape[] +ROW hash = "u3bu" +| EVAL boundary = TO_GEOSHAPE(TO_GEOHASH(hash)) +// end::geohash_to_geoshape[] +; + +// tag::geohash_to_geoshape-result[] +hash:keyword | boundary:geo_shape +u3bu | POLYGON((12.3046875 55.546875, 12.65625 55.546875, 12.65625 55.72265625, 12.3046875 55.72265625, 12.3046875 55.546875)) +// end::geohash_to_geoshape-result[] +; + +geohashLongToGeoShape +required_capability: spatial_grid + +ROW hash = TO_LONG(13686180) +| EVAL boundary = TO_GEOSHAPE(TO_GEOHASH(hash)) +; + +hash:long | boundary:geo_shape +13686180 | POLYGON((12.3046875 55.546875, 12.65625 55.546875, 12.65625 55.72265625, 12.3046875 55.72265625, 12.3046875 55.546875)) +; + geohashLiteral required_capability: spatial_grid -// tag::st_geohash-literal[] +// tag::to_geohash_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohash4 = ST_GEOHASH(location, 4), geohash3 = ST_GEOHASH(location, 3), geohash2 = ST_GEOHASH(location, 2), geohash1 = ST_GEOHASH(location, 1) -// end::st_geohash-literal[] +// end::to_geohash_literal[] ; -// tag::st_geohash-literal-result[] -location:geo_point | geohash4:long | geohash3:long | geohash2:long | geohash1:long -POINT (12.6493508684508 55.6285017221528) | 13686180 | 427683 | 13362 | 417 -// end::st_geohash-literal-result[] +// tag::to_geohash_literal-result[] +location:geo_point | geohash4:geohash | geohash3:geohash | geohash2:geohash | geohash1:geohash +POINT(12.6493508684508 55.6285017221528) | u3bu | u3b | u3 | u +// end::to_geohash_literal-result[] ; geohashLiteralString required_capability: spatial_grid ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") -| EVAL geohash4 = ST_GEOHASH_TO_STRING(ST_GEOHASH(location, 4)), - geohash3 = ST_GEOHASH_TO_STRING(ST_GEOHASH(location, 3)), - geohash2 = ST_GEOHASH_TO_STRING(ST_GEOHASH(location, 2)), - geohash1 = ST_GEOHASH_TO_STRING(ST_GEOHASH(location, 1)) +| EVAL geohash4 = TO_STRING(ST_GEOHASH(location, 4)), + geohash3 = TO_STRING(ST_GEOHASH(location, 3)), + geohash2 = TO_STRING(ST_GEOHASH(location, 2)), + geohash1 = TO_STRING(ST_GEOHASH(location, 1)) ; location:geo_point | geohash4:keyword | geohash3:keyword | geohash2:keyword | geohash1:keyword POINT(12.6493508684508 55.6285017221528) | u3bu | u3b | u3 | u ; +geohashLiteralLong +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geohash4 = TO_LONG(ST_GEOHASH(location, 4)), + geohash3 = TO_LONG(ST_GEOHASH(location, 3)), + geohash2 = TO_LONG(ST_GEOHASH(location, 2)), + geohash1 = TO_LONG(ST_GEOHASH(location, 1)) +; + +location:geo_point | geohash4:long | geohash3:long | geohash2:long | geohash1:long +POINT (12.6493508684508 55.6285017221528) | 13686180 | 427683 | 13362 | 417 +; + geohashField required_capability: spatial_grid FROM airports | WHERE abbrev == "CPH" | EVAL geohash = ST_GEOHASH(location, 7) -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -| KEEP geohash, geohashString, abbrev, name, location +| KEEP geohash, abbrev, name, location ; -geohash:long | geohashString:keyword | abbrev:keyword | name:text | location:geo_point -448469007591 | u3buryf | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +geohash:geohash | abbrev:keyword | name:text | location:geo_point +u3buryf | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) ; gridGeohashStatsBy @@ -89,7 +144,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL geohashString = TO_STRING(geohash) | KEEP count, centroid, geohashString | SORT count DESC, geohashString ASC // end::st_geohash-grid[] @@ -121,13 +176,13 @@ gridGeohashQuery required_capability: spatial_grid FROM airports -| WHERE ST_GEOHASH(location, 1) == ST_GEOHASH_TO_LONG("7") +| WHERE ST_GEOHASH(location, 1) == TO_GEOHASH("7") | EVAL geohash = ST_GEOHASH(location, 2) | STATS count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohash -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL geohashString = TO_STRING(geohash) | KEEP count, centroid, geohashString | SORT count DESC, geohashString ASC ; @@ -150,23 +205,24 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohash -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -| KEEP count, centroid, geohashString +| EVAL geohashString = TO_STRING(geohash) +| EVAL cellBoundary = TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary | SORT count DESC, geohashString ASC ; -count:long | centroid:geo_point | geohashString:keyword -19 | POINT (6.360728044651057 47.94084087577894) | u0 -10 | POINT (15.350638423115015 47.80751353036612) | u2 -9 | POINT (18.5217544157058 42.1394603792578) | sr -8 | POINT (6.351574736181647 51.8981519783847) | u1 -7 | POINT (5.268637698941997 42.747250193330856) | sp -7 | POINT (17.092350951528974 53.365471504096476) | u3 -5 | POINT (16.2651440910995 58.812188878655434) | u6 -4 | POINT (7.7012718468904495 36.39783004182391) | sn -3 | POINT (14.222751930356026 37.168446206487715) | sq -3 | POINT (7.318722177296877 59.788265260867774) | u4 -2 | POINT (16.706149326637387 32.37822346854955) | sm +count:long | centroid:geo_point | geohashString:keyword | cellBoundary:geo_shape +19 | POINT (6.360728044651057 47.94084087577894) | u0 | POLYGON((0.0 45.0, 11.25 45.0, 11.25 50.625, 0.0 50.625, 0.0 45.0)) +10 | POINT (15.350638423115015 47.80751353036612) | u2 | POLYGON((11.25 45.0, 22.5 45.0, 22.5 50.625, 11.25 50.625, 11.25 45.0)) +9 | POINT (18.5217544157058 42.1394603792578) | sr | POLYGON((11.25 39.375, 22.5 39.375, 22.5 45.0, 11.25 45.0, 11.25 39.375)) +8 | POINT (6.351574736181647 51.8981519783847) | u1 | POLYGON((0.0 50.625, 11.25 50.625, 11.25 56.25, 0.0 56.25, 0.0 50.625)) +7 | POINT (5.268637698941997 42.747250193330856) | sp | POLYGON((0.0 39.375, 11.25 39.375, 11.25 45.0, 0.0 45.0, 0.0 39.375)) +7 | POINT (17.092350951528974 53.365471504096476) | u3 | POLYGON((11.25 50.625, 22.5 50.625, 22.5 56.25, 11.25 56.25, 11.25 50.625)) +5 | POINT (16.2651440910995 58.812188878655434) | u6 | POLYGON((11.25 56.25, 22.5 56.25, 22.5 61.875, 11.25 61.875, 11.25 56.25)) +4 | POINT (7.7012718468904495 36.39783004182391) | sn | POLYGON((0.0 33.75, 11.25 33.75, 11.25 39.375, 0.0 39.375, 0.0 33.75)) +3 | POINT (14.222751930356026 37.168446206487715) | sq | POLYGON((11.25 33.75, 22.5 33.75, 22.5 39.375, 11.25 39.375, 11.25 33.75)) +3 | POINT (7.318722177296877 59.788265260867774) | u4 | POLYGON((0.0 56.25, 11.25 56.25, 11.25 61.875, 0.0 61.875, 0.0 56.25)) +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)) ; gridGeohashStatsByBoundsEnvelope @@ -179,23 +235,51 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohash -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -| KEEP count, centroid, geohashString +| EVAL geohashString = TO_STRING(geohash) +| EVAL cellBoundary = TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary | SORT count DESC, geohashString ASC ; -count:long | centroid:geo_point | geohashString:keyword -19 | POINT (6.360728044651057 47.94084087577894) | u0 -10 | POINT (15.350638423115015 47.80751353036612) | u2 -9 | POINT (18.5217544157058 42.1394603792578) | sr -8 | POINT (6.351574736181647 51.8981519783847) | u1 -7 | POINT (5.268637698941997 42.747250193330856) | sp -7 | POINT (17.092350951528974 53.365471504096476) | u3 -5 | POINT (16.2651440910995 58.812188878655434) | u6 -4 | POINT (7.7012718468904495 36.39783004182391) | sn -3 | POINT (14.222751930356026 37.168446206487715) | sq -3 | POINT (7.318722177296877 59.788265260867774) | u4 -2 | POINT (16.706149326637387 32.37822346854955) | sm +count:long | centroid:geo_point | geohashString:keyword | cellBoundary:geo_shape +19 | POINT (6.360728044651057 47.94084087577894) | u0 | POLYGON((0.0 45.0, 11.25 45.0, 11.25 50.625, 0.0 50.625, 0.0 45.0)) +10 | POINT (15.350638423115015 47.80751353036612) | u2 | POLYGON((11.25 45.0, 22.5 45.0, 22.5 50.625, 11.25 50.625, 11.25 45.0)) +9 | POINT (18.5217544157058 42.1394603792578) | sr | POLYGON((11.25 39.375, 22.5 39.375, 22.5 45.0, 11.25 45.0, 11.25 39.375)) +8 | POINT (6.351574736181647 51.8981519783847) | u1 | POLYGON((0.0 50.625, 11.25 50.625, 11.25 56.25, 0.0 56.25, 0.0 50.625)) +7 | POINT (5.268637698941997 42.747250193330856) | sp | POLYGON((0.0 39.375, 11.25 39.375, 11.25 45.0, 0.0 45.0, 0.0 39.375)) +7 | POINT (17.092350951528974 53.365471504096476) | u3 | POLYGON((11.25 50.625, 22.5 50.625, 22.5 56.25, 11.25 56.25, 11.25 50.625)) +5 | POINT (16.2651440910995 58.812188878655434) | u6 | POLYGON((11.25 56.25, 22.5 56.25, 22.5 61.875, 11.25 61.875, 11.25 56.25)) +4 | POINT (7.7012718468904495 36.39783004182391) | sn | POLYGON((0.0 33.75, 11.25 33.75, 11.25 39.375, 0.0 39.375, 0.0 33.75)) +3 | POINT (14.222751930356026 37.168446206487715) | sq | POLYGON((11.25 33.75, 22.5 33.75, 22.5 39.375, 11.25 39.375, 11.25 33.75)) +3 | POINT (7.318722177296877 59.788265260867774) | u4 | POLYGON((0.0 56.25, 11.25 56.25, 11.25 61.875, 0.0 61.875, 0.0 56.25)) +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)) +; + +gridGeohashDocsFromCell +required_capability: spatial_grid + +FROM airports +| WHERE ST_INTERSECTS(location, TO_GEOHASH("u1")) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) +; + +count:long | centroid:geo_point +8 | POINT (6.351574736181647 51.8981519783847) +; + +gridGeohashLiteralFromCell +required_capability: spatial_grid + +ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (6.351574736181647 51.8981519783847)", "POINT (5.268637698941997 42.747250193330856)"] +| EVAL location = TO_GEOPOINT(location) +| MV_EXPAND location +| WHERE ST_INTERSECTS(location, TO_GEOHASH("u1")) +; + +location:geo_point +POINT (6.351574736181647 51.8981519783847) ; gridGeohashStatsByWhereUK @@ -208,14 +292,15 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geohash -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -| KEEP count, centroid, geohashString +| EVAL geohashString = TO_STRING(geohash) +| EVAL cellBoundary = TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary | SORT count DESC ; -count:long | centroid:geo_point | geohashString:keyword -14 | POINT (-2.5644131543646966 53.38093495994274) | gc -3 | POINT (-2.7510103583335876 58.79020635969937) | gf +count:long | centroid:geo_point | geohashString:keyword | cellBoundary:geo_shape +14 | POINT (-2.5644131543646966 53.38093495994274) | gc | POLYGON((-11.25 50.625, 0.0 50.625, 0.0 56.25, -11.25 56.25, -11.25 50.625)) +3 | POINT (-2.7510103583335876 58.79020635969937) | gf | POLYGON((-11.25 56.25, 0.0 56.25, 0.0 61.875, -11.25 61.875, -11.25 56.25)) ; gridGeohashStatsByBoundsUK @@ -229,17 +314,18 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geohash -| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) -| KEEP count, centroid, geohashString +| EVAL geohashString = TO_STRING(geohash) +| EVAL cellBoundary = TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary | SORT count DESC, geohashString ASC ; -count:long | centroid:geo_point | geohashString:keyword -19 | POINT (6.360728044651057 47.94084087577894) | u0 -17 | POINT (-3.5034258844440473 53.25306422789307) | gc -8 | POINT (6.351574736181647 51.8981519783847) | u1 -3 | POINT (-2.7510103583335876 58.79020635969937) | gf -3 | POINT (7.318722177296877 59.788265260867774) | u4 +count:long | centroid:geo_point | geohashString:keyword | cellBoundary:geo_shape +19 | POINT (6.360728044651057 47.94084087577894) | u0 | POLYGON((0.0 45.0, 11.25 45.0, 11.25 50.625, 0.0 50.625, 0.0 45.0)) +17 | POINT (-3.5034258844440473 53.25306422789307) | gc | POLYGON((-11.25 50.625, 0.0 50.625, 0.0 56.25, -11.25 56.25, -11.25 50.625)) +8 | POINT (6.351574736181647 51.8981519783847) | u1 | POLYGON((0.0 50.625, 11.25 50.625, 11.25 56.25, 0.0 56.25, 0.0 50.625)) +3 | POINT (-2.7510103583335876 58.79020635969937) | gf | POLYGON((-11.25 56.25, 0.0 56.25, 0.0 61.875, -11.25 61.875, -11.25 56.25)) +3 | POINT (7.318722177296877 59.788265260867774) | u4 | POLYGON((0.0 56.25, 11.25 56.25, 11.25 61.875, 0.0 61.875, 0.0 56.25)) ; gridGeohashInStatsBy @@ -290,19 +376,35 @@ count:long | centroid:geo_point # Tests for geo_grid function: ST_GEOTILE ############################################### -geotileStringToLong +toGeotile +required_capability: spatial_grid + +// tag::to_geotile[] +ROW string = "4/8/5" +| EVAL geotile = TO_GEOTILE(string) +// end::to_geotile[] +; + +// tag::to_geotile-result[] +string:keyword | geotile:geotile +4/8/5 | 4/8/5 +// end::to_geotile-result[] +; + +toGeotileToLong required_capability: spatial_grid -// tag::geotile_to_long[] -ROW geotile = "4/8/5" -| EVAL geotileLong = ST_GEOTILE_TO_LONG(geotile) -// end::geotile_to_long[] +// tag::to_geotile_to_long[] +ROW string = "4/8/5" +| EVAL geotile = TO_GEOTILE(string) +| EVAL geotileLong = TO_LONG(geotile) +// end::to_geotile_to_long[] ; -// tag::geotile_to_long-result[] -geotile:keyword | geotileLong:long -4/8/5 | 1152921508901814277 -// end::geotile_to_long-result[] +// tag::to_geotile_to_long-result[] +string:keyword | geotile:geotile | geotileLong:long +4/8/5 | 4/8/5 | 1152921508901814277 +// end::to_geotile_to_long-result[] ; geotileLongToString @@ -310,7 +412,7 @@ required_capability: spatial_grid // tag::geotile_to_string[] ROW geotile = 1152921508901814277 -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(TO_GEOTILE(geotile)) // end::geotile_to_string[] ; @@ -320,50 +422,78 @@ geotile:long | geotileString:keyword // end::geotile_to_string-result[] ; +geotileStringToGeoshape +required_capability: spatial_grid + +// tag::geotile_to_geoshape[] +ROW tile = "4/8/5" +| EVAL boundary = TO_GEOSHAPE(TO_GEOTILE(tile)) +// end::geotile_to_geoshape[] +; + +// tag::geotile_to_geoshape-result[] +tile:keyword | boundary:geo_shape +4/8/5 | POLYGON((0.0 40.979898069620134, 22.5 40.979898069620134, 22.5 55.77657301866769, 0.0 55.77657301866769, 0.0 40.979898069620134)) +// end::geotile_to_geoshape-result[] +; + geotileLiteral required_capability: spatial_grid -// tag::st_geotile-literal[] +// tag::st_geotile_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geotile4 = ST_GEOTILE(location, 4), geotile3 = ST_GEOTILE(location, 3), geotile2 = ST_GEOTILE(location, 2), geotile1 = ST_GEOTILE(location, 1) -// end::st_geotile-literal[] +// end::st_geotile_literal[] ; -// tag::st_geotile-literal-result[] -location:geo_point | geotile4:long | geotile3:long | geotile2:long | geotile1:long -POINT (12.6493508684508 55.6285017221528) | 1152921508901814277 | 864691130602618882 | 576460753377165313 | 288230376688582656 -// end::st_geotile-literal-result[] +// tag::st_geotile_literal-result[] +location:geo_point | geotile4:geotile | geotile3:geotile | geotile2:geotile | geotile1:geotile +POINT (12.6493508684508 55.6285017221528) | 4/8/5 | 3/4/2 | 2/2/1 | 1/1/0 +// end::st_geotile_literal-result[] ; geotileLiteralString required_capability: spatial_grid ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") -| EVAL geotile4 = ST_GEOTILE_TO_STRING(ST_GEOTILE(location, 4)), - geotile3 = ST_GEOTILE_TO_STRING(ST_GEOTILE(location, 3)), - geotile2 = ST_GEOTILE_TO_STRING(ST_GEOTILE(location, 2)), - geotile1 = ST_GEOTILE_TO_STRING(ST_GEOTILE(location, 1)) +| EVAL geotile4 = TO_STRING(ST_GEOTILE(location, 4)), + geotile3 = TO_STRING(ST_GEOTILE(location, 3)), + geotile2 = TO_STRING(ST_GEOTILE(location, 2)), + geotile1 = TO_STRING(ST_GEOTILE(location, 1)) ; location:geo_point | geotile4:keyword | geotile3:keyword | geotile2:keyword | geotile1:keyword POINT (12.6493508684508 55.6285017221528) | 4/8/5 | 3/4/2 | 2/2/1 | 1/1/0 ; +geotileLiteralLong +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geotile4 = TO_LONG(ST_GEOTILE(location, 4)), + geotile3 = TO_LONG(ST_GEOTILE(location, 3)), + geotile2 = TO_LONG(ST_GEOTILE(location, 2)), + geotile1 = TO_LONG(ST_GEOTILE(location, 1)) +; + +location:geo_point | geotile4:long | geotile3:long | geotile2:long | geotile1:long +POINT (12.6493508684508 55.6285017221528) | 1152921508901814277 | 864691130602618882 | 576460753377165313 | 288230376688582656 +; + geotileField required_capability: spatial_grid FROM airports | WHERE abbrev == "CPH" | EVAL geotile = ST_GEOTILE(location, 7) -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) -| KEEP geotile, geotileString, abbrev, name, location +| KEEP geotile, abbrev, name, location ; -geotile:long | geotileString:keyword | abbrev:keyword | name:text | location:geo_point -2017612669569204264 | 7/68/40 | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +geotile:geotile | abbrev:keyword | name:text | location:geo_point +7/68/40 | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) ; gridGeotileStatsBy @@ -376,7 +506,7 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) | SORT count DESC, geotileString ASC | KEEP count, centroid, geotileString // end::st_geotile-grid[] @@ -402,13 +532,13 @@ gridGeotileQuery required_capability: spatial_grid FROM airports -| WHERE ST_GEOTILE(location, 2) == ST_GEOTILE_TO_LONG("2/0/2") +| WHERE ST_GEOTILE(location, 2) == TO_GEOTILE("2/0/2") | EVAL geotile = ST_GEOTILE(location, 3) | STATS count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) | SORT count DESC, geotileString ASC | KEEP count, centroid, geotileString ; @@ -428,14 +558,15 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) +| EVAL cellBoundary = TO_GEOSHAPE(geotile) | SORT count DESC, geotileString ASC -| KEEP count, centroid, geotileString +| KEEP count, centroid, geotileString, cellBoundary ; -count:long | centroid:geo_point | geotileString:keyword -100 | POINT (18.10569669920951 50.40505832391791) | 3/4/2 -79 | POINT (24.516750878736943 23.93036561181085) | 3/4/3 +count:long | centroid:geo_point | geotileString:keyword | cellBoundary:geo_shape +100 | POINT (18.10569669920951 50.40505832391791) | 3/4/2 | POLYGON((0.0 40.979898069620134, 45.0 40.979898069620134, 45.0 66.51326044311186, 0.0 66.51326044311186, 0.0 40.979898069620134)) +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)) ; gridGeotileStatsByBoundsEnvelope @@ -448,14 +579,42 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL geotileString = TO_STRING(geotile) +| EVAL cellBoundary = TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary | SORT count DESC, geotileString ASC -| KEEP count, centroid, geotileString ; -count:long | centroid:geo_point | geotileString:keyword -100 | POINT (18.10569669920951 50.40505832391791) | 3/4/2 -79 | POINT (24.516750878736943 23.93036561181085) | 3/4/3 +count:long | centroid:geo_point | geotileString:keyword | cellBoundary:geo_shape +100 | POINT (18.10569669920951 50.40505832391791) | 3/4/2 | POLYGON((0.0 40.979898069620134, 45.0 40.979898069620134, 45.0 66.51326044311186, 0.0 66.51326044311186, 0.0 40.979898069620134)) +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)) +; + +gridGeotileDocsFromCell +required_capability: spatial_grid + +FROM airports +| WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3")) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) +; + +count:long | centroid:geo_point +79 | POINT (24.516750878736943 23.93036561181085) +; + +gridGeotileLiteralFromCell +required_capability: spatial_grid + +ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (24.516750878736943 23.93036561181085)", "POINT (5.268637698941997 42.747250193330856)"] +| EVAL location = TO_GEOPOINT(location) +| MV_EXPAND location +| WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3")) +; + +location:geo_point +POINT (24.516750878736943 23.93036561181085) ; gridGeotileStatsByWhereUK @@ -468,14 +627,15 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) -| KEEP count, centroid, geotileString +| EVAL geotileString = TO_STRING(geotile) +| EVAL cellBoundary = TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary | SORT count DESC ; -count:long | centroid:geo_point | geotileString:keyword -12 | POINT (-2.342151787597686 52.9600293841213) | 4/7/5 -5 | POINT (-3.2097987569868565 57.63667118176818) | 4/7/4 +count:long | centroid:geo_point | geotileString:keyword | cellBoundary:geo_shape +12 | POINT (-2.342151787597686 52.9600293841213) | 4/7/5 | POLYGON((-22.5 40.979898069620134, 0.0 40.979898069620134, 0.0 55.77657301866769, -22.5 55.77657301866769, -22.5 40.979898069620134)) +5 | POINT (-3.2097987569868565 57.63667118176818) | 4/7/4 | POLYGON((-22.5 55.77657301866769, 0.0 55.77657301866769, 0.0 66.51326044311186, -22.5 66.51326044311186, -22.5 55.77657301866769)) ; gridGeotileStatsByBoundsUK @@ -489,16 +649,17 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geotile -| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) -| KEEP count, centroid, geotileString +| EVAL geotileString = TO_STRING(geotile) +| EVAL cellBoundary = TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary | SORT count DESC ; -count:long | centroid:geo_point | geotileString:keyword -56 | POINT (10.54233039047436 47.85997457644304) | 4/8/5 -18 | POINT (-3.5578574100509286 51.27018998377025) | 4/7/5 -11 | POINT (14.310833624648778 59.85619530801407) | 4/8/4 -7 | POINT (-6.466632609122565 59.19681839378817) | 4/7/4 +count:long | centroid:geo_point | geotileString:keyword | cellBoundary:geo_shape +56 | POINT (10.54233039047436 47.85997457644304) | 4/8/5 | POLYGON((0.0 40.979898069620134, 22.5 40.979898069620134, 22.5 55.77657301866769, 0.0 55.77657301866769, 0.0 40.979898069620134)) +18 | POINT (-3.5578574100509286 51.27018998377025) | 4/7/5 | POLYGON((-22.5 40.979898069620134, 0.0 40.979898069620134, 0.0 55.77657301866769, -22.5 55.77657301866769, -22.5 40.979898069620134)) +11 | POINT (14.310833624648778 59.85619530801407) | 4/8/4 | POLYGON((0.0 55.77657301866769, 22.5 55.77657301866769, 22.5 66.51326044311186, 0.0 66.51326044311186, 0.0 55.77657301866769)) +7 | POINT (-6.466632609122565 59.19681839378817) | 4/7/4 | POLYGON((-22.5 55.77657301866769, 0.0 55.77657301866769, 0.0 66.51326044311186, -22.5 66.51326044311186, -22.5 55.77657301866769)) ; gridGeotileInStatsBy @@ -542,80 +703,124 @@ count:long | centroid:geo_point # Tests for geo_grid function: ST_GEOHEX ############################################### -geohexStringToLong +toGeohex required_capability: spatial_grid -// tag::geohex_to_long[] -ROW geohex = "841f059ffffffff" -| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex) -// end::geohex_to_long[] +// tag::to_geohex[] +ROW string = "841f059ffffffff" +| EVAL geohex = TO_GEOHEX(string) +// end::to_geohex[] ; -// tag::geohex_to_long-result[] -geohex:keyword | geohexLong:long -841f059ffffffff | 595020895127339007 -// end::geohex_to_long-result[] +// tag::to_geohex-result[] +string:keyword | geohex:geohex +841f059ffffffff | 841f059ffffffff +// end::to_geohex-result[] ; -geohexLongToString +toGeohexToLong required_capability: spatial_grid -// tag::geohex_to_string[] -ROW geohex = 595020895127339007 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -// end::geohex_to_string[] +// tag::to_geohex_to_long[] +ROW string = "841f059ffffffff" +| EVAL geohex = TO_GEOHEX(string) +| EVAL geohexLong = TO_LONG(geohex) +// end::to_geohex_to_long[] ; -// tag::geohex_to_string-result[] -geohex:long | geohexString:keyword +// tag::to_geohex_to_long-result[] +string:keyword | geohex:geohex | geohexLong:long +841f059ffffffff | 841f059ffffffff | 595020895127339007 +// end::to_geohex_to_long-result[] +; + +geohexLongToGeoHex +required_capability: spatial_grid + +// tag::long_to_geohex[] +ROW gridId = 595020895127339007 +| EVAL geohex = TO_GEOHEX(gridId) +// end::long_to_geohex[] +; + +// tag::long_to_geohex-result[] +gridId:long | geohex:geohex 595020895127339007 | 841f059ffffffff -// end::geohex_to_string-result[] +// end::long_to_geohex-result[] +; + +geohexStringToGeoshape +required_capability: spatial_grid + +// tag::geohex_to_geoshape[] +ROW hex = "841f059ffffffff" +| EVAL boundary = TO_GEOSHAPE(TO_GEOHEX(hex)) +// end::geohex_to_geoshape[] +; + +// tag::geohex_to_geoshape-result[] +hex:keyword | boundary:geo_shape +841f059ffffffff | POLYGON ((12.353546327258265 55.80335405461356, 12.2434612967008 55.60502874054935, 12.51733872608954 55.470800201545316, 12.901880149865134 55.53443156197633, 13.014270156228921 55.73262985778208, 12.739822958959069 55.8673267391136, 12.353546327258265 55.80335405461356)) +// end::geohex_to_geoshape-result[] ; geohexLiteral required_capability: spatial_grid -// tag::st_geohex-literal[] +// tag::st_geohex_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohex4 = ST_GEOHEX(location, 4), geohex3 = ST_GEOHEX(location, 3), geohex2 = ST_GEOHEX(location, 2), geohex1 = ST_GEOHEX(location, 1) -// end::st_geohex-literal[] +// end::st_geohex_literal[] ; -// tag::st_geohex-literal-result[] -location:geo_point | geohex4:long | geohex3:long | geohex2:long | geohex1:long -POINT (12.6493508684508 55.6285017221528) | 595020895127339007 | 590517321269772287 | 586013859081355263 | 581514107744681983 -// end::st_geohex-literal-result[] +// tag::st_geohex_literal-result[] +location:geo_point | geohex4:geohex | geohex3:geohex | geohex2:geohex | geohex1:geohex +POINT (12.6493508684508 55.6285017221528) | 841f059ffffffff | 831f05fffffffff | 821f07fffffffff | 811f3ffffffffff +// end::st_geohex_literal-result[] ; geohexLiteralString required_capability: spatial_grid ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") -| EVAL geohex4 = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 4)), - geohex3 = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 3)), - geohex2 = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 2)), - geohex1 = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 1)) +| EVAL geohex4 = TO_STRING(ST_GEOHEX(location, 4)), + geohex3 = TO_STRING(ST_GEOHEX(location, 3)), + geohex2 = TO_STRING(ST_GEOHEX(location, 2)), + geohex1 = TO_STRING(ST_GEOHEX(location, 1)) ; location:geo_point | geohex4:keyword | geohex3:keyword | geohex2:keyword | geohex1:keyword POINT (12.6493508684508 55.6285017221528) | 841f059ffffffff | 831f05fffffffff | 821f07fffffffff | 811f3ffffffffff ; +geohexLiteralLong +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geohex4 = TO_LONG(ST_GEOHEX(location, 4)), + geohex3 = TO_LONG(ST_GEOHEX(location, 3)), + geohex2 = TO_LONG(ST_GEOHEX(location, 2)), + geohex1 = TO_LONG(ST_GEOHEX(location, 1)) +; + +location:geo_point | geohex4:long | geohex3:long | geohex2:long | geohex1:long +POINT (12.6493508684508 55.6285017221528) | 595020895127339007 | 590517321269772287 | 586013859081355263 | 581514107744681983 +; + geohexField required_capability: spatial_grid FROM airports | WHERE abbrev == "CPH" | EVAL geohex = ST_GEOHEX(location, 7) -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -| KEEP geohex, geohexString, abbrev, name, location +| KEEP geohex, abbrev, name, location ; -geohex:long | geohexString:keyword | abbrev:keyword | name:text | location:geo_point -608531685838946303 | 871f05818ffffff | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +geohex:geohex | abbrev:keyword | name:text | location:geo_point +871f05818ffffff | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) ; gridGeohexStatsBy @@ -629,7 +834,7 @@ FROM airports centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) | KEEP count, centroid, geohexString | SORT count DESC, geohexString ASC // end::st_geohex-grid[] @@ -655,13 +860,13 @@ gridGeohexQuery required_capability: spatial_grid FROM airports -| WHERE ST_GEOHEX(location, 1) == ST_GEOHEX_TO_LONG("812bbffffffffff") +| WHERE ST_GEOHEX(location, 1) == TO_GEOHEX("812bbffffffffff") | EVAL geohex = ST_GEOHEX(location, 2) | STATS count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohex -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) | KEEP count, centroid, geohexString | SORT count DESC, geohexString ASC ; @@ -685,23 +890,24 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohex -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) +| EVAL cellBoundary = TO_GEOSHAPE(geohex) | SORT count DESC, geohexString ASC -| KEEP count, centroid, geohexString +| KEEP count, centroid, geohexString, cellBoundary ; -count:long | centroid:geo_point | geohexString:keyword -22 | POINT (7.250850197689777 48.21363834643059) | 811fbffffffffff -17 | POINT (-0.7606179875266903 52.86413913565304) | 81197ffffffffff -7 | POINT (2.475211258445467 41.32352174592337) | 81397ffffffffff -6 | POINT (11.75047050230205 42.351422344800085) | 811ebffffffffff -5 | POINT (18.766171680763364 59.15833930950612) | 8108bffffffffff -5 | POINT (11.404999259859324 54.510593589395285) | 811f3ffffffffff -4 | POINT (5.167026452254504 59.81037143385038) | 8109bffffffffff -4 | POINT (-1.1871178611181676 35.77457194332965) | 81383ffffffffff -3 | POINT (-1.1497433669865131 45.83295159973204) | 81187ffffffffff -3 | POINT (9.197671310976148 36.29719984252006) | 81387ffffffffff -1 | POINT (13.144258903339505 32.66916951164603) | 813fbffffffffff +count:long | centroid:geo_point | geohexString:keyword | cellBoundary:geo_shape +22 | POINT (7.250850197689777 48.21363834643059) | 811fbffffffffff | POLYGON ((1.1885095534434493 49.47027919866873, 2.026568965384636 45.18424868970643, 7.509948481928886 43.786609353945, 12.677317810359858 46.40695745798227, 12.345747364400065 50.55427508726938, 6.259687055981993 51.96477015603749, 3.6300086390995467 50.6104633125695, 1.1885095534434493 49.47027919866873)) +17 | POINT (-0.7606179875266903 52.86413913565304) | 81197ffffffffff | POLYGON ((-0.9315871635106163 57.689497374592854, -6.436337296790312 55.3773904155485, -4.889760342933795 51.22372845966177, 1.1885095534434493 49.47027919866873, 3.6300086390995365 50.610463312569514, 6.259687055981993 51.96477015603749, 5.523646549290304 55.70676846515228, -0.9315871635106163 57.689497374592854)) +7 | POINT (2.475211258445467 41.32352174592337) | 81397ffffffffff | POLYGON ((-2.4177958307002347 42.54047996565121, -1.416234262837718 38.1159967227654, 0.2387159546288331 37.58884624349159, 3.543589356987798 36.59789814478598, 8.045142114241353 39.40213636897177, 7.509948481928886 43.786609353945, 2.026568965384636 45.18424868970643, -2.4177958307002347 42.54047996565121)) +6 | POINT (11.75047050230205 42.351422344800085) | 811ebffffffffff | POLYGON ((7.509948481928886 43.786609353945, 8.045142114241353 39.40213636897177, 13.244313475659823 37.5237123657852, 18.325260281104846 39.988177963363235, 18.314740441319 44.47067958889503, 12.677317810359858 46.40695745798227, 7.509948481928886 43.786609353945)) +5 | POINT (18.766171680763364 59.15833930950612) | 8108bffffffffff | POLYGON ((11.080660058482376 61.54051460002519, 11.555977692900722 58.13053116585142, 18.2752359517578 56.63295271905082, 25.082722326707877 58.4015448703527, 24.517172437523495 62.47811345192472, 17.53544630840839 63.800792653212156, 15.771773841154092 62.88996835796253, 11.080660058482376 61.54051460002519)) +5 | POINT (11.404999259859324 54.510593589395285) | 811f3ffffffffff | POLYGON ((5.523646549290313 55.70676846515226, 6.259687055981993 51.96477015603749, 12.345747364400065 50.55427508726938, 18.289963485942284 52.81905199947076, 18.2752359517578 56.63295271905082, 11.555977692900722 58.13053116585142, 5.523646549290313 55.70676846515226)) +4 | POINT (5.167026452254504 59.81037143385038) | 8109bffffffffff | POLYGON ((4.012620898449951 63.32706132801842, -2.297526087621831 61.54550957788076, -0.9315871635106163 57.689497374592854, 5.523646549290304 55.70676846515228, 11.555977692900722 58.13053116585142, 11.080660058482376 61.54051460002519, 8.644221197607186 61.8908384753262, 4.012620898449951 63.32706132801842)) +4 | POINT (-1.1871178611181676 35.77457194332965) | 81383ffffffffff | POLYGON ((-5.442348460730093 35.12442405176796, -4.341769247156951 30.69897412778907, -1.2408020165138167 29.828776159725596, 0.26094682603113584 29.300374659234986, 4.204173995672654 32.11010693139568, 3.543589356987798 36.59789814478598, 0.2387159546288331 37.58884624349159, -1.416234262837718 38.1159967227654, -5.442348460730093 35.12442405176796)) +3 | POINT (-1.1497433669865131 45.83295159973204) | 81187ffffffffff | POLYGON ((-4.889760342933795 51.22372845966177, -9.724736207832692 48.43009421958323, -8.101589192291552 44.0506310521871, -2.4177958307002347 42.54047996565121, 2.026568965384605 45.18424868970644, 1.1885095534434493 49.47027919866873, -4.889760342933795 51.22372845966177)) +3 | POINT (9.197671310976148 36.29719984252006) | 81387ffffffffff | POLYGON ((3.543589356987798 36.59789814478598, 4.204173995672654 32.11010693139568, 8.974635637589913 30.254840780701706, 13.488580338198277 32.87501547725471, 13.244313475659823 37.5237123657852, 8.045142114241353 39.40213636897177, 3.543589356987798 36.59789814478598)) +1 | POINT (13.144258903339505 32.66916951164603) | 813fbffffffffff | POLYGON ((8.974635637589913 30.254840780701706, 9.380676605201614 25.60370257696876, 13.915183885634578 23.45043771532035, 18.351304577591982 25.86678026136113, 18.343416368196834 30.62734805513404, 13.488580338198277 32.87501547725471, 8.974635637589913 30.254840780701706)) ; gridGeohexStatsByBoundsEnvelope @@ -714,7 +920,7 @@ FROM airports count = COUNT(*), centroid = ST_CENTROID_AGG(location) BY geohex -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL geohexString = TO_STRING(geohex) | SORT count DESC, geohexString ASC | KEEP count, centroid, geohexString ; @@ -738,8 +944,8 @@ required_capability: spatial_grid FROM airports | EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) -| WHERE ST_GEOHEX_TO_STRING(geohex) == "8108bffffffffff" -| EVAL geohexString = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, 1)) +| WHERE TO_STRING(geohex) == "8108bffffffffff" +| EVAL geohexString = TO_STRING(ST_GEOHEX(location, 1)) | KEEP abbrev, location, geohexString | SORT abbrev ASC ; @@ -758,15 +964,14 @@ required_capability: spatial_grid FROM airports | WHERE abbrev IN ("RTW", "TIP", "XMN") | EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -| KEEP abbrev, location, geohex, geohexString +| KEEP abbrev, location, geohex | SORT abbrev ASC ; -abbrev:keyword | location:geo_point | geohex:long | geohexString:keyword -RTW | POINT (46.035023249891 51.5606456508842) | null | null -TIP | POINT (13.1442589810713 32.6691695504993) | 582085853791125503 | 813fbffffffffff -XMN | POINT (118.12696884672 24.537192570557) | null | null +abbrev:keyword | location:geo_point | geohex:geohex +RTW | POINT (46.035023249891 51.5606456508842) | null +TIP | POINT (13.1442589810713 32.6691695504993) | 813fbffffffffff +XMN | POINT (118.12696884672 24.537192570557) | null ; literalGridGeohexByBounds @@ -777,16 +982,44 @@ ROW location = ["POINT (46.035023249891 51.5606456508842)", "POINT (13.144258981 | EVAL location = TO_GEOPOINT(location) | EVAL geohex = ST_GEOHEX(location, 1) | EVAL geohexBounded = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) -| EVAL geohex = ST_GEOHEX_TO_STRING(geohex) -| EVAL geohexBounded = ST_GEOHEX_TO_STRING(geohexBounded) -| KEEP location, geohex, geohexBounded +| EVAL geohexShape = TO_GEOSHAPE(geohex) +| EVAL geohex = TO_STRING(geohex) +| KEEP location, geohex, geohexBounded, geohexShape | SORT geohex ASC ; -location:geo_point | geohex:keyword | geohexBounded:keyword -POINT (46.035023249891 51.5606456508842) | 8110bffffffffff | null -POINT (13.1442589810713 32.6691695504993) | 813fbffffffffff | 813fbffffffffff -POINT (118.12696884672 24.537192570557) | 8141bffffffffff | null +location:geo_point | geohex:keyword | geohexBounded:geohex | geohexShape:geo_shape +POINT (46.035023249891 51.5606456508842) | 8110bffffffffff | null | POLYGON ((42.136829069634125 51.40943727610449, 47.038222832332735 48.33994165728296, 53.670493635625505 49.37211750883398, 56.286117998753014 53.74532256646542, 51.15131422930829 57.15637211465772, 43.547481617187756 55.820803924848654, 42.136829069634125 51.40943727610449)) +POINT (13.1442589810713 32.6691695504993) | 813fbffffffffff | 813fbffffffffff | POLYGON ((8.974635637589913 30.254840780701706, 9.380676605201614 25.60370257696876, 13.915183885634578 23.45043771532035, 18.351304577591982 25.86678026136113, 18.343416368196834 30.62734805513404, 13.488580338198277 32.87501547725471, 8.974635637589913 30.254840780701706)) +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)) +; + +gridGeohexDocsFromCell +required_capability: spatial_grid + +FROM airports +| WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff")) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) +; + +count:long | centroid:geo_point +7 | POINT (2.475211258445467 41.32352174592337) +; + +gridGeohexLiteralFromCell +required_capability: spatial_grid + +ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (2.475211258445467 41.32352174592337)", "POINT (5.268637698941997 42.747250193330856)"] +| EVAL location = TO_GEOPOINT(location) +| MV_EXPAND location +| WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff")) +; + +location:geo_point +POINT (2.475211258445467 41.32352174592337) +POINT (5.268637698941997 42.747250193330856) ; gridGeohexStatsByWhereUK @@ -799,16 +1032,17 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geohex -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -| KEEP count, centroid, geohexString +| EVAL geohexString = TO_STRING(geohex) +| EVAL cellBoundary = TO_GEOSHAPE(geohex) +| KEEP count, centroid, geohexString, cellBoundary | SORT count DESC, geohexString ASC ; -count:long | centroid:geo_point | geohexString:keyword -13 | POINT (-2.283508819169723 53.28242553254733) | 81197ffffffffff -2 | POINT (-3.482485176064074 58.24696456314996) | 81193ffffffffff -1 | POINT (-1.2880607228726149 59.87668995279819) | 8109bffffffffff -1 | POINT (-6.216169511899352 54.66155751608312) | 81183ffffffffff +count:long | centroid:geo_point | geohexString:keyword | cellBoundary:geo_shape +13 | POINT (-2.283508819169723 53.28242553254733) | 81197ffffffffff | POLYGON ((-0.9315871635106163 57.689497374592854, -6.436337296790312 55.3773904155485, -4.889760342933795 51.22372845966177, 1.1885095534434493 49.47027919866873, 3.6300086390995365 50.610463312569514, 6.259687055981993 51.96477015603749, 5.523646549290304 55.70676846515228, -0.9315871635106163 57.689497374592854)) +2 | POINT (-3.482485176064074 58.24696456314996) | 81193ffffffffff | POLYGON ((-10.44497754477833 63.09505407752544, -16.37196241724276 60.568693514800756, -13.79164665163863 56.73632442836386, -6.436337296790312 55.3773904155485, -0.9315871635106163 57.689497374592854, -2.297526087621831 61.54550957788076, -10.44497754477833 63.09505407752544)) +1 | POINT (-1.2880607228726149 59.87668995279819) | 8109bffffffffff | POLYGON ((4.012620898449951 63.32706132801842, -2.297526087621831 61.54550957788076, -0.9315871635106163 57.689497374592854, 5.523646549290304 55.70676846515228, 11.555977692900722 58.13053116585142, 11.080660058482376 61.54051460002519, 8.644221197607186 61.8908384753262, 4.012620898449951 63.32706132801842)) +1 | POINT (-6.216169511899352 54.66155751608312) | 81183ffffffffff | POLYGON ((-13.79164665163863 56.73632442836386, -18.841171686388584 53.74020675223833, -16.3823406256948 49.6092693973489, -9.724736207832692 48.43009421958323, -4.889760342933795 51.22372845966177, -6.436337296790312 55.3773904155485, -13.79164665163863 56.73632442836386)) ; gridGeohexStatsByBoundsUK @@ -822,26 +1056,27 @@ FROM airports count = COUNT(location), centroid = ST_CENTROID_AGG(location) BY geohex -| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) -| KEEP count, centroid, geohexString +| EVAL geohexString = TO_STRING(geohex) +| EVAL cellBoundary = TO_GEOSHAPE(geohex) +| KEEP count, centroid, geohexString, cellBoundary | SORT count DESC, geohexString ASC ; -count:long | centroid:geo_point | geohexString:keyword -5 | POINT (-1.7227098606526852 51.717823022045195) | 82195ffffffffff -4 | POINT (-3.9897833741270006 54.21732849790715) | 821957fffffffff -3 | POINT (-7.885485291481018 52.65633414499462) | 82182ffffffffff -3 | POINT (3.0334555450826883 48.842039234004915) | 821fb7fffffffff -2 | POINT (5.428531668148935 59.585608751513064) | 820987fffffffff -2 | POINT (-4.2476349184289575 56.70184155693278) | 82190ffffffffff -2 | POINT (1.4715016074478626 50.863699545152485) | 82194ffffffffff -2 | POINT (4.5991105819121 52.129031270742416) | 82196ffffffffff -2 | POINT (-2.5373152876272798 55.49281941493973) | 821977fffffffff -1 | POINT (-1.2880607228726149 59.87668995279819) | 8209a7fffffffff -1 | POINT (0.15865350142121315 49.36166098807007) | 821867fffffffff -1 | POINT (-7.270800014957786 62.06249998882413) | 821927fffffffff -1 | POINT (-2.9013785161077976 58.95442885346711) | 82192ffffffffff -1 | POINT (-1.6598310694098473 53.8690819311887) | 821947fffffffff +count:long | centroid:geo_point | geohexString:keyword | cellBoundary:geo_shape +5 | POINT (-1.7227098606526852 51.717823022045195) | 82195ffffffffff | POLYGON ((-2.1788859209290505 53.251551050714795, -4.578382413982977 52.792439042763036, -4.889760342933795 51.22372845966177, -2.906527879284175 50.14229216995713, -0.6310947579755295 50.60191112048408, -0.21913743445926337 52.1416808182628, -2.1788859209290505 53.251551050714795)) +4 | POINT (-3.9897833741270006 54.21732849790715) | 821957fffffffff | POLYGON ((-3.9031812914854935 55.840605806464886, -6.436337296790312 55.3773904155485, -6.713499065102683 53.841053788108646, -4.578382413982977 52.792439042763036, -2.1788859209290505 53.251551050714795, -1.7855433613316123 54.76238836624054, -3.9031812914854935 55.840605806464886)) +3 | POINT (-7.885485291481018 52.65633414499462) | 82182ffffffffff | POLYGON ((-6.713499065102683 53.841053788108646, -9.16699332513357 53.28908444969493, -9.362891292036808 51.69686278886942, -7.224493860559402 50.67904691252102, -4.889760342933795 51.22372845966177, -4.578382413982977 52.792439042763036, -6.713499065102683 53.841053788108646)) +3 | POINT (3.0334555450826883 48.842039234004915) | 821fb7fffffffff | POLYGON ((1.1885095534434493 49.47027919866873, 0.7640259623867446 47.90745035042651, 2.458901717447715 46.76373050573097, 4.652435425239358 47.393027403288, 5.163510941569062 48.943763955054884, 3.3847715100589153 49.85377035058955, 1.1885095534434493 49.47027919866873)) +2 | POINT (5.428531668148935 59.585608751513064) | 820987fffffffff | POLYGON ((5.479068693190393 60.92198553471913, 2.767527791540729 60.73321011494055, 2.198216040575142 59.383886486983954, 4.229785449235632 58.25202580757624, 6.766112799653718 58.44709614018101, 7.4384643434389535 59.76718020289119, 5.479068693190393 60.92198553471913)) +2 | POINT (-4.2476349184289575 56.70184155693278) | 82190ffffffffff | POLYGON ((-5.832270115239392 58.353838498476094, -8.508655388670189 57.8811306023458, -8.740899630542538 56.38258811071853, -6.436337296790312 55.3773904155485, -3.9031812914854935 55.840605806464886, -3.536381138969186 57.31728796714347, -5.832270115239392 58.353838498476094)) +2 | POINT (1.4715016074478626 50.863699545152485) | 82194ffffffffff | POLYGON ((2.101313983947425 52.51713397842229, -0.21913743445926337 52.1416808182628, -0.6310947579755295 50.60191112048408, 1.1885095534434493 49.47027919866873, 3.384771510058846 49.85377035058955, 3.8811335596706074 51.360376195950145, 2.101313983947425 52.51713397842229)) +2 | POINT (4.5991105819121 52.129031270742416) | 82196ffffffffff | POLYGON ((4.948742151508294 54.2882866932292, 2.592789031305367 53.99775155222293, 2.101313983947425 52.51713397842229, 3.8811335596706074 51.360376195950145, 6.259687055981993 51.96477015603749, 6.8482289070479005 53.43156035343158, 4.948742151508294 54.2882866932292)) +2 | POINT (-2.5373152876272798 55.49281941493973) | 821977fffffffff | POLYGON ((-0.9315871635106163 57.689497374592854, -3.536381138969186 57.31728796714347, -3.9031812914854935 55.840605806464886, -1.7855433613316123 54.76238836624054, 0.6707588590220377 55.133805943055435, 1.1521975506221078 56.583354389307445, -0.9315871635106163 57.689497374592854)) +1 | POINT (-1.2880607228726149 59.87668995279819) | 8209a7fffffffff | POLYGON ((0.5480202135218006 61.82886471359379, -2.297526087621831 61.54550957788076, -2.7356231170279166 60.17050935552437, -0.4671324618104694 59.1035939329508, 2.198216040575142 59.383886486983954, 2.767527791540729 60.73321011494055, 0.5480202135218006 61.82886471359379)) +1 | POINT (0.15865350142121315 49.36166098807007) | 821867fffffffff | POLYGON ((-0.6310947579755295 50.60191112048408, -2.906527879284175 50.14229216995713, -3.2436562689082553 48.547301491418715, -1.3966081625912774 47.44351195977148, 0.7640259623867446 47.90745035042651, 1.1885095534434493 49.47027919866873, -0.6310947579755295 50.60191112048408)) +1 | POINT (-7.270800014957786 62.06249998882413) | 821927fffffffff | POLYGON ((-4.777634484041529 62.56377272218282, -7.72004205669337 62.172198741500715, -7.999682127502827 60.77664727688846, -5.502334925300172 59.7918551703578, -2.7356231170279166 60.17050935552437, -2.297526087621831 61.54550957788076, -4.777634484041529 62.56377272218282)) +1 | POINT (-2.9013785161077976 58.95442885346711) | 82192ffffffffff | POLYGON ((-2.7356231170279166 60.17050935552437, -5.502334925300172 59.7918551703578, -5.832270115239392 58.353838498476094, -3.536381138969186 57.31728796714347, -0.9315871635106163 57.689497374592854, -0.4671324618104694 59.1035939329508, -2.7356231170279166 60.17050935552437)) +1 | POINT (-1.6598310694098473 53.8690819311887) | 821947fffffffff | POLYGON ((0.6707588590220377 55.133805943055435, -1.7855433613316123 54.76238836624054, -2.1788859209290505 53.251551050714795, -0.21913743445926337 52.1416808182628, 2.101313983947425 52.51713397842229, 2.592789031305367 53.99775155222293, 0.6707588590220377 55.133805943055435)) ; gridGeohexInStatsByBounds diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java similarity index 57% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringFromLongEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java index 3e33f376e4e7e..8123fbdc3238f 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringFromLongEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java @@ -2,8 +2,9 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import java.lang.IllegalArgumentException; import java.lang.Override; import java.lang.String; import org.apache.lucene.util.BytesRef; @@ -16,24 +17,27 @@ import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; +import org.elasticsearch.xpack.esql.core.type.DataType; /** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohashToString}. + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ToGeoShape}. * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. */ -public final class StGeohashToStringFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { - private final EvalOperator.ExpressionEvaluator gridId; +public final class ToGeoShapeFromGeoGridEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator in; - public StGeohashToStringFromLongEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, - DriverContext driverContext) { + private final DataType dataType; + + public ToGeoShapeFromGeoGridEvaluator(Source source, EvalOperator.ExpressionEvaluator in, + DataType dataType, DriverContext driverContext) { super(driverContext, source); - this.gridId = gridId; + this.in = in; + this.dataType = dataType; } @Override public EvalOperator.ExpressionEvaluator next() { - return gridId; + return in; } @Override @@ -41,11 +45,21 @@ public Block evalVector(Vector v) { LongVector vector = (LongVector) v; int positionCount = v.getPositionCount(); if (vector.isConstant()) { - return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0), positionCount); + try { + return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0), positionCount); + } catch (IllegalArgumentException e) { + registerException(e); + return driverContext.blockFactory().newConstantNullBlock(positionCount); + } } try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { for (int p = 0; p < positionCount; p++) { - builder.appendBytesRef(evalValue(vector, p)); + try { + builder.appendBytesRef(evalValue(vector, p)); + } catch (IllegalArgumentException e) { + registerException(e); + builder.appendNull(); + } } return builder.build(); } @@ -53,7 +67,7 @@ public Block evalVector(Vector v) { private BytesRef evalValue(LongVector container, int index) { long value = container.getLong(index); - return StGeohashToString.fromLong(value); + return ToGeoShape.fromGeoGrid(value, this.dataType); } @Override @@ -68,13 +82,17 @@ public Block evalBlock(Block b) { boolean positionOpened = false; boolean valuesAppended = false; for (int i = start; i < end; i++) { - BytesRef value = evalValue(block, i); - if (positionOpened == false && valueCount > 1) { - builder.beginPositionEntry(); - positionOpened = true; + try { + BytesRef value = evalValue(block, i); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendBytesRef(value); + valuesAppended = true; + } catch (IllegalArgumentException e) { + registerException(e); } - builder.appendBytesRef(value); - valuesAppended = true; } if (valuesAppended == false) { builder.appendNull(); @@ -88,37 +106,40 @@ public Block evalBlock(Block b) { private BytesRef evalValue(LongBlock container, int index) { long value = container.getLong(index); - return StGeohashToString.fromLong(value); + return ToGeoShape.fromGeoGrid(value, this.dataType); } @Override public String toString() { - return "StGeohashToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeoShapeFromGeoGridEvaluator[" + "in=" + in + ", dataType=" + dataType + "]"; } @Override public void close() { - Releasables.closeExpectNoException(gridId); + Releasables.closeExpectNoException(in); } public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory gridId; + private final EvalOperator.ExpressionEvaluator.Factory in; + + private final DataType dataType; - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, DataType dataType) { this.source = source; - this.gridId = gridId; + this.in = in; + this.dataType = dataType; } @Override - public StGeohashToStringFromLongEvaluator get(DriverContext context) { - return new StGeohashToStringFromLongEvaluator(source, gridId.get(context), context); + public ToGeoShapeFromGeoGridEvaluator get(DriverContext context) { + return new ToGeoShapeFromGeoGridEvaluator(source, in.get(context), dataType, context); } @Override public String toString() { - return "StGeohashToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeoShapeFromGeoGridEvaluator[" + "in=" + in + ", dataType=" + dataType + "]"; } } } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java similarity index 64% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromStringEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java index b99abc16e62f8..b2816bcbfe0db 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java @@ -2,8 +2,9 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import java.lang.IllegalArgumentException; import java.lang.Override; import java.lang.String; import org.apache.lucene.util.BytesRef; @@ -16,24 +17,23 @@ import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; /** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotileToLong}. + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ToGeohash}. * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. */ -public final class StGeotileToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { - private final EvalOperator.ExpressionEvaluator gridId; +public final class ToGeohashFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator in; - public StGeotileToLongFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, + public ToGeohashFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator in, DriverContext driverContext) { super(driverContext, source); - this.gridId = gridId; + this.in = in; } @Override public EvalOperator.ExpressionEvaluator next() { - return gridId; + return in; } @Override @@ -42,11 +42,21 @@ public Block evalVector(Vector v) { int positionCount = v.getPositionCount(); BytesRef scratchPad = new BytesRef(); if (vector.isConstant()) { - return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + try { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } catch (IllegalArgumentException e) { + registerException(e); + return driverContext.blockFactory().newConstantNullBlock(positionCount); + } } try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { for (int p = 0; p < positionCount; p++) { - builder.appendLong(evalValue(vector, p, scratchPad)); + try { + builder.appendLong(evalValue(vector, p, scratchPad)); + } catch (IllegalArgumentException e) { + registerException(e); + builder.appendNull(); + } } return builder.build(); } @@ -54,7 +64,7 @@ public Block evalVector(Vector v) { private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeotileToLong.fromString(value); + return ToGeohash.fromString(value); } @Override @@ -70,13 +80,17 @@ public Block evalBlock(Block b) { boolean positionOpened = false; boolean valuesAppended = false; for (int i = start; i < end; i++) { - long value = evalValue(block, i, scratchPad); - if (positionOpened == false && valueCount > 1) { - builder.beginPositionEntry(); - positionOpened = true; + try { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } catch (IllegalArgumentException e) { + registerException(e); } - builder.appendLong(value); - valuesAppended = true; } if (valuesAppended == false) { builder.appendNull(); @@ -90,37 +104,37 @@ public Block evalBlock(Block b) { private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeotileToLong.fromString(value); + return ToGeohash.fromString(value); } @Override public String toString() { - return "StGeotileToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeohashFromStringEvaluator[" + "in=" + in + "]"; } @Override public void close() { - Releasables.closeExpectNoException(gridId); + Releasables.closeExpectNoException(in); } public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory gridId; + private final EvalOperator.ExpressionEvaluator.Factory in; - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in) { this.source = source; - this.gridId = gridId; + this.in = in; } @Override - public StGeotileToLongFromStringEvaluator get(DriverContext context) { - return new StGeotileToLongFromStringEvaluator(source, gridId.get(context), context); + public ToGeohashFromStringEvaluator get(DriverContext context) { + return new ToGeohashFromStringEvaluator(source, in.get(context), context); } @Override public String toString() { - return "StGeotileToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeohashFromStringEvaluator[" + "in=" + in + "]"; } } } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java similarity index 64% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongFromStringEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java index 640a77fe05fb9..a80d67945cb1d 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java @@ -2,8 +2,9 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import java.lang.IllegalArgumentException; import java.lang.Override; import java.lang.String; import org.apache.lucene.util.BytesRef; @@ -16,24 +17,23 @@ import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; /** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohashToLong}. + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ToGeohex}. * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. */ -public final class StGeohashToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { - private final EvalOperator.ExpressionEvaluator gridId; +public final class ToGeohexFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator in; - public StGeohashToLongFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, + public ToGeohexFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator in, DriverContext driverContext) { super(driverContext, source); - this.gridId = gridId; + this.in = in; } @Override public EvalOperator.ExpressionEvaluator next() { - return gridId; + return in; } @Override @@ -42,11 +42,21 @@ public Block evalVector(Vector v) { int positionCount = v.getPositionCount(); BytesRef scratchPad = new BytesRef(); if (vector.isConstant()) { - return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + try { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } catch (IllegalArgumentException e) { + registerException(e); + return driverContext.blockFactory().newConstantNullBlock(positionCount); + } } try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { for (int p = 0; p < positionCount; p++) { - builder.appendLong(evalValue(vector, p, scratchPad)); + try { + builder.appendLong(evalValue(vector, p, scratchPad)); + } catch (IllegalArgumentException e) { + registerException(e); + builder.appendNull(); + } } return builder.build(); } @@ -54,7 +64,7 @@ public Block evalVector(Vector v) { private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeohashToLong.fromString(value); + return ToGeohex.fromString(value); } @Override @@ -70,13 +80,17 @@ public Block evalBlock(Block b) { boolean positionOpened = false; boolean valuesAppended = false; for (int i = start; i < end; i++) { - long value = evalValue(block, i, scratchPad); - if (positionOpened == false && valueCount > 1) { - builder.beginPositionEntry(); - positionOpened = true; + try { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } catch (IllegalArgumentException e) { + registerException(e); } - builder.appendLong(value); - valuesAppended = true; } if (valuesAppended == false) { builder.appendNull(); @@ -90,37 +104,37 @@ public Block evalBlock(Block b) { private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeohashToLong.fromString(value); + return ToGeohex.fromString(value); } @Override public String toString() { - return "StGeohashToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeohexFromStringEvaluator[" + "in=" + in + "]"; } @Override public void close() { - Releasables.closeExpectNoException(gridId); + Releasables.closeExpectNoException(in); } public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory gridId; + private final EvalOperator.ExpressionEvaluator.Factory in; - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in) { this.source = source; - this.gridId = gridId; + this.in = in; } @Override - public StGeohashToLongFromStringEvaluator get(DriverContext context) { - return new StGeohashToLongFromStringEvaluator(source, gridId.get(context), context); + public ToGeohexFromStringEvaluator get(DriverContext context) { + return new ToGeohexFromStringEvaluator(source, in.get(context), context); } @Override public String toString() { - return "StGeohashToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeohexFromStringEvaluator[" + "in=" + in + "]"; } } } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java similarity index 64% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongFromStringEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java index 815b5c9cb9015..e6a943506e4f4 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java @@ -2,8 +2,9 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; +import java.lang.IllegalArgumentException; import java.lang.Override; import java.lang.String; import org.apache.lucene.util.BytesRef; @@ -16,24 +17,23 @@ import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; /** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohexToLong}. + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ToGeotile}. * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. */ -public final class StGeohexToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { - private final EvalOperator.ExpressionEvaluator gridId; +public final class ToGeotileFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator in; - public StGeohexToLongFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, + public ToGeotileFromStringEvaluator(Source source, EvalOperator.ExpressionEvaluator in, DriverContext driverContext) { super(driverContext, source); - this.gridId = gridId; + this.in = in; } @Override public EvalOperator.ExpressionEvaluator next() { - return gridId; + return in; } @Override @@ -42,11 +42,21 @@ public Block evalVector(Vector v) { int positionCount = v.getPositionCount(); BytesRef scratchPad = new BytesRef(); if (vector.isConstant()) { - return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + try { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } catch (IllegalArgumentException e) { + registerException(e); + return driverContext.blockFactory().newConstantNullBlock(positionCount); + } } try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { for (int p = 0; p < positionCount; p++) { - builder.appendLong(evalValue(vector, p, scratchPad)); + try { + builder.appendLong(evalValue(vector, p, scratchPad)); + } catch (IllegalArgumentException e) { + registerException(e); + builder.appendNull(); + } } return builder.build(); } @@ -54,7 +64,7 @@ public Block evalVector(Vector v) { private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeohexToLong.fromString(value); + return ToGeotile.fromString(value); } @Override @@ -70,13 +80,17 @@ public Block evalBlock(Block b) { boolean positionOpened = false; boolean valuesAppended = false; for (int i = start; i < end; i++) { - long value = evalValue(block, i, scratchPad); - if (positionOpened == false && valueCount > 1) { - builder.beginPositionEntry(); - positionOpened = true; + try { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } catch (IllegalArgumentException e) { + registerException(e); } - builder.appendLong(value); - valuesAppended = true; } if (valuesAppended == false) { builder.appendNull(); @@ -90,37 +104,37 @@ public Block evalBlock(Block b) { private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { BytesRef value = container.getBytesRef(index, scratchPad); - return StGeohexToLong.fromString(value); + return ToGeotile.fromString(value); } @Override public String toString() { - return "StGeohexToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeotileFromStringEvaluator[" + "in=" + in + "]"; } @Override public void close() { - Releasables.closeExpectNoException(gridId); + Releasables.closeExpectNoException(in); } public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory gridId; + private final EvalOperator.ExpressionEvaluator.Factory in; - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in) { this.source = source; - this.gridId = gridId; + this.in = in; } @Override - public StGeohexToLongFromStringEvaluator get(DriverContext context) { - return new StGeohexToLongFromStringEvaluator(source, gridId.get(context), context); + public ToGeotileFromStringEvaluator get(DriverContext context) { + return new ToGeotileFromStringEvaluator(source, in.get(context), context); } @Override public String toString() { - return "StGeohexToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + return "ToGeotileFromStringEvaluator[" + "in=" + in + "]"; } } } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromGeoGridEvaluator.java similarity index 78% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringFromLongEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromGeoGridEvaluator.java index aece0da62cd23..b0567776cfff6 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringFromLongEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringFromGeoGridEvaluator.java @@ -2,7 +2,7 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import java.lang.Override; import java.lang.String; @@ -16,19 +16,22 @@ import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; +import org.elasticsearch.xpack.esql.core.type.DataType; /** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotileToString}. + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link ToString}. * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. */ -public final class StGeotileToStringFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { +public final class ToStringFromGeoGridEvaluator extends AbstractConvertFunction.AbstractEvaluator { private final EvalOperator.ExpressionEvaluator gridId; - public StGeotileToStringFromLongEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, - DriverContext driverContext) { + private final DataType dataType; + + public ToStringFromGeoGridEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, + DataType dataType, DriverContext driverContext) { super(driverContext, source); this.gridId = gridId; + this.dataType = dataType; } @Override @@ -53,7 +56,7 @@ public Block evalVector(Vector v) { private BytesRef evalValue(LongVector container, int index) { long value = container.getLong(index); - return StGeotileToString.fromLong(value); + return ToString.fromGeoGrid(value, this.dataType); } @Override @@ -88,12 +91,12 @@ public Block evalBlock(Block b) { private BytesRef evalValue(LongBlock container, int index) { long value = container.getLong(index); - return StGeotileToString.fromLong(value); + return ToString.fromGeoGrid(value, this.dataType); } @Override public String toString() { - return "StGeotileToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + return "ToStringFromGeoGridEvaluator[" + "gridId=" + gridId + ", dataType=" + dataType + "]"; } @Override @@ -106,19 +109,23 @@ public static class Factory implements EvalOperator.ExpressionEvaluator.Factory private final EvalOperator.ExpressionEvaluator.Factory gridId; - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { + private final DataType dataType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId, + DataType dataType) { this.source = source; this.gridId = gridId; + this.dataType = dataType; } @Override - public StGeotileToStringFromLongEvaluator get(DriverContext context) { - return new StGeotileToStringFromLongEvaluator(source, gridId.get(context), context); + public ToStringFromGeoGridEvaluator get(DriverContext context) { + return new ToStringFromGeoGridEvaluator(source, gridId.get(context), dataType, context); } @Override public String toString() { - return "StGeotileToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + return "ToStringFromGeoGridEvaluator[" + "gridId=" + gridId + ", dataType=" + dataType + "]"; } } } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.java new file mode 100644 index 0000000000000..9464495a05178 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.java @@ -0,0 +1,127 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialDisjoint}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encodedPoints; + + private final long gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator encodedPoints, long gridId, DataType gridType, + DriverContext driverContext) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedPointsBlock = (LongBlock) encodedPoints.eval(page)) { + return eval(page.getPositionCount(), encodedPointsBlock); + } + } + + public BooleanBlock eval(int positionCount, LongBlock encodedPointsBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedPointsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialDisjoint.processGeoPointDocValuesAndConstantGrid(result, p, encodedPointsBlock, this.gridId, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encodedPoints); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory encodedPoints; + + private final long gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encodedPoints, + long gridId, DataType gridType) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator get(DriverContext context) { + return new SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator(source, encodedPoints.get(context), gridId, gridType, context); + } + + @Override + public String toString() { + return "SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.java new file mode 100644 index 0000000000000..23a6a0016867b --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.java @@ -0,0 +1,133 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialDisjoint}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encodedPoints; + + private final EvalOperator.ExpressionEvaluator gridIds; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator encodedPoints, EvalOperator.ExpressionEvaluator gridIds, + DataType gridType, DriverContext driverContext) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridIds = gridIds; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedPointsBlock = (LongBlock) encodedPoints.eval(page)) { + try (LongBlock gridIdsBlock = (LongBlock) gridIds.eval(page)) { + return eval(page.getPositionCount(), encodedPointsBlock, gridIdsBlock); + } + } + } + + public BooleanBlock eval(int positionCount, LongBlock encodedPointsBlock, + LongBlock gridIdsBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedPointsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (!gridIdsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialDisjoint.processGeoPointDocValuesAndSourceGrid(result, p, encodedPointsBlock, gridIdsBlock, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridIds=" + gridIds + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encodedPoints, gridIds); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory encodedPoints; + + private final EvalOperator.ExpressionEvaluator.Factory gridIds; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encodedPoints, + EvalOperator.ExpressionEvaluator.Factory gridIds, DataType gridType) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridIds = gridIds; + this.gridType = gridType; + } + + @Override + public SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator get(DriverContext context) { + return new SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator(source, encodedPoints.get(context), gridIds.get(context), gridType, context); + } + + @Override + public String toString() { + return "SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridIds=" + gridIds + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndConstantGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndConstantGridEvaluator.java new file mode 100644 index 0000000000000..aa8b09b9e8420 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndConstantGridEvaluator.java @@ -0,0 +1,127 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialDisjoint}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialDisjointGeoSourceAndConstantGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkb; + + private final long gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialDisjointGeoSourceAndConstantGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkb, long gridId, DataType gridType, + DriverContext driverContext) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlock = (BytesRefBlock) wkb.eval(page)) { + return eval(page.getPositionCount(), wkbBlock); + } + } + + public BooleanBlock eval(int positionCount, BytesRefBlock wkbBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialDisjoint.processGeoSourceAndConstantGrid(result, p, wkbBlock, this.gridId, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialDisjointGeoSourceAndConstantGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkb); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory wkb; + + private final long gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkb, long gridId, + DataType gridType) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialDisjointGeoSourceAndConstantGridEvaluator get(DriverContext context) { + return new SpatialDisjointGeoSourceAndConstantGridEvaluator(source, wkb.get(context), gridId, gridType, context); + } + + @Override + public String toString() { + return "SpatialDisjointGeoSourceAndConstantGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndSourceGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndSourceGridEvaluator.java new file mode 100644 index 0000000000000..556c647edb695 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointGeoSourceAndSourceGridEvaluator.java @@ -0,0 +1,133 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialDisjoint}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialDisjointGeoSourceAndSourceGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkb; + + private final EvalOperator.ExpressionEvaluator gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialDisjointGeoSourceAndSourceGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkb, EvalOperator.ExpressionEvaluator gridId, + DataType gridType, DriverContext driverContext) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlock = (BytesRefBlock) wkb.eval(page)) { + try (LongBlock gridIdBlock = (LongBlock) gridId.eval(page)) { + return eval(page.getPositionCount(), wkbBlock, gridIdBlock); + } + } + } + + public BooleanBlock eval(int positionCount, BytesRefBlock wkbBlock, LongBlock gridIdBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (!gridIdBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialDisjoint.processGeoSourceAndSourceGrid(result, p, wkbBlock, gridIdBlock, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialDisjointGeoSourceAndSourceGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkb, gridId); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory wkb; + + private final EvalOperator.ExpressionEvaluator.Factory gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkb, + EvalOperator.ExpressionEvaluator.Factory gridId, DataType gridType) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialDisjointGeoSourceAndSourceGridEvaluator get(DriverContext context) { + return new SpatialDisjointGeoSourceAndSourceGridEvaluator(source, wkb.get(context), gridId.get(context), gridType, context); + } + + @Override + public String toString() { + return "SpatialDisjointGeoSourceAndSourceGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.java new file mode 100644 index 0000000000000..e134546b8e35c --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.java @@ -0,0 +1,127 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialIntersects}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encodedPoints; + + private final long gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator encodedPoints, long gridId, DataType gridType, + DriverContext driverContext) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedPointsBlock = (LongBlock) encodedPoints.eval(page)) { + return eval(page.getPositionCount(), encodedPointsBlock); + } + } + + public BooleanBlock eval(int positionCount, LongBlock encodedPointsBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedPointsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialIntersects.processGeoPointDocValuesAndConstantGrid(result, p, encodedPointsBlock, this.gridId, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encodedPoints); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory encodedPoints; + + private final long gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encodedPoints, + long gridId, DataType gridType) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator get(DriverContext context) { + return new SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator(source, encodedPoints.get(context), gridId, gridType, context); + } + + @Override + public String toString() { + return "SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.java new file mode 100644 index 0000000000000..df4058bca87b4 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.java @@ -0,0 +1,133 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialIntersects}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encodedPoints; + + private final EvalOperator.ExpressionEvaluator gridIds; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator encodedPoints, EvalOperator.ExpressionEvaluator gridIds, + DataType gridType, DriverContext driverContext) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridIds = gridIds; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedPointsBlock = (LongBlock) encodedPoints.eval(page)) { + try (LongBlock gridIdsBlock = (LongBlock) gridIds.eval(page)) { + return eval(page.getPositionCount(), encodedPointsBlock, gridIdsBlock); + } + } + } + + public BooleanBlock eval(int positionCount, LongBlock encodedPointsBlock, + LongBlock gridIdsBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedPointsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (!gridIdsBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialIntersects.processGeoPointDocValuesAndSourceGrid(result, p, encodedPointsBlock, gridIdsBlock, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridIds=" + gridIds + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encodedPoints, gridIds); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory encodedPoints; + + private final EvalOperator.ExpressionEvaluator.Factory gridIds; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encodedPoints, + EvalOperator.ExpressionEvaluator.Factory gridIds, DataType gridType) { + this.source = source; + this.encodedPoints = encodedPoints; + this.gridIds = gridIds; + this.gridType = gridType; + } + + @Override + public SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator get(DriverContext context) { + return new SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator(source, encodedPoints.get(context), gridIds.get(context), gridType, context); + } + + @Override + public String toString() { + return "SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator[" + "encodedPoints=" + encodedPoints + ", gridIds=" + gridIds + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndConstantGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndConstantGridEvaluator.java new file mode 100644 index 0000000000000..23a6fb1cda3be --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndConstantGridEvaluator.java @@ -0,0 +1,127 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialIntersects}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialIntersectsGeoSourceAndConstantGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkb; + + private final long gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialIntersectsGeoSourceAndConstantGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkb, long gridId, DataType gridType, + DriverContext driverContext) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlock = (BytesRefBlock) wkb.eval(page)) { + return eval(page.getPositionCount(), wkbBlock); + } + } + + public BooleanBlock eval(int positionCount, BytesRefBlock wkbBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialIntersects.processGeoSourceAndConstantGrid(result, p, wkbBlock, this.gridId, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialIntersectsGeoSourceAndConstantGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkb); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory wkb; + + private final long gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkb, long gridId, + DataType gridType) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialIntersectsGeoSourceAndConstantGridEvaluator get(DriverContext context) { + return new SpatialIntersectsGeoSourceAndConstantGridEvaluator(source, wkb.get(context), gridId, gridType, context); + } + + @Override + public String toString() { + return "SpatialIntersectsGeoSourceAndConstantGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndSourceGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndSourceGridEvaluator.java new file mode 100644 index 0000000000000..8d2c55a82cec6 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsGeoSourceAndSourceGridEvaluator.java @@ -0,0 +1,133 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; + +import java.io.IOException; +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link SpatialIntersects}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class SpatialIntersectsGeoSourceAndSourceGridEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkb; + + private final EvalOperator.ExpressionEvaluator gridId; + + private final DataType gridType; + + private final DriverContext driverContext; + + private Warnings warnings; + + public SpatialIntersectsGeoSourceAndSourceGridEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkb, EvalOperator.ExpressionEvaluator gridId, + DataType gridType, DriverContext driverContext) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlock = (BytesRefBlock) wkb.eval(page)) { + try (LongBlock gridIdBlock = (LongBlock) gridId.eval(page)) { + return eval(page.getPositionCount(), wkbBlock, gridIdBlock); + } + } + } + + public BooleanBlock eval(int positionCount, BytesRefBlock wkbBlock, LongBlock gridIdBlock) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (!gridIdBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + SpatialIntersects.processGeoSourceAndSourceGrid(result, p, wkbBlock, gridIdBlock, this.gridType); + } catch (IllegalArgumentException | IOException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "SpatialIntersectsGeoSourceAndSourceGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkb, gridId); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory wkb; + + private final EvalOperator.ExpressionEvaluator.Factory gridId; + + private final DataType gridType; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkb, + EvalOperator.ExpressionEvaluator.Factory gridId, DataType gridType) { + this.source = source; + this.wkb = wkb; + this.gridId = gridId; + this.gridType = gridType; + } + + @Override + public SpatialIntersectsGeoSourceAndSourceGridEvaluator get(DriverContext context) { + return new SpatialIntersectsGeoSourceAndSourceGridEvaluator(source, wkb.get(context), gridId.get(context), gridType, context); + } + + @Override + public String toString() { + return "SpatialIntersectsGeoSourceAndSourceGridEvaluator[" + "wkb=" + wkb + ", gridId=" + gridId + ", gridType=" + gridType + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringFromLongEvaluator.java deleted file mode 100644 index 9806e85ef6a48..0000000000000 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringFromLongEvaluator.java +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License -// 2.0; you may not use this file except in compliance with the Elastic License -// 2.0. -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import java.lang.Override; -import java.lang.String; -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.compute.data.Block; -import org.elasticsearch.compute.data.BytesRefBlock; -import org.elasticsearch.compute.data.LongBlock; -import org.elasticsearch.compute.data.LongVector; -import org.elasticsearch.compute.data.Vector; -import org.elasticsearch.compute.operator.DriverContext; -import org.elasticsearch.compute.operator.EvalOperator; -import org.elasticsearch.core.Releasables; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; - -/** - * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohexToString}. - * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. - */ -public final class StGeohexToStringFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { - private final EvalOperator.ExpressionEvaluator gridId; - - public StGeohexToStringFromLongEvaluator(Source source, EvalOperator.ExpressionEvaluator gridId, - DriverContext driverContext) { - super(driverContext, source); - this.gridId = gridId; - } - - @Override - public EvalOperator.ExpressionEvaluator next() { - return gridId; - } - - @Override - public Block evalVector(Vector v) { - LongVector vector = (LongVector) v; - int positionCount = v.getPositionCount(); - if (vector.isConstant()) { - return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0), positionCount); - } - try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - builder.appendBytesRef(evalValue(vector, p)); - } - return builder.build(); - } - } - - private BytesRef evalValue(LongVector container, int index) { - long value = container.getLong(index); - return StGeohexToString.fromLong(value); - } - - @Override - public Block evalBlock(Block b) { - LongBlock block = (LongBlock) b; - int positionCount = block.getPositionCount(); - try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - int valueCount = block.getValueCount(p); - int start = block.getFirstValueIndex(p); - int end = start + valueCount; - boolean positionOpened = false; - boolean valuesAppended = false; - for (int i = start; i < end; i++) { - BytesRef value = evalValue(block, i); - if (positionOpened == false && valueCount > 1) { - builder.beginPositionEntry(); - positionOpened = true; - } - builder.appendBytesRef(value); - valuesAppended = true; - } - if (valuesAppended == false) { - builder.appendNull(); - } else if (positionOpened) { - builder.endPositionEntry(); - } - } - return builder.build(); - } - } - - private BytesRef evalValue(LongBlock container, int index) { - long value = container.getLong(index); - return StGeohexToString.fromLong(value); - } - - @Override - public String toString() { - return "StGeohexToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(gridId); - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - - private final EvalOperator.ExpressionEvaluator.Factory gridId; - - public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory gridId) { - this.source = source; - this.gridId = gridId; - } - - @Override - public StGeohexToStringFromLongEvaluator get(DriverContext context) { - return new StGeohexToStringFromLongEvaluator(source, gridId.get(context), context); - } - - @Override - public String toString() { - return "StGeohexToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; - } - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java index 00f297efd0e53..965c9571f7547 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java @@ -29,6 +29,7 @@ import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongAsNumber; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.aggregateMetricDoubleBlockToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateTimeToString; +import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.geoGridToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.ipToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.nanoTimeToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.spatialToString; @@ -136,6 +137,14 @@ protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Pa return builder.value(spatialToString(((BytesRefBlock) block).getBytesRef(valueIndex, scratch))); } }; + case GEOHASH, GEOTILE, GEOHEX -> new PositionToXContent(block) { + @Override + protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Params params, int valueIndex) + throws IOException { + long longVal = ((LongBlock) block).getLong(valueIndex); + return builder.value(geoGridToString(longVal, columnInfo.type())); + } + }; case BOOLEAN -> new PositionToXContent(block) { @Override protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Params params, int valueIndex) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ResponseValueUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ResponseValueUtils.java index 3a406de60ace7..5d0b60c138710 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ResponseValueUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/ResponseValueUtils.java @@ -34,6 +34,7 @@ import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongAsNumber; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.aggregateMetricDoubleBlockToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateTimeToString; +import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.geoGridToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.ipToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.nanoTimeToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.spatialToString; @@ -135,6 +136,7 @@ private static Object valueAt(DataType dataType, Block block, int offset, BytesR case GEO_POINT, GEO_SHAPE, CARTESIAN_POINT, CARTESIAN_SHAPE -> spatialToString( ((BytesRefBlock) block).getBytesRef(offset, scratch) ); + case GEOHEX, GEOHASH, GEOTILE -> geoGridToString(((LongBlock) block).getLong(offset), dataType); case AGGREGATE_METRIC_DOUBLE -> aggregateMetricDoubleBlockToString((AggregateMetricDoubleBlock) block, offset); case UNSUPPORTED -> (String) null; case SOURCE -> { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java index 0fb7387cfa428..f5866a5b064a8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java @@ -322,6 +322,9 @@ public static Failure validateBinaryComparison(BinaryComparison bc) { allowed.add(DataType.GEO_SHAPE); allowed.add(DataType.CARTESIAN_POINT); allowed.add(DataType.CARTESIAN_SHAPE); + allowed.add(DataType.GEOHASH); + allowed.add(DataType.GEOTILE); + allowed.add(DataType.GEOHEX); if (bc instanceof Equals || bc instanceof NotEquals) { allowed.add(DataType.BOOLEAN); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java index 23f875e4a0595..01ac78a1f21ff 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java @@ -20,6 +20,9 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; @@ -62,6 +65,14 @@ public static Expression.TypeResolution isExact(Expression e, String operationNa CARTESIAN_POINT.typeName(), GEO_SHAPE.typeName(), CARTESIAN_SHAPE.typeName() }; + private static final String[] SPATIAL_AND_GRID_TYPE_NAMES = new String[] { + GEO_POINT.typeName(), + CARTESIAN_POINT.typeName(), + GEO_SHAPE.typeName(), + CARTESIAN_SHAPE.typeName(), + GEOHASH.typeName(), + GEOTILE.typeName(), + GEOHEX.typeName() }; private static final String[] POINT_TYPE_NAMES = new String[] { GEO_POINT.typeName(), CARTESIAN_POINT.typeName() }; public static Expression.TypeResolution isSpatialPoint(Expression e, String operationName, TypeResolutions.ParamOrdinal paramOrd) { @@ -71,4 +82,8 @@ public static Expression.TypeResolution isSpatialPoint(Expression e, String oper public static Expression.TypeResolution isSpatial(Expression e, String operationName, TypeResolutions.ParamOrdinal paramOrd) { return isType(e, DataType::isSpatial, operationName, paramOrd, SPATIAL_TYPE_NAMES); } + + public static Expression.TypeResolution isSpatialAndGrid(Expression e, String operationName, TypeResolutions.ParamOrdinal paramOrd) { + return isType(e, DataType::isSpatialAndGrid, operationName, paramOrd, SPATIAL_AND_GRID_TYPE_NAMES); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java index 901f364a60041..f0e60e1e95839 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java @@ -61,14 +61,8 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StDistance; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StEnvelope; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohashToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohashToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohexToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohexToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotileToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotileToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMax; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMin; @@ -235,14 +229,8 @@ private static List spatials() { SpatialWithin.ENTRY, StDistance.ENTRY, StGeohash.ENTRY, - StGeohashToString.ENTRY, - StGeohashToLong.ENTRY, StGeotile.ENTRY, - StGeotileToString.ENTRY, - StGeotileToLong.ENTRY, - StGeohex.ENTRY, - StGeohexToString.ENTRY, - StGeohexToLong.ENTRY + StGeohex.ENTRY ); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index b115eb5c33c6e..6cafffad36a0b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -68,6 +68,9 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoPoint; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoShape; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohash; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohex; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeotile; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIp; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIpLeadingZerosDecimal; @@ -140,14 +143,8 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StDistance; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StEnvelope; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohashToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohashToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohexToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohexToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotileToLong; -import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotileToString; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMax; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMin; @@ -202,6 +199,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_PERIOD; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; @@ -231,6 +231,9 @@ public class EsqlFunctionRegistry { GEO_SHAPE, CARTESIAN_POINT, CARTESIAN_SHAPE, + GEOHASH, + GEOHEX, + GEOTILE, BOOLEAN, UNSIGNED_LONG, UNSUPPORTED @@ -403,14 +406,8 @@ private static FunctionDefinition[][] functions() { def(StX.class, StX::new, "st_x"), def(StY.class, StY::new, "st_y"), def(StGeohash.class, StGeohash::new, "st_geohash"), - def(StGeohashToLong.class, StGeohashToLong::new, "st_geohash_to_long"), - def(StGeohashToString.class, StGeohashToString::new, "st_geohash_to_string"), def(StGeotile.class, StGeotile::new, "st_geotile"), - def(StGeotileToLong.class, StGeotileToLong::new, "st_geotile_to_long"), - def(StGeotileToString.class, StGeotileToString::new, "st_geotile_to_string"), - def(StGeohex.class, StGeohex::new, "st_geohex"), - def(StGeohexToLong.class, StGeohexToLong::new, "st_geohex_to_long"), - def(StGeohexToString.class, StGeohexToString::new, "st_geohex_to_string") }, + def(StGeohex.class, StGeohex::new, "st_geohex") }, // conditional new FunctionDefinition[] { def(Case.class, Case::new, "case") }, // null @@ -433,6 +430,9 @@ private static FunctionDefinition[][] functions() { def(ToDouble.class, ToDouble::new, "to_double", "to_dbl"), def(ToGeoPoint.class, ToGeoPoint::new, "to_geopoint"), def(ToGeoShape.class, ToGeoShape::new, "to_geoshape"), + def(ToGeohash.class, ToGeohash::new, "to_geohash"), + def(ToGeotile.class, ToGeotile::new, "to_geotile"), + def(ToGeohex.class, ToGeohex::new, "to_geohex"), def(ToIp.class, ToIp::new, "to_ip"), def(ToInteger.class, ToInteger::new, "to_integer", "to_int"), def(ToLong.class, ToLong::new, "to_long"), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java index 721cdc0a55241..62aea3d3e5f5e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Values.java @@ -53,6 +53,9 @@ public class Values extends AggregateFunction implements ToAggregator { Map.entry(DataType.CARTESIAN_POINT, ValuesBytesRefAggregatorFunctionSupplier::new), Map.entry(DataType.GEO_SHAPE, ValuesBytesRefAggregatorFunctionSupplier::new), Map.entry(DataType.CARTESIAN_SHAPE, ValuesBytesRefAggregatorFunctionSupplier::new), + Map.entry(DataType.GEOHASH, ValuesLongAggregatorFunctionSupplier::new), + Map.entry(DataType.GEOTILE, ValuesLongAggregatorFunctionSupplier::new), + Map.entry(DataType.GEOHEX, ValuesLongAggregatorFunctionSupplier::new), Map.entry(DataType.BOOLEAN, ValuesBooleanAggregatorFunctionSupplier::new) ); @@ -66,6 +69,9 @@ public class Values extends AggregateFunction implements ToAggregator { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -104,6 +110,9 @@ public Values( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Case.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Case.java index fff1189207cc7..3f7d0d5b9a793 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Case.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/Case.java @@ -70,6 +70,9 @@ ConditionEvaluatorSupplier toEvaluator(ToEvaluator toEvaluator) { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -110,6 +113,9 @@ public Case( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java index f3a7ef8ca1481..b8852804e0242 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShape.java @@ -11,6 +11,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; +import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -23,10 +24,14 @@ import java.util.List; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; +import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.geoGridToShape; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToGeo; public class ToGeoShape extends AbstractConvertFunction { @@ -39,6 +44,9 @@ public class ToGeoShape extends AbstractConvertFunction { private static final Map EVALUATORS = Map.ofEntries( Map.entry(GEO_POINT, (source, fieldEval) -> fieldEval), Map.entry(GEO_SHAPE, (source, fieldEval) -> fieldEval), + Map.entry(GEOHASH, (source, fieldEval) -> new ToGeoShapeFromGeoGridEvaluator.Factory(source, fieldEval, GEOHASH)), + Map.entry(GEOTILE, (source, fieldEval) -> new ToGeoShapeFromGeoGridEvaluator.Factory(source, fieldEval, GEOTILE)), + Map.entry(GEOHEX, (source, fieldEval) -> new ToGeoShapeFromGeoGridEvaluator.Factory(source, fieldEval, GEOHEX)), Map.entry(KEYWORD, ToGeoShapeFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeoShapeFromStringEvaluator.Factory::new) ); @@ -55,7 +63,7 @@ public ToGeoShape( Source source, @Param( name = "field", - type = { "geo_point", "geo_shape", "keyword", "text" }, + type = { "geo_point", "geo_shape", "geohash", "geohex", "geotile", "keyword", "text" }, description = "Input value. The input can be a single- or multi-valued column or an expression." ) Expression field ) { @@ -95,4 +103,9 @@ protected NodeInfo info() { static BytesRef fromKeyword(BytesRef in) { return stringToGeo(in.utf8ToString()); } + + @ConvertEvaluator(extraName = "FromGeoGrid", warnExceptions = { IllegalArgumentException.class }) + static BytesRef fromGeoGrid(long in, @Fixed DataType dataType) { + return geoGridToShape(in, dataType); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java similarity index 57% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLong.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java index 717dfea9724ec..96b23760839a4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -16,49 +16,50 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; import java.io.IOException; import java.util.List; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; -public class StGeohashToLong extends AbstractConvertFunction implements EvaluatorMapper { +public class ToGeohash extends AbstractConvertFunction { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( Expression.class, - "StGeohashToLong", - StGeohashToLong::new + "ToGeohash", + ToGeohash::new ); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), - Map.entry(KEYWORD, StGeohashToLongFromStringEvaluator.Factory::new) + Map.entry(KEYWORD, ToGeohashFromStringEvaluator.Factory::new), + Map.entry(TEXT, ToGeohashFromStringEvaluator.Factory::new) ); - @FunctionInfo( - returnType = "long", - description = "Converts an input value representing a geohash grid-ID in string format into a long.", - examples = { @Example(file = "spatial-grid", tag = "geohash_to_long") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOHASH - ) - public StGeohashToLong( + @FunctionInfo(returnType = "geohash", description = """ + Converts an input value to a `geohash` value. + A string will only be successfully converted if it respects the + `geohash` format.""", examples = @Example(file = "spatial-grid", tag = "to_geohash")) + public ToGeohash( Source source, @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v + name = "field", + type = { "long", "keyword", "text" }, + description = "Input value. The input can be a single- or multi-valued column or an expression." + ) Expression field ) { - super(source, v); + super(source, field); } - private StGeohashToLong(StreamInput in) throws IOException { + private ToGeohash(StreamInput in) throws IOException { super(in); } @@ -74,21 +75,21 @@ protected Map factories() { @Override public DataType dataType() { - return LONG; + return GEOHASH; } @Override public Expression replaceChildren(List newChildren) { - return new StGeohashToLong(source(), newChildren.get(0)); + return new ToGeohash(source(), newChildren.get(0)); } @Override protected NodeInfo info() { - return NodeInfo.create(this, StGeohashToLong::new, field()); + return NodeInfo.create(this, ToGeohash::new, field()); } - @ConvertEvaluator(extraName = "FromString") - static long fromString(BytesRef gridId) { - return Geohash.longEncode(gridId.utf8ToString()); + @ConvertEvaluator(extraName = "FromString", warnExceptions = { IllegalArgumentException.class }) + static long fromString(BytesRef in) { + return Geohash.longEncode(in.utf8ToString()); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java similarity index 56% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLong.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java index abb357a683109..6216131eefebe 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -16,49 +16,46 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; import java.io.IOException; import java.util.List; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; -public class StGeohexToLong extends AbstractConvertFunction implements EvaluatorMapper { - public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( - Expression.class, - "StGeohexToLong", - StGeohexToLong::new - ); +public class ToGeohex extends AbstractConvertFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToGeohex", ToGeohex::new); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), - Map.entry(KEYWORD, StGeohexToLongFromStringEvaluator.Factory::new) + Map.entry(KEYWORD, ToGeohexFromStringEvaluator.Factory::new), + Map.entry(TEXT, ToGeohexFromStringEvaluator.Factory::new) ); - @FunctionInfo( - returnType = "long", - description = "Converts an input value representing a geohex grid-ID in string format into a long.", - examples = { @Example(file = "spatial-grid", tag = "geohex_to_long") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOHEX - ) - public StGeohexToLong( + @FunctionInfo(returnType = "geohex", description = """ + Converts an input value to a `geohex` value. + A string will only be successfully converted if it respects the + `geohex` format.""", examples = @Example(file = "spatial-grid", tag = "to_geohex")) + public ToGeohex( Source source, @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input geohex grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v + name = "field", + type = { "long", "keyword", "text" }, + description = "Input value. The input can be a single- or multi-valued column or an expression." + ) Expression field ) { - super(source, v); + super(source, field); } - private StGeohexToLong(StreamInput in) throws IOException { + private ToGeohex(StreamInput in) throws IOException { super(in); } @@ -74,21 +71,21 @@ protected Map factories() { @Override public DataType dataType() { - return LONG; + return GEOHEX; } @Override public Expression replaceChildren(List newChildren) { - return new StGeohexToLong(source(), newChildren.get(0)); + return new ToGeohex(source(), newChildren.get(0)); } @Override protected NodeInfo info() { - return NodeInfo.create(this, StGeohexToLong::new, field()); + return NodeInfo.create(this, ToGeohex::new, field()); } - @ConvertEvaluator(extraName = "FromString") - static long fromString(BytesRef gridId) { - return H3.stringToH3(gridId.utf8ToString()); + @ConvertEvaluator(extraName = "FromString", warnExceptions = { IllegalArgumentException.class }) + static long fromString(BytesRef in) { + return H3.stringToH3(in.utf8ToString()); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java similarity index 57% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLong.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java index fd52f273a4f76..e7406d3c1cb84 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -16,49 +16,50 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; import java.io.IOException; import java.util.List; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; +import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; -public class StGeotileToLong extends AbstractConvertFunction implements EvaluatorMapper { +public class ToGeotile extends AbstractConvertFunction { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( Expression.class, - "StGeotileToLong", - StGeotileToLong::new + "ToGeotile", + ToGeotile::new ); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), - Map.entry(KEYWORD, StGeotileToLongFromStringEvaluator.Factory::new) + Map.entry(KEYWORD, ToGeotileFromStringEvaluator.Factory::new), + Map.entry(TEXT, ToGeotileFromStringEvaluator.Factory::new) ); - @FunctionInfo( - returnType = "long", - description = "Converts an input value representing a geotile grid-ID in string format into a long.", - examples = { @Example(file = "spatial-grid", tag = "geotile_to_long") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOTILE - ) - public StGeotileToLong( + @FunctionInfo(returnType = "geotile", description = """ + Converts an input value to a `geotile` value. + A string will only be successfully converted if it respects the + `geotile` format.""", examples = @Example(file = "spatial-grid", tag = "to_geotile")) + public ToGeotile( Source source, @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v + name = "field", + type = { "long", "keyword", "text" }, + description = "Input value. The input can be a single- or multi-valued column or an expression." + ) Expression field ) { - super(source, v); + super(source, field); } - private StGeotileToLong(StreamInput in) throws IOException { + private ToGeotile(StreamInput in) throws IOException { super(in); } @@ -74,21 +75,21 @@ protected Map factories() { @Override public DataType dataType() { - return LONG; + return GEOTILE; } @Override public Expression replaceChildren(List newChildren) { - return new StGeotileToLong(source(), newChildren.get(0)); + return new ToGeotile(source(), newChildren.get(0)); } @Override protected NodeInfo info() { - return NodeInfo.create(this, StGeotileToLong::new, field()); + return NodeInfo.create(this, ToGeotile::new, field()); } - @ConvertEvaluator(extraName = "FromString") - static long fromString(BytesRef gridId) { - return GeoTileUtils.longEncode(gridId.utf8ToString()); + @ConvertEvaluator(extraName = "FromString", warnExceptions = { IllegalArgumentException.class }) + static long fromString(BytesRef in) { + return GeoTileUtils.longEncode(in.utf8ToString()); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java index 51bb3936060c1..6983437e8ac5a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLong.java @@ -28,6 +28,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; @@ -51,7 +54,10 @@ public class ToLong extends AbstractConvertFunction { Map.entry(UNSIGNED_LONG, ToLongFromUnsignedLongEvaluator.Factory::new), Map.entry(INTEGER, ToLongFromIntEvaluator.Factory::new), // CastIntToLongEvaluator would be a candidate, but not MV'd Map.entry(DataType.COUNTER_LONG, (source, field) -> field), - Map.entry(DataType.COUNTER_INTEGER, ToLongFromIntEvaluator.Factory::new) + Map.entry(DataType.COUNTER_INTEGER, ToLongFromIntEvaluator.Factory::new), + Map.entry(GEOHASH, (source, fieldEval) -> fieldEval), + Map.entry(GEOTILE, (source, fieldEval) -> fieldEval), + Map.entry(GEOHEX, (source, fieldEval) -> fieldEval) ); @FunctionInfo( @@ -86,7 +92,10 @@ public ToLong( "unsigned_long", "integer", "counter_integer", - "counter_long" }, + "counter_long", + "geohash", + "geotile", + "geohex" }, description = "Input value. The input can be a single- or multi-valued column or an expression." ) Expression field ) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java index e3221f374375e..9cf14aea6b643 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToString.java @@ -11,6 +11,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.compute.ann.ConvertEvaluator; +import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -31,6 +32,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; @@ -41,6 +45,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateTimeToString; +import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.geoGridToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.ipToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.nanoTimeToString; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.numericBooleanToString; @@ -67,6 +72,9 @@ public class ToString extends AbstractConvertFunction implements EvaluatorMapper Map.entry(CARTESIAN_POINT, ToStringFromCartesianPointEvaluator.Factory::new), Map.entry(CARTESIAN_SHAPE, ToStringFromCartesianShapeEvaluator.Factory::new), Map.entry(GEO_SHAPE, ToStringFromGeoShapeEvaluator.Factory::new), + Map.entry(GEOHASH, (source, fieldEval) -> new ToStringFromGeoGridEvaluator.Factory(source, fieldEval, GEOHASH)), + Map.entry(GEOTILE, (source, fieldEval) -> new ToStringFromGeoGridEvaluator.Factory(source, fieldEval, GEOTILE)), + Map.entry(GEOHEX, (source, fieldEval) -> new ToStringFromGeoGridEvaluator.Factory(source, fieldEval, GEOHEX)), Map.entry(AGGREGATE_METRIC_DOUBLE, ToStringFromAggregateMetricDoubleEvaluator.Factory::new) ); @@ -91,6 +99,9 @@ public ToString( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -197,4 +208,9 @@ static BytesRef fromCartesianShape(BytesRef wkb) { static BytesRef fromGeoShape(BytesRef wkb) { return new BytesRef(spatialToString(wkb)); } + + @ConvertEvaluator(extraName = "FromGeoGrid") + static BytesRef fromGeoGrid(long gridId, @Fixed DataType dataType) { + return new BytesRef(geoGridToString(gridId, dataType)); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppend.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppend.java index c60fb07704e2e..6680d27f360ba 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppend.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppend.java @@ -60,6 +60,9 @@ public class MvAppend extends EsqlScalarFunction implements EvaluatorMapper { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -82,6 +85,9 @@ public MvAppend( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -101,6 +107,9 @@ public MvAppend( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCount.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCount.java index f36d121ef104f..12171c65ba036 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCount.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCount.java @@ -50,6 +50,9 @@ public MvCount( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupe.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupe.java index 2826335403075..9a305d62e2336 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupe.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupe.java @@ -42,6 +42,9 @@ public class MvDedupe extends AbstractMultivalueFunction { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -65,6 +68,9 @@ public MvDedupe( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirst.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirst.java index a741fbd1175b3..7287a21b16f2f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirst.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirst.java @@ -49,6 +49,9 @@ public class MvFirst extends AbstractMultivalueFunction { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -80,6 +83,9 @@ public MvFirst( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLast.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLast.java index e65d7fca2221b..035332b9181a9 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLast.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLast.java @@ -49,6 +49,9 @@ public class MvLast extends AbstractMultivalueFunction { "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -80,6 +83,9 @@ public MvLast( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java index 5386a9e3ef763..2bafe1ec45ac3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java @@ -27,7 +27,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.isRepresentable; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; /** * Reduce a multivalued field to a single valued field containing the maximum value. @@ -69,7 +69,7 @@ public String getWriteableName() { @Override protected TypeResolution resolveFieldType() { - return isType(field(), t -> isSpatial(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); + return isType(field(), t -> isSpatialAndGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java index a2b3c53f322ba..efc281aa867bf 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java @@ -27,7 +27,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.isRepresentable; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; /** * Reduce a multivalued field to a single valued field containing the minimum value. @@ -69,7 +69,7 @@ public String getWriteableName() { @Override protected TypeResolution resolveFieldType() { - return isType(field(), t -> isSpatial(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); + return isType(field(), t -> isSpatialAndGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSlice.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSlice.java index c50cb941c97f6..6e960cf749399 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSlice.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSlice.java @@ -63,6 +63,9 @@ public class MvSlice extends EsqlScalarFunction implements OptionalArgument, Eva "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -92,6 +95,9 @@ public MvSlice( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java index c8005506be627..ad300465d34cf 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java @@ -31,20 +31,7 @@ import java.util.List; import java.util.stream.Stream; -import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN; -import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; -import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; -import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; -import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; -import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; -import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; -import static org.elasticsearch.xpack.esql.core.type.DataType.IP; -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.NULL; -import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION; /** * Function returning the first non-null value. {@code COALESCE} runs as though @@ -205,7 +192,10 @@ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { case BOOLEAN -> CoalesceBooleanEvaluator.toEvaluator(toEvaluator, children()); case DOUBLE, COUNTER_DOUBLE -> CoalesceDoubleEvaluator.toEvaluator(toEvaluator, children()); case INTEGER, COUNTER_INTEGER -> CoalesceIntEvaluator.toEvaluator(toEvaluator, children()); - case LONG, DATE_NANOS, DATETIME, COUNTER_LONG, UNSIGNED_LONG -> CoalesceLongEvaluator.toEvaluator(toEvaluator, children()); + case LONG, DATE_NANOS, DATETIME, COUNTER_LONG, UNSIGNED_LONG, GEOHASH, GEOTILE, GEOHEX -> CoalesceLongEvaluator.toEvaluator( + toEvaluator, + children() + ); case KEYWORD, TEXT, CARTESIAN_POINT, CARTESIAN_SHAPE, GEO_POINT, GEO_SHAPE, IP, VERSION -> CoalesceBytesRefEvaluator .toEvaluator(toEvaluator, children()); case NULL -> EvalOperator.CONSTANT_NULL_FACTORY; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index 437973705f343..6fc237a91fa5a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.util.Objects; +import java.util.function.Predicate; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; @@ -55,15 +56,17 @@ protected BinarySpatialFunction( Expression right, boolean leftDocValues, boolean rightDocValues, - boolean pointsOnly + boolean pointsOnly, + boolean supportsGrid ) { super(source, left, right); this.leftDocValues = leftDocValues; this.rightDocValues = rightDocValues; - this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly); + this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly, supportsGrid); } - protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly) throws IOException { + protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly, boolean supportsGrid) + throws IOException { // The doc-values fields are only used on data nodes local planning, and therefor never serialized this( in.getTransportVersion().onOrAfter(TransportVersions.ESQL_SERIALIZE_SOURCE_FUNCTIONS_WARNINGS) @@ -73,7 +76,8 @@ protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean r in.readNamedWriteable(Expression.class), leftDocValues, rightDocValues, - pointsOnly + pointsOnly, + supportsGrid ); } @@ -119,10 +123,12 @@ protected TypeResolution resolveType() { static class SpatialTypeResolver { private final SpatialEvaluatorFactory.SpatialSourceResolution supplier; private final boolean pointsOnly; + private final boolean supportsGrid; - SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly) { + SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly, boolean supportsGrid) { this.supplier = supplier; this.pointsOnly = pointsOnly; + this.supportsGrid = supportsGrid; } public Expression left() { @@ -150,7 +156,13 @@ protected TypeResolution resolveType() { protected Expression.TypeResolution isSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) { return pointsOnly ? EsqlTypeResolutions.isSpatialPoint(e, sourceText(), paramOrd) - : EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd); + : (supportsGrid + ? EsqlTypeResolutions.isSpatialAndGrid(e, sourceText(), paramOrd) + : EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd)); + } + + protected Expression.TypeResolution isGeoPoint(Expression e, TypeResolutions.ParamOrdinal paramOrd) { + return isType(e, GEO_POINT::equals, sourceText(), paramOrd, GEO_POINT.typeName()); } private TypeResolution resolveType( @@ -182,6 +194,16 @@ protected TypeResolution resolveType( if (resolution.unresolved()) { return resolution; } + // TODO Remove these grid checks once we support geo_shape relation to geoGrid + if (resolution.resolved() && DataType.isGeoGrid(spatialExpression.dataType())) { + resolution = isGeoPoint(otherExpression, otherParamOrdinal); + } + if (resolution.resolved() && DataType.isGeoGrid(otherExpression.dataType())) { + resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); + } + if (resolution.unresolved()) { + return resolution; + } supplier.setCrsType(spatialExpression.dataType()); return TypeResolution.TYPE_RESOLVED; } @@ -192,15 +214,12 @@ protected TypeResolution isSameSpatialType( String operationName, TypeResolutions.ParamOrdinal paramOrd ) { - return pointsOnly - ? isType(expression, dt -> dt == spatialDataType, operationName, paramOrd, compatibleTypeNames(spatialDataType)) - : isType( - expression, - dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt), - operationName, - paramOrd, - compatibleTypeNames(spatialDataType) - ); + Predicate isSpatialType = pointsOnly + ? dt -> dt == spatialDataType + : (supportsGrid + ? dt -> DataType.isSpatialAndGrid(dt) && spatialCRSCompatible(spatialDataType, dt) + : dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt)); + return isType(expression, isSpatialType, operationName, paramOrd, compatibleTypeNames(spatialDataType)); } } @@ -248,7 +267,7 @@ public enum SpatialCrsType { public static SpatialCrsType fromDataType(DataType dataType) { return DataType.isSpatialGeo(dataType) ? SpatialCrsType.GEO - : DataType.isSpatial(dataType) ? SpatialCrsType.CARTESIAN + : DataType.isSpatialAndGrid(dataType) ? SpatialCrsType.CARTESIAN : SpatialCrsType.UNSPECIFIED; } } @@ -286,6 +305,9 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd } private static boolean isPushableSpatialAttribute(Expression exp, LucenePushdownPredicates p) { - return exp instanceof FieldAttribute fa && DataType.isSpatial(fa.dataType()) && fa.getExactInfo().hasExact() && p.isIndexed(fa); + return exp instanceof FieldAttribute fa + && DataType.isSpatialAndGrid(fa.dataType()) + && fa.getExactInfo().hasExact() + && p.isIndexed(fa); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java index 3e16fa163fcd6..e8725f256db0c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java @@ -36,12 +36,17 @@ import java.util.HashMap; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; +import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; /** * This is the primary class for supporting the function ST_DISJOINT. @@ -81,20 +86,30 @@ public class SpatialDisjoint extends SpatialRelatesFunction { ) public SpatialDisjoint( Source source, - @Param(name = "geomA", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ - Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. - If `null`, the function returns `null`.""") Expression left, - @Param(name = "geomB", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ - Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. - If `null`, the function returns `null`. - The second parameter must also have the same coordinate system as the first. - This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""") Expression right + @Param( + name = "geomA", + type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, + description = """ + Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) + or a geo-grid value (`geohash`, `geotile`, `geohex`). + If `null`, the function returns `null`.""" + ) Expression left, + @Param( + name = "geomB", + type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, + description = """ + Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) + or a geo-grid value (`geohash`, `geotile`, `geohex`). + If `null`, the function returns `null`. + The second parameter must also have the same coordinate system as the first. + This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""" + ) Expression right ) { this(source, left, right, false, false); } private SpatialDisjoint(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues); + super(source, left, right, leftDocValues, rightDocValues, true); } private SpatialDisjoint(StreamInput in) throws IOException { @@ -132,6 +147,11 @@ protected NodeInfo info() { @Override public Object fold(FoldContext ctx) { try { + if (DataType.isGeoGrid(left().dataType())) { + return foldGeoGrid(ctx, right(), left(), left().dataType()); + } else if (DataType.isGeoGrid(right().dataType())) { + return foldGeoGrid(ctx, left(), right(), right().dataType()); + } GeometryDocValueReader docValueReader = asGeometryDocValueReader(ctx, crsType(), left()); Component2D component2D = asLuceneComponent2D(ctx, crsType(), right()); return (crsType() == SpatialCrsType.GEO) @@ -142,6 +162,11 @@ public Object fold(FoldContext ctx) { } } + private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gridExp, DataType gridType) throws IOException { + long gridId = (Long) valueOf(ctx, gridExp); + return GEO.compareGeometryAndGrid(makeGeometryFromLiteral(ctx, spatialExp), gridId, gridType); + } + @Override Map> evaluatorRules() { return evaluatorMap; @@ -211,6 +236,78 @@ public Object fold(FoldContext ctx) { } } } + + // Support geo_point and geo-grid types + for (DataType gridType : new DataType[] { GEOHASH, GEOTILE, GEOHEX }) { + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType), + new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( + (s, w, g) -> new SpatialDisjointGeoSourceAndConstantGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType).withLeftDocValues(), + new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( + (s, w, g) -> new SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType), + new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( + (s, w, g) -> new SpatialDisjointGeoSourceAndSourceGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType).withLeftDocValues(), + new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( + (s, w, g) -> new SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.Factory(s, w, g, gridType) + ) + ); + } + } + + @Evaluator(extraName = "GeoSourceAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoSourceAndConstantGrid( + BooleanBlock.Builder results, + int p, + BytesRefBlock wkb, + @Fixed long gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processSourceAndConstantGrid(results, p, wkb, gridId, gridType); + } + + @Evaluator(extraName = "GeoPointDocValuesAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoPointDocValuesAndConstantGrid( + BooleanBlock.Builder results, + int p, + LongBlock encodedPoints, + @Fixed long gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processGeoPointDocValuesAndConstantGrid(results, p, encodedPoints, gridId, gridType); + } + + @Evaluator(extraName = "GeoSourceAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoSourceAndSourceGrid( + BooleanBlock.Builder results, + int p, + BytesRefBlock wkb, + LongBlock gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processSourceAndSourceGrid(results, p, wkb, gridId, gridType); + } + + @Evaluator(extraName = "GeoPointDocValuesAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoPointDocValuesAndSourceGrid( + BooleanBlock.Builder results, + int p, + LongBlock encodedPoints, + LongBlock gridIds, + @Fixed DataType gridType + ) throws IOException { + GEO.processGeoPointDocValuesAndSourceGrid(results, p, encodedPoints, gridIds, gridType); } @Evaluator(extraName = "GeoSourceAndConstant", warnExceptions = { IllegalArgumentException.class, IOException.class }) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java index dcd53075cf69c..8cda0414474eb 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java @@ -17,6 +17,7 @@ import java.util.Map; +import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLong; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2Ds; @@ -179,6 +180,26 @@ public EvalOperator.ExpressionEvaluator.Factory get(SpatialSourceSupplier s, Eva } } + /** + * This evaluator factory is used when the right hand side is a geo-grid constant or literal, + * and the left is sourced from the index, or from previous evaluators. + */ + protected static class SpatialEvaluatorWithConstantGridFactory extends SpatialEvaluatorFactory< + EvalOperator.ExpressionEvaluator.Factory, + Long> { + + SpatialEvaluatorWithConstantGridFactory( + TriFunction factoryCreator + ) { + super(factoryCreator); + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory get(SpatialSourceSupplier s, EvaluatorMapper.ToEvaluator toEvaluator) { + return factoryCreator.apply(s.source(), toEvaluator.apply(s.left()), asLong(toEvaluator.foldCtx(), s.right())); + } + } + /** * This evaluator factory is used when the right hand side is a constant or literal, * and the left is sourced from the index, or from previous evaluators. diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java index 601550cd173bb..8e94bdd5ced8e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java @@ -36,12 +36,17 @@ import java.util.HashMap; import java.util.Map; +import static org.elasticsearch.xpack.esql.core.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; +import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; /** * This is the primary class for supporting the function ST_INTERSECTS. @@ -79,20 +84,30 @@ public class SpatialIntersects extends SpatialRelatesFunction { In mathematical terms: ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅""", examples = @Example(file = "spatial", tag = "st_intersects-airports")) public SpatialIntersects( Source source, - @Param(name = "geomA", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ - Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. - If `null`, the function returns `null`.""") Expression left, - @Param(name = "geomB", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ - Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. - If `null`, the function returns `null`. - The second parameter must also have the same coordinate system as the first. - This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""") Expression right + @Param( + name = "geomA", + type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, + description = """ + Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) + or a geo-grid value (`geohash`, `geotile`, `geohex`). + If `null`, the function returns `null`.""" + ) Expression left, + @Param( + name = "geomB", + type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, + description = """ + Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) + or a geo-grid value (`geohash`, `geotile`, `geohex`). + If `null`, the function returns `null`. + The second parameter must also have the same coordinate system as the first. + This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""" + ) Expression right ) { this(source, left, right, false, false); } private SpatialIntersects(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues); + super(source, left, right, leftDocValues, rightDocValues, true); } private SpatialIntersects(StreamInput in) throws IOException { @@ -130,6 +145,11 @@ protected NodeInfo info() { @Override public Object fold(FoldContext ctx) { try { + if (DataType.isGeoGrid(left().dataType())) { + return foldGeoGrid(ctx, right(), left(), left().dataType()); + } else if (DataType.isGeoGrid(right().dataType())) { + return foldGeoGrid(ctx, left(), right(), right().dataType()); + } GeometryDocValueReader docValueReader = asGeometryDocValueReader(ctx, crsType(), left()); Component2D component2D = asLuceneComponent2D(ctx, crsType(), right()); return (crsType() == SpatialCrsType.GEO) @@ -140,6 +160,11 @@ public Object fold(FoldContext ctx) { } } + private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gridExp, DataType gridType) throws IOException { + long gridId = (Long) valueOf(ctx, gridExp); + return GEO.compareGeometryAndGrid(makeGeometryFromLiteral(ctx, spatialExp), gridId, gridType); + } + @Override Map> evaluatorRules() { return evaluatorMap; @@ -209,6 +234,78 @@ public Object fold(FoldContext ctx) { } } } + + // Support geo_point and geo-grid types + for (DataType gridType : new DataType[] { GEOHASH, GEOTILE, GEOHEX }) { + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType), + new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( + (s, w, g) -> new SpatialIntersectsGeoSourceAndConstantGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType).withLeftDocValues(), + new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( + (s, w, g) -> new SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType), + new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( + (s, w, g) -> new SpatialIntersectsGeoSourceAndSourceGridEvaluator.Factory(s, w, g, gridType) + ) + ); + evaluatorMap.put( + SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType).withLeftDocValues(), + new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( + (s, w, g) -> new SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.Factory(s, w, g, gridType) + ) + ); + } + } + + @Evaluator(extraName = "GeoSourceAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoSourceAndConstantGrid( + BooleanBlock.Builder results, + int p, + BytesRefBlock wkb, + @Fixed long gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processSourceAndConstantGrid(results, p, wkb, gridId, gridType); + } + + @Evaluator(extraName = "GeoPointDocValuesAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoPointDocValuesAndConstantGrid( + BooleanBlock.Builder results, + int p, + LongBlock encodedPoints, + @Fixed long gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processGeoPointDocValuesAndConstantGrid(results, p, encodedPoints, gridId, gridType); + } + + @Evaluator(extraName = "GeoSourceAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoSourceAndSourceGrid( + BooleanBlock.Builder results, + int p, + BytesRefBlock wkb, + LongBlock gridId, + @Fixed DataType gridType + ) throws IOException { + GEO.processSourceAndSourceGrid(results, p, wkb, gridId, gridType); + } + + @Evaluator(extraName = "GeoPointDocValuesAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) + static void processGeoPointDocValuesAndSourceGrid( + BooleanBlock.Builder results, + int p, + LongBlock encodedPoints, + LongBlock gridIds, + @Fixed DataType gridType + ) throws IOException { + GEO.processGeoPointDocValuesAndSourceGrid(results, p, encodedPoints, gridIds, gridType); } @Evaluator(extraName = "GeoSourceAndConstant", warnExceptions = { IllegalArgumentException.class, IOException.class }) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java index 4af5230e9d328..feade885653bb 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java @@ -18,10 +18,14 @@ import org.elasticsearch.compute.data.LongBlock; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.geometry.Geometry; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.index.mapper.ShapeIndexer; import org.elasticsearch.lucene.spatial.Component2DVisitor; import org.elasticsearch.lucene.spatial.CoordinateEncoder; import org.elasticsearch.lucene.spatial.GeometryDocValueReader; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.xpack.esql.capabilities.TranslationAware; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -42,6 +46,7 @@ import java.io.IOException; import java.util.Map; +import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometry; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; @@ -53,11 +58,22 @@ public abstract class SpatialRelatesFunction extends BinarySpatialFunction SurrogateExpression { protected SpatialRelatesFunction(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, false); + super(source, left, right, leftDocValues, rightDocValues, false, false); + } + + protected SpatialRelatesFunction( + Source source, + Expression left, + Expression right, + boolean leftDocValues, + boolean rightDocValues, + boolean supportsGrid + ) { + super(source, left, right, leftDocValues, rightDocValues, false, supportsGrid); } protected SpatialRelatesFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues) throws IOException { - super(in, leftDocValues, rightDocValues, false); + super(in, leftDocValues, rightDocValues, false, false); } public abstract ShapeRelation queryRelation(); @@ -117,6 +133,93 @@ protected boolean geometryRelatesGeometry(GeometryDocValueReader reader, Compone return visitor.matches(); } + protected void processSourceAndConstantGrid( + BooleanBlock.Builder builder, + int position, + BytesRefBlock wkb, + long gridId, + DataType gridType + ) { + if (wkb.getValueCount(position) < 1) { + builder.appendNull(); + } else { + builder.appendBoolean(compareGeometryAndGrid(asGeometry(wkb, position), gridId, gridType)); + } + } + + protected void processSourceAndSourceGrid( + BooleanBlock.Builder builder, + int position, + BytesRefBlock wkb, + LongBlock gridIds, + DataType gridType + ) { + if (wkb.getValueCount(position) < 1 || gridIds.getValueCount(position) < 1) { + builder.appendNull(); + } else { + builder.appendBoolean(compareGeometryAndGrid(asGeometry(wkb, position), gridIds.getLong(position), gridType)); + } + } + + protected boolean compareGeometryAndGrid(Geometry geometry, long gridId, DataType gridType) { + if (geometry instanceof Point point) { + long geoGridId = getGridId(point, gridId, gridType); + return gridId == geoGridId; + } else { + throw new IllegalArgumentException( + "Unsupported grid intersection geometry type: " + geometry.getClass().getSimpleName() + "; expected Point" + ); + } + } + + protected void processGeoPointDocValuesAndConstantGrid( + BooleanBlock.Builder builder, + int position, + LongBlock encodedPoint, + long gridId, + DataType gridType + ) { + if (encodedPoint.getValueCount(position) < 1) { + builder.appendNull(); + } else { + final Point point = spatialCoordinateType.longAsPoint(encodedPoint.getLong(position)); + long geoGridId = getGridId(point, gridId, gridType); + builder.appendBoolean(gridId == geoGridId); + } + } + + protected void processGeoPointDocValuesAndSourceGrid( + BooleanBlock.Builder builder, + int position, + LongBlock encodedPoint, + LongBlock gridIds, + DataType gridType + ) { + if (encodedPoint.getValueCount(position) < 1 || gridIds.getValueCount(position) < 1) { + builder.appendNull(); + } else { + final Point point = spatialCoordinateType.longAsPoint(encodedPoint.getLong(position)); + final long gridId = gridIds.getLong(position); + long geoGridId = getGridId(point, gridId, gridType); + builder.appendBoolean(gridId == geoGridId); + } + } + + private long getGridId(Point point, @Fixed long gridId, @Fixed DataType gridType) { + return switch (gridType) { + case GEOHASH -> Geohash.longEncode(point.getX(), point.getY(), Geohash.stringEncode(gridId).length()); + case GEOTILE -> GeoTileUtils.longEncode( + point.getX(), + point.getY(), + Integer.parseInt(GeoTileUtils.stringEncode(gridId).split("/")[0]) + ); + case GEOHEX -> H3.geoToH3(point.getY(), point.getX(), H3.getResolution(gridId)); + default -> throw new IllegalArgumentException( + "Unsupported grid type: " + gridType + "; expected GEOHASH, GEOTILE, or GEOHEX" + ); + }; + } + protected void processSourceAndConstant(BooleanBlock.Builder builder, int position, BytesRefBlock left, @Fixed Component2D right) throws IOException { if (left.getValueCount(position) < 1) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java index 1b06c6dfd3dd5..83b64c2664070 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java @@ -42,6 +42,20 @@ public class SpatialRelatesUtils { + /** Converts a {@link Expression} into a {@link Long}. */ + static Long asLong(FoldContext ctx, Expression expression) { + Object value = valueOf(ctx, expression); + if (value instanceof Long longValue) { + return longValue; + } else if (value instanceof Integer intValue) { + return intValue.longValue(); + } else { + throw new IllegalArgumentException( + "Unsupported combination of literal [" + value.getClass().getSimpleName() + "] of type [" + expression.dataType() + "]" + ); + } + } + /** Converts a {@link Expression} into a {@link Component2D}. */ static Component2D asLuceneComponent2D(FoldContext ctx, BinarySpatialFunction.SpatialCrsType crsType, Expression expression) { return asLuceneComponent2D(crsType, makeGeometryFromLiteral(ctx, expression)); @@ -153,7 +167,7 @@ static GeometryDocValueReader asGeometryDocValueReader( return asGeometryDocValueReader(encoder, shapeIndexer, asGeometry(valueBlock, position)); } - private static Geometry asGeometry(BytesRefBlock valueBlock, int position) { + static Geometry asGeometry(BytesRefBlock valueBlock, int position) { final BytesRef scratch = new BytesRef(); final int firstValueIndex = valueBlock.getFirstValueIndex(position); final int valueCount = valueBlock.getValueCount(position); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java index f0c25e3289cc1..e318d79848cc4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java @@ -241,15 +241,15 @@ public StDistance( The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_point` and `cartesian_point` parameters.""") Expression right ) { - super(source, left, right, false, false, true); + super(source, left, right, false, false, true, false); } protected StDistance(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, true); + super(source, left, right, leftDocValues, rightDocValues, true, false); } private StDistance(StreamInput in) throws IOException { - super(in, false, false, true); + super(in, false, false, true, false); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java index 6fcef627e2cbc..bfbc965354d60 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java @@ -31,8 +31,9 @@ import java.io.IOException; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; +import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile.fromRectangle; /** * Calculates the geohash of geo_point geometries. @@ -99,10 +100,12 @@ private static int checkPrecisionRange(int precision) { } @FunctionInfo( - returnType = "long", + returnType = "geohash", description = """ Calculates the `geohash` of the supplied geo_point at the specified precision. - The result is long encoded. Use [ST_GEOHASH_TO_STRING](#esql-st_geohash_to_string) to convert the result to a string. + The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, + [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate + the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation.md).""", @@ -117,7 +120,7 @@ public StGeohash( ) Expression field, @Param(name = "precision", type = { "integer" }, description = """ Expression of type `integer`. If `null`, the function returns `null`. - Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash).""") Expression precision, + Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash).""", optional = true) Expression precision, @Param(name = "bounds", type = { "geo_shape" }, description = """ Optional bounds to filter the grid tiles, a `geo_shape` of type `BBOX`. Use [`ST_ENVELOPE`](#esql-st_envelope) if the `geo_shape` is of any other type.""", optional = true) Expression bounds @@ -147,7 +150,7 @@ public String getWriteableName() { @Override public DataType dataType() { - return LONG; + return GEOHASH; } @Override @@ -220,4 +223,8 @@ static void fromFieldDocValuesAndLiteralAndLiteral( ) { fromEncodedLong(results, p, encoded, bounds); } + + public static BytesRef toBounds(long gridId) { + return fromRectangle(Geohash.toBoundingBox(Geohash.stringEncode(gridId))); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToString.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToString.java deleted file mode 100644 index d3c6f7697e0c9..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToString.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.compute.ann.ConvertEvaluator; -import org.elasticsearch.geometry.utils.Geohash; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.NodeInfo; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; -import org.elasticsearch.xpack.esql.expression.function.Example; -import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; -import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; - -public class StGeohashToString extends AbstractConvertFunction implements EvaluatorMapper { - public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( - Expression.class, - "StGeohashToString", - StGeohashToString::new - ); - - private static final Map EVALUATORS = Map.ofEntries( - Map.entry(KEYWORD, (source, fieldEval) -> fieldEval), - Map.entry(LONG, StGeohashToStringFromLongEvaluator.Factory::new) - ); - - @FunctionInfo( - returnType = "keyword", - description = "Converts an input value representing a geohash grid-ID in long format into a string.", - examples = { @Example(file = "spatial-grid", tag = "geohash_to_string") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOHASH - ) - public StGeohashToString( - Source source, - @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input geohash grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v - ) { - super(source, v); - } - - private StGeohashToString(StreamInput in) throws IOException { - super(in); - } - - @Override - public String getWriteableName() { - return ENTRY.name; - } - - @Override - protected Map factories() { - return EVALUATORS; - } - - @Override - public DataType dataType() { - return KEYWORD; - } - - @Override - public Expression replaceChildren(List newChildren) { - return new StGeohashToString(source(), newChildren.get(0)); - } - - @Override - protected NodeInfo info() { - return NodeInfo.create(this, StGeohashToString::new, field()); - } - - @ConvertEvaluator(extraName = "FromLong") - static BytesRef fromLong(long gridId) { - return new BytesRef(Geohash.stringEncode(gridId)); - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohex.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohex.java index cbbd9cf362e5b..536d6b84dabc5 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohex.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohex.java @@ -16,8 +16,12 @@ import org.elasticsearch.compute.data.BytesRefBlock; import org.elasticsearch.compute.data.LongBlock; import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.geometry.LinearRing; import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.Polygon; +import org.elasticsearch.h3.CellBoundary; import org.elasticsearch.h3.H3; +import org.elasticsearch.h3.LatLng; import org.elasticsearch.license.License; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -25,6 +29,7 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes; import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; @@ -32,7 +37,7 @@ import java.io.IOException; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; /** @@ -88,7 +93,7 @@ public String toString() { ); private static int checkPrecisionRange(int precision) { - if (precision < 1 || precision > H3.MAX_H3_RES) { + if (precision < 0 || precision > H3.MAX_H3_RES) { throw new IllegalArgumentException( "Invalid geohex_grid precision of " + precision + ". Must be between 0 and " + H3.MAX_H3_RES + "." ); @@ -97,10 +102,12 @@ private static int checkPrecisionRange(int precision) { } @FunctionInfo( - returnType = "long", + returnType = "geohex", description = """ Calculates the `geohex`, the H3 cell-id, of the supplied geo_point at the specified precision. - The result is long encoded. Use [ST_GEOHEX_TO_STRING](#esql-st_geohex_to_string) to convert the result to a string. + The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, + [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate + the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation.md).""", @@ -150,7 +157,7 @@ public String getWriteableName() { @Override public DataType dataType() { - return LONG; + return GEOHEX; } @Override @@ -223,4 +230,23 @@ static void fromFieldDocValuesAndLiteralAndLiteral( ) { fromEncodedLong(results, p, encoded, bounds); } + + public static BytesRef toBounds(long gridId) { + return fromCellBoundary(H3.h3ToGeoBoundary(gridId)); + } + + private static BytesRef fromCellBoundary(CellBoundary cell) { + double[] x = new double[cell.numPoints() + 1]; + double[] y = new double[cell.numPoints() + 1]; + for (int i = 0; i < cell.numPoints(); i++) { + LatLng vertex = cell.getLatLon(i); + x[i] = vertex.getLonDeg(); + y[i] = vertex.getLatDeg(); + } + x[cell.numPoints()] = x[0]; + y[cell.numPoints()] = y[0]; + LinearRing ring = new LinearRing(x, y); + Polygon polygon = new Polygon(ring); + return SpatialCoordinateTypes.GEO.asWkb(polygon); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToString.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToString.java deleted file mode 100644 index 9632fe983a66b..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToString.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.compute.ann.ConvertEvaluator; -import org.elasticsearch.h3.H3; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.NodeInfo; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; -import org.elasticsearch.xpack.esql.expression.function.Example; -import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; -import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; - -public class StGeohexToString extends AbstractConvertFunction implements EvaluatorMapper { - public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( - Expression.class, - "StGeohexToString", - StGeohexToString::new - ); - - private static final Map EVALUATORS = Map.ofEntries( - Map.entry(KEYWORD, (source, fieldEval) -> fieldEval), - Map.entry(LONG, StGeohexToStringFromLongEvaluator.Factory::new) - ); - - @FunctionInfo( - returnType = "keyword", - description = "Converts an input value representing a Geohex grid-ID in long format into a string.", - examples = { @Example(file = "spatial-grid", tag = "geohex_to_string") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOHEX - ) - public StGeohexToString( - Source source, - @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input Geohex grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v - ) { - super(source, v); - } - - private StGeohexToString(StreamInput in) throws IOException { - super(in); - } - - @Override - public String getWriteableName() { - return ENTRY.name; - } - - @Override - protected Map factories() { - return EVALUATORS; - } - - @Override - public DataType dataType() { - return KEYWORD; - } - - @Override - public Expression replaceChildren(List newChildren) { - return new StGeohexToString(source(), newChildren.get(0)); - } - - @Override - protected NodeInfo info() { - return NodeInfo.create(this, StGeohexToString::new, field()); - } - - @ConvertEvaluator(extraName = "FromLong") - static BytesRef fromLong(long gridId) { - return new BytesRef(H3.h3ToString(gridId)); - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotile.java index 66e2bbe2e3358..969ce806ea535 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotile.java @@ -16,7 +16,10 @@ import org.elasticsearch.compute.data.BytesRefBlock; import org.elasticsearch.compute.data.LongBlock; import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.geometry.LinearRing; import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.Polygon; +import org.elasticsearch.geometry.Rectangle; import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileBoundedPredicate; import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -24,6 +27,7 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes; import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; @@ -32,7 +36,7 @@ import java.io.IOException; import static org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils.checkPrecisionRange; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; /** @@ -93,10 +97,12 @@ public String toString() { ); @FunctionInfo( - returnType = "long", + returnType = "geotile", description = """ Calculates the `geotile` of the supplied geo_point at the specified precision. - The result is long encoded. Use [ST_GEOTILE_TO_STRING](#esql-st_geotile_to_string) to convert the result to a string. + The result is long encoded. Use [TO_STRING](#esql-to_string) to convert the result to a string, + [TO_LONG](#esql-to_long) to convert it to a `long`, or [TO_GEOSHAPE](esql-to_geoshape.md) to calculate + the `geo_shape` bounding geometry. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query.md) and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation.md).""", @@ -141,7 +147,7 @@ public String getWriteableName() { @Override public DataType dataType() { - return LONG; + return GEOTILE; } @Override @@ -214,4 +220,16 @@ static void fromFieldDocValuesAndLiteralAndLiteral( ) { fromEncodedLong(results, p, encoded, bounds); } + + public static BytesRef toBounds(long gridId) { + return fromRectangle(GeoTileUtils.toBoundingBox(gridId)); + } + + static BytesRef fromRectangle(Rectangle bbox) { + double[] x = new double[] { bbox.getMinX(), bbox.getMaxX(), bbox.getMaxX(), bbox.getMinX(), bbox.getMinX() }; + double[] y = new double[] { bbox.getMinY(), bbox.getMinY(), bbox.getMaxY(), bbox.getMaxY(), bbox.getMinY() }; + LinearRing ring = new LinearRing(x, y); + Polygon polygon = new Polygon(ring); + return SpatialCoordinateTypes.GEO.asWkb(polygon); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToString.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToString.java deleted file mode 100644 index 1a2d2b88afc52..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToString.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.compute.ann.ConvertEvaluator; -import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.NodeInfo; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; -import org.elasticsearch.xpack.esql.expression.function.Example; -import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; -import org.elasticsearch.xpack.esql.expression.function.Param; -import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; - -public class StGeotileToString extends AbstractConvertFunction implements EvaluatorMapper { - public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( - Expression.class, - "StGeotileToString", - StGeotileToString::new - ); - - private static final Map EVALUATORS = Map.ofEntries( - Map.entry(KEYWORD, (source, fieldEval) -> fieldEval), - Map.entry(LONG, StGeotileToStringFromLongEvaluator.Factory::new) - ); - - @FunctionInfo( - returnType = "keyword", - description = "Converts an input value representing a geotile grid-ID in long format into a string.", - examples = { @Example(file = "spatial-grid", tag = "geotile_to_string") }, - depthOffset = 1 // make it appear as a subsection of ST_GEOTILE - ) - public StGeotileToString( - Source source, - @Param( - name = "grid_id", - type = { "keyword", "long" }, - description = "Input geotile grid-id. The input can be a single- or multi-valued column or an expression." - ) Expression v - ) { - super(source, v); - } - - private StGeotileToString(StreamInput in) throws IOException { - super(in); - } - - @Override - public String getWriteableName() { - return ENTRY.name; - } - - @Override - protected Map factories() { - return EVALUATORS; - } - - @Override - public DataType dataType() { - return KEYWORD; - } - - @Override - public Expression replaceChildren(List newChildren) { - return new StGeotileToString(source(), newChildren.get(0)); - } - - @Override - protected NodeInfo info() { - return NodeInfo.create(this, StGeotileToString::new, field()); - } - - @ConvertEvaluator(extraName = "FromLong") - static BytesRef fromLong(long gridId) { - return new BytesRef(GeoTileUtils.stringEncode(gridId)); - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java index 01f57342da1f0..90faa64f273ac 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java @@ -48,6 +48,9 @@ public class Equals extends EsqlBinaryComparison implements Negatable TopNEncoder.DEFAULT_SORTABLE; case GEO_POINT, CARTESIAN_POINT, GEO_SHAPE, CARTESIAN_SHAPE, COUNTER_LONG, COUNTER_INTEGER, COUNTER_DOUBLE, SOURCE, - AGGREGATE_METRIC_DOUBLE, DENSE_VECTOR -> TopNEncoder.DEFAULT_UNSORTABLE; + AGGREGATE_METRIC_DOUBLE, DENSE_VECTOR, GEOHASH, GEOTILE, GEOHEX -> TopNEncoder.DEFAULT_UNSORTABLE; // unsupported fields are encoded as BytesRef, we'll use the same encoder; all values should be null at this point case PARTIAL_AGG, UNSUPPORTED -> TopNEncoder.UNSUPPORTED; }; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java index 07771a6360625..5412d08c2f668 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java @@ -264,7 +264,7 @@ && translatable(exp, LucenePushdownPredicates.DEFAULT).finish() == TranslationAw * This specifically excludes spatial data types, which are not themselves sortable. */ public static ElementType toSortableElementType(DataType dataType) { - if (DataType.isSpatial(dataType)) { + if (DataType.isSpatialAndGrid(dataType)) { return ElementType.UNKNOWN; } return toElementType(dataType); @@ -285,7 +285,7 @@ public static ElementType toElementType(DataType dataType) { public static ElementType toElementType(DataType dataType, MappedFieldType.FieldExtractPreference fieldExtractPreference) { return switch (dataType) { - case LONG, DATETIME, DATE_NANOS, UNSIGNED_LONG, COUNTER_LONG -> ElementType.LONG; + case LONG, DATETIME, DATE_NANOS, UNSIGNED_LONG, COUNTER_LONG, GEOHASH, GEOTILE, GEOHEX -> ElementType.LONG; case INTEGER, COUNTER_INTEGER -> ElementType.INT; case DOUBLE, COUNTER_DOUBLE -> ElementType.DOUBLE; // unsupported fields are passed through as a BytesRef diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java index 54f796dee0909..042f982ae3206 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java @@ -21,7 +21,10 @@ import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder.Metric; import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.search.DocValueFormat; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; @@ -46,6 +49,9 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoPoint; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoShape; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohash; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohex; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeotile; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIpLeadingZerosRejected; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong; @@ -53,6 +59,9 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToTimeDuration; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToUnsignedLong; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToVersion; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile; import org.elasticsearch.xpack.esql.parser.ParsingException; import org.elasticsearch.xpack.versionfield.Version; @@ -79,6 +88,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_PERIOD; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; @@ -125,6 +137,9 @@ public class EsqlDataTypeConverter { entry(DOUBLE, ToDouble::new), entry(GEO_POINT, ToGeoPoint::new), entry(GEO_SHAPE, ToGeoShape::new), + entry(GEOHASH, ToGeohash::new), + entry(GEOTILE, ToGeotile::new), + entry(GEOHEX, ToGeohex::new), entry(INTEGER, ToInteger::new), entry(IP, ToIpLeadingZerosRejected::new), entry(LONG, ToLong::new), @@ -238,7 +253,7 @@ public static Converter converterFor(DataType from, DataType to) { if (DataType.isSpatialGeo(to)) { return EsqlConverter.STRING_TO_GEO; } - if (DataType.isSpatial(to)) { + if (DataType.isSpatialAndGrid(to)) { return EsqlConverter.STRING_TO_SPATIAL; } if (to == DataType.TIME_DURATION) { @@ -544,6 +559,24 @@ public static String spatialToString(BytesRef field) { return UNSPECIFIED.wkbToWkt(field); } + public static String geoGridToString(long field, DataType dataType) { + return switch (dataType) { + case GEOHASH -> Geohash.stringEncode(field); + case GEOTILE -> GeoTileUtils.stringEncode(field); + case GEOHEX -> H3.h3ToString(field); + default -> throw new IllegalArgumentException("Unsupported data type for geo grid: " + dataType); + }; + } + + public static BytesRef geoGridToShape(long field, DataType dataType) { + return switch (dataType) { + case GEOHASH -> StGeohash.toBounds(field); + case GEOTILE -> StGeotile.toBounds(field); + case GEOHEX -> StGeohex.toBounds(field); + default -> throw new IllegalArgumentException("Unsupported data type for geo grid: " + dataType); + }; + } + public static BytesRef stringToGeo(String field) { return GEO.wktToWkb(field); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java index cd0389e757e8c..3d36b5096dffb 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java @@ -39,8 +39,12 @@ import org.elasticsearch.core.TimeValue; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.index.mapper.BlockLoader; import org.elasticsearch.rest.action.RestActions; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.AbstractChunkedSerializingTestCase; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.RemoteClusterAware; @@ -231,6 +235,22 @@ private Page randomPage(List columns) { case CARTESIAN_SHAPE -> ((BytesRefBlock.Builder) builder).appendBytesRef( CARTESIAN.asWkb(ShapeTestUtils.randomGeometry(randomBoolean())) ); + case GEOHASH -> { + Point p = GeometryTestUtils.randomPoint(); + ((LongBlock.Builder) builder).appendLong( + Geohash.longEncode(p.getX(), p.getY(), randomIntBetween(1, Geohash.PRECISION)) + ); + } + case GEOTILE -> { + Point p = GeometryTestUtils.randomPoint(); + ((LongBlock.Builder) builder).appendLong( + GeoTileUtils.longEncode(p.getX(), p.getY(), randomIntBetween(0, GeoTileUtils.MAX_ZOOM)) + ); + } + case GEOHEX -> { + Point p = GeometryTestUtils.randomPoint(); + ((LongBlock.Builder) builder).appendLong(H3.geoToH3(p.getLat(), p.getLon(), randomIntBetween(1, H3.MAX_H3_RES))); + } case AGGREGATE_METRIC_DOUBLE -> { BlockLoader.AggregateMetricDoubleBuilder aggBuilder = (BlockLoader.AggregateMetricDoubleBuilder) builder; aggBuilder.min().appendDouble(randomDouble()); @@ -1197,6 +1217,9 @@ static Page valuesToPage(BlockFactory blockFactory, List columns BytesRef wkb = stringToSpatial(value.toString()); ((BytesRefBlock.Builder) builder).appendBytesRef(wkb); } + case GEOHASH -> ((LongBlock.Builder) builder).appendLong(Geohash.longEncode(value.toString())); + case GEOTILE -> ((LongBlock.Builder) builder).appendLong(GeoTileUtils.longEncode(value.toString())); + case GEOHEX -> ((LongBlock.Builder) builder).appendLong(H3.stringToH3(value.toString())); case AGGREGATE_METRIC_DOUBLE -> { BlockLoader.AggregateMetricDoubleBuilder aggBuilder = (BlockLoader.AggregateMetricDoubleBuilder) builder; aggBuilder.min().appendDouble(((Number) value).doubleValue()); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java index 1c558cbd0a96b..66801769dc8f7 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java @@ -1620,7 +1620,7 @@ public void testRegexOnInt() { public void testUnsupportedTypesWithToString() { // DATE_PERIOD and TIME_DURATION types have been added, but not really patched through the engine; i.e. supported. final String supportedTypes = "aggregate_metric_double or boolean or cartesian_point or cartesian_shape or date_nanos or datetime " - + "or geo_point or geo_shape or ip or numeric or string or version"; + + "or geo_point or geo_shape or geohash or geohex or geotile or ip or numeric or string or version"; verifyUnsupported( "row period = 1 year | eval to_string(period)", "line 1:28: argument of [to_string(period)] must be [" + supportedTypes + "], found value [period] type [date_period]" diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index 14e5c0615e2b4..9f3629f3cc804 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -50,6 +50,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; import static org.elasticsearch.xpack.esql.core.type.DataType.FLOAT; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; @@ -1041,6 +1044,9 @@ public void testSpatialSort() { "1:136: cannot sort on cartesian_shape", error(prefix + "| EVAL shape = TO_CARTESIANSHAPE(wkt) | limit 5 | sort shape") ); + assertEquals("1:143: cannot sort on geohash", error(prefix + "| EVAL grid = ST_GEOHASH(TO_GEOPOINT(wkt),1) | limit 5 | sort grid")); + assertEquals("1:143: cannot sort on geotile", error(prefix + "| EVAL grid = ST_GEOTILE(TO_GEOPOINT(wkt),1) | limit 5 | sort grid")); + assertEquals("1:142: cannot sort on geohex", error(prefix + "| EVAL grid = ST_GEOHEX(TO_GEOPOINT(wkt),1) | limit 5 | sort grid")); var airports = AnalyzerTestUtils.analyzer(loadMapping("mapping-airports.json", "airports")); var airportsWeb = AnalyzerTestUtils.analyzer(loadMapping("mapping-airports_web.json", "airports_web")); var countriesBbox = AnalyzerTestUtils.analyzer(loadMapping("mapping-countries_bbox.json", "countries_bbox")); @@ -1049,6 +1055,15 @@ public void testSpatialSort() { assertEquals("1:36: cannot sort on cartesian_point", error("FROM airports_web | LIMIT 5 | sort location", airportsWeb)); assertEquals("1:38: cannot sort on geo_shape", error("FROM countries_bbox | LIMIT 5 | sort shape", countriesBbox)); assertEquals("1:42: cannot sort on cartesian_shape", error("FROM countries_bbox_web | LIMIT 5 | sort shape", countriesBboxWeb)); + assertEquals( + "1:67: cannot sort on geohash", + error("FROM airports | LIMIT 5 | EVAL g = ST_GEOHASH(location, 1) | sort g", airports) + ); + assertEquals( + "1:67: cannot sort on geotile", + error("FROM airports | LIMIT 5 | EVAL g = ST_GEOTILE(location, 1) | sort g", airports) + ); + assertEquals("1:66: cannot sort on geohex", error("FROM airports | LIMIT 5 | EVAL g = ST_GEOHEX(location, 1) | sort g", airports)); } public void testSourceSorting() { @@ -1738,7 +1753,8 @@ public void testToDatePeriodTimeDurationInInvalidPosition() { // where assertEquals( "1:26: first argument of [\"3 days\"::date_period == to_dateperiod(\"3 days\")] must be " - + "[boolean, cartesian_point, cartesian_shape, date_nanos, datetime, double, geo_point, geo_shape, integer, ip, keyword, " + + "[boolean, cartesian_point, cartesian_shape, date_nanos, datetime, double, geo_point, geo_shape, " + + "geohash, geohex, geotile, integer, ip, keyword, " + "long, text, unsigned_long or version], found value [\"3 days\"::date_period] type [date_period]", error("row x = \"3 days\" | where \"3 days\"::date_period == to_dateperiod(\"3 days\")") ); @@ -1964,7 +1980,7 @@ public void testChangePoint() { public void testChangePoint_keySortable() { assumeTrue("change_point must be enabled", EsqlCapabilities.Cap.CHANGE_POINT.isEnabled()); List sortableTypes = List.of(BOOLEAN, DOUBLE, DATE_NANOS, DATETIME, INTEGER, IP, KEYWORD, LONG, UNSIGNED_LONG, VERSION); - List unsortableTypes = List.of(CARTESIAN_POINT, CARTESIAN_SHAPE, GEO_POINT, GEO_SHAPE); + List unsortableTypes = List.of(CARTESIAN_POINT, CARTESIAN_SHAPE, GEO_POINT, GEO_SHAPE, GEOHASH, GEOTILE, GEOHEX); for (DataType type : sortableTypes) { query(Strings.format("ROW key=NULL::%s, value=0\n | CHANGE_POINT value ON key", type)); } @@ -1987,6 +2003,9 @@ public void testChangePoint_valueNumeric() { DATETIME, GEO_POINT, GEO_SHAPE, + GEOHASH, + GEOTILE, + GEOHEX, IP, KEYWORD, VERSION diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/MultiRowTestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/MultiRowTestCaseSupplier.java index bb0d2e57c3440..794bec5fab12f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/MultiRowTestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/MultiRowTestCaseSupplier.java @@ -14,6 +14,10 @@ import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; import org.elasticsearch.geometry.Geometry; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.versionfield.Version; @@ -427,6 +431,36 @@ private static List spatialCases( return cases; } + public static List geohashCases(int minRows, int maxRows) { + Supplier gen = () -> { + Point point = GeometryTestUtils.randomPoint(); + return Geohash.longEncode(point.getX(), point.getY(), ESTestCase.randomIntBetween(1, Geohash.PRECISION)); + }; + List cases = new ArrayList<>(); + addSuppliers(cases, minRows, maxRows, "", DataType.GEOHASH, gen); + return cases; + } + + public static List geotileCases(int minRows, int maxRows) { + Supplier gen = () -> { + Point point = GeometryTestUtils.randomPoint(); + return GeoTileUtils.longEncode(point.getX(), point.getY(), ESTestCase.randomIntBetween(1, GeoTileUtils.MAX_ZOOM)); + }; + List cases = new ArrayList<>(); + addSuppliers(cases, minRows, maxRows, "", DataType.GEOTILE, gen); + return cases; + } + + public static List geohexCases(int minRows, int maxRows) { + Supplier gen = () -> { + Point point = GeometryTestUtils.randomPoint(); + return H3.geoToH3(point.getLat(), point.getLon(), ESTestCase.randomIntBetween(1, H3.MAX_H3_RES)); + }; + List cases = new ArrayList<>(); + addSuppliers(cases, minRows, maxRows, "", DataType.GEOHEX, gen); + return cases; + } + public static List stringCases(int minRows, int maxRows, DataType type) { List cases = new ArrayList<>(); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java index 66ca512eb135d..f2e93ff25158b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java @@ -13,8 +13,12 @@ import org.elasticsearch.common.time.DateUtils; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -46,6 +50,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Collectors; +import static org.elasticsearch.test.ESTestCase.randomIntBetween; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; import static org.hamcrest.Matchers.equalTo; @@ -631,6 +636,20 @@ public static void forUnaryBoolean( unary(suppliers, expectedEvaluatorToString, booleanCases(), expectedType, v -> expectedValue.apply((Boolean) v), warnings); } + /** + * Generate positive test cases for a unary function operating on an {@link DataType#GEOHASH}. + */ + public static void forUnaryGeoGrid( + List suppliers, + String expectedEvaluatorToString, + DataType gridType, + DataType expectedType, + Function expectedValue, + List warnings + ) { + unary(suppliers, expectedEvaluatorToString, geoGridCases(gridType), expectedType, n -> expectedValue.apply((long) n), warnings); + } + /** * Generate positive test cases for a unary function operating on an {@link DataType#GEO_POINT}. */ @@ -832,7 +851,7 @@ public static List intCases(int min, int max, boolean include int lower = Math.max(min, 1); int upper = Math.min(max, Integer.MAX_VALUE); if (lower < upper) { - cases.add(new TypedDataSupplier("", () -> ESTestCase.randomIntBetween(lower, upper), DataType.INTEGER)); + cases.add(new TypedDataSupplier("", () -> randomIntBetween(lower, upper), DataType.INTEGER)); } else if (lower == upper) { cases.add(new TypedDataSupplier("<" + lower + " int>", () -> lower, DataType.INTEGER)); } @@ -840,7 +859,7 @@ public static List intCases(int min, int max, boolean include int lower1 = Math.max(min, Integer.MIN_VALUE); int upper1 = Math.min(max, -1); if (lower1 < upper1) { - cases.add(new TypedDataSupplier("", () -> ESTestCase.randomIntBetween(lower1, upper1), DataType.INTEGER)); + cases.add(new TypedDataSupplier("", () -> randomIntBetween(lower1, upper1), DataType.INTEGER)); } else if (lower1 == upper1) { cases.add(new TypedDataSupplier("<" + lower1 + " int>", () -> lower1, DataType.INTEGER)); } @@ -1157,11 +1176,7 @@ public static List datePeriodCases(int yearMin, int monthMin, new TypedDataSupplier("", () -> Period.ZERO, DataType.DATE_PERIOD, true), new TypedDataSupplier( "", - () -> Period.of( - ESTestCase.randomIntBetween(yMin, yMax), - ESTestCase.randomIntBetween(mMin, mMax), - ESTestCase.randomIntBetween(dMin, dMax) - ), + () -> Period.of(randomIntBetween(yMin, yMax), randomIntBetween(mMin, mMax), randomIntBetween(dMin, dMax)), DataType.DATE_PERIOD, true ) @@ -1187,6 +1202,10 @@ public static List timeDurationCases(long minValue, long maxV ); } + public static List geoGridCases(DataType gridType) { + return geoGridCases(gridType, ESTestCase::randomBoolean); + } + public static List geoPointCases() { return geoPointCases(ESTestCase::randomBoolean); } @@ -1203,6 +1222,22 @@ public static List cartesianShapeCases() { return cartesianShapeCases(ESTestCase::randomBoolean); } + /** + * Generate cases for {@link DataType#GEOHASH}. + */ + public static List geoGridCases(DataType gridType, Supplier hasAlt) { + Supplier gridId = () -> { + Point point = GeometryTestUtils.randomPoint(hasAlt.get()); + return switch (gridType) { + case GEOHASH -> Geohash.longEncode(point.getX(), point.getY(), randomIntBetween(1, Geohash.PRECISION)); + case GEOTILE -> GeoTileUtils.longEncode(point.getX(), point.getY(), randomIntBetween(0, GeoTileUtils.MAX_ZOOM)); + case GEOHEX -> H3.geoToH3(point.getLat(), point.getLon(), randomIntBetween(0, H3.MAX_H3_RES)); + default -> throw new IllegalArgumentException("Unsupported grid type: " + gridType); + }; + }; + return List.of(new TypedDataSupplier("<" + gridType.esType() + ">", gridId, gridType)); + } + /** * Generate cases for {@link DataType#GEO_POINT}. *

diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java index 11c7476eb4b03..3dccacfe55a27 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/ValuesTests.java @@ -57,7 +57,10 @@ public static Iterable parameters() { MultiRowTestCaseSupplier.geoPointCases(1, 1000, MultiRowTestCaseSupplier.IncludingAltitude.NO), MultiRowTestCaseSupplier.cartesianPointCases(1, 1000, MultiRowTestCaseSupplier.IncludingAltitude.NO), MultiRowTestCaseSupplier.geoShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO), - MultiRowTestCaseSupplier.cartesianShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO) + MultiRowTestCaseSupplier.cartesianShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO), + MultiRowTestCaseSupplier.geohashCases(1, 100), + MultiRowTestCaseSupplier.geotileCases(1, 100), + MultiRowTestCaseSupplier.geohexCases(1, 100) ).flatMap(List::stream).map(ValuesTests::makeSupplier).collect(Collectors.toCollection(() -> suppliers)); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(suppliers, false); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/CaseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/CaseTests.java index 8d3b214f97a63..a538f17969bce 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/CaseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/conditional/CaseTests.java @@ -56,6 +56,9 @@ public class CaseTests extends AbstractScalarFunctionTestCase { DataType.GEO_POINT, DataType.CARTESIAN_SHAPE, DataType.GEO_SHAPE, + DataType.GEOHASH, + DataType.GEOTILE, + DataType.GEOHEX, DataType.NULL ).collect(Collectors.toList()); if (Build.current().isSnapshot()) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeErrorTests.java index 9e6f81e649d84..3b689323990dc 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeErrorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeErrorTests.java @@ -32,6 +32,7 @@ protected Expression build(Source source, List args) { @Override protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { - return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "geo_point or geo_shape or string")); + String expectedTypes = "geo_point or geo_shape or geohash or geohex or geotile or string"; + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> expectedTypes)); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java index 5b75bded802de..11c7c4e2d2def 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java @@ -18,6 +18,7 @@ import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; import org.elasticsearch.xpack.esql.expression.function.FunctionName; import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import java.util.ArrayList; import java.util.List; @@ -39,8 +40,20 @@ public static Iterable parameters() { final Function evaluatorName = s -> "ToGeoShape" + s + "Evaluator[in=" + attribute + "]"; final List suppliers = new ArrayList<>(); + // Points and shapes TestCaseSupplier.forUnaryGeoPoint(suppliers, attribute, DataType.GEO_SHAPE, v -> v, List.of()); TestCaseSupplier.forUnaryGeoShape(suppliers, attribute, DataType.GEO_SHAPE, v -> v, List.of()); + // Geo-Grid types + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + TestCaseSupplier.forUnaryGeoGrid( + suppliers, + "ToGeoShapeFromGeoGridEvaluator[in=Attribute[channel=0], dataType=" + gridType + "]", + gridType, + DataType.GEO_SHAPE, + v -> EsqlDataTypeConverter.geoGridToShape(v, gridType), + List.of() + ); + } // random strings that don't look like a geo shape TestCaseSupplier.forUnaryStrings(suppliers, evaluatorName.apply("FromString"), DataType.GEO_SHAPE, bytesRef -> null, bytesRef -> { var exception = expectThrows(Exception.class, () -> GEO.wktToWkb(bytesRef.utf8ToString())); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongErrorTests.java index cc93e4f050796..4c387c545f6f6 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongErrorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongErrorTests.java @@ -32,13 +32,8 @@ protected Expression build(Source source, List args) { @Override protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { - return equalTo( - typeErrorMessage( - false, - validPerPosition, - signature, - (v, p) -> "boolean or counter_integer or counter_long or date_nanos or datetime or numeric or string" - ) - ); + String expectedTypes = + "boolean or counter_integer or counter_long or date_nanos or datetime or geohash or geohex or geotile or numeric or string"; + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> expectedTypes)); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java index 50748d582ed1f..b7925fce6b496 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java @@ -241,6 +241,11 @@ public static Iterable parameters() { l -> ((Integer) l).longValue(), List.of() ); + + // Geo-Grid types + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + TestCaseSupplier.forUnaryGeoGrid(suppliers, read, gridType, DataType.LONG, v -> v, List.of()); + } return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java index f766deb2e1686..f378a56e5c451 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java @@ -19,6 +19,7 @@ import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import java.math.BigInteger; import java.time.Instant; @@ -141,6 +142,17 @@ public static Iterable parameters() { v -> new BytesRef(v.toString()), List.of() ); + // Geo-Grid types + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + TestCaseSupplier.forUnaryGeoGrid( + suppliers, + "ToStringFromGeoGridEvaluator[gridId=Attribute[channel=0], dataType=" + gridType + "]", + gridType, + DataType.KEYWORD, + v -> new BytesRef(EsqlDataTypeConverter.geoGridToString(v, gridType)), + List.of() + ); + } return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java index c57847a5daea9..dfa0dc786474c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/AbstractMultivalueFunctionTestCase.java @@ -12,6 +12,10 @@ import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; import org.elasticsearch.geometry.Geometry; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -571,6 +575,98 @@ protected static void spatial( } } + /** + * Build many test cases with {@code geohash} values that are converted to another type. + * This assumes that the function consumes {@code geohash} values and produces another type. + * For example, mv_count() can consume geo-grid values and produce an integer count. + */ + protected static void geohashGrid( + List cases, + String name, + String evaluatorName, + DataType expectedDataType, + BiFunction, Matcher> matcher + ) { + Supplier supplier = () -> { + Point point = GeometryTestUtils.randomPoint(); + return Geohash.longEncode(point.getX(), point.getY(), randomIntBetween(1, Geohash.PRECISION)); + }; + spatialGrid(cases, name, evaluatorName, DataType.GEOHASH, expectedDataType, supplier, matcher); + } + + /** + * Build many test cases with {@code geotile} values that are converted to another type. + * This assumes that the function consumes {@code geotile} values and produces another type. + * For example, mv_count() can consume geo-grid values and produce an integer count. + */ + protected static void geotileGrid( + List cases, + String name, + String evaluatorName, + DataType expectedDataType, + BiFunction, Matcher> matcher + ) { + Supplier supplier = () -> { + Point point = GeometryTestUtils.randomPoint(); + return GeoTileUtils.longEncode(point.getX(), point.getY(), randomIntBetween(1, GeoTileUtils.MAX_ZOOM)); + }; + spatialGrid(cases, name, evaluatorName, DataType.GEOTILE, expectedDataType, supplier, matcher); + } + + /** + * Build many test cases with {@code geohex} values that are converted to another type. + * This assumes that the function consumes {@code geohex} values and produces another type. + * For example, mv_count() can consume geo-grid values and produce an integer count. + */ + protected static void geohexGrid( + List cases, + String name, + String evaluatorName, + DataType expectedDataType, + BiFunction, Matcher> matcher + ) { + Supplier supplier = () -> { + Point point = GeometryTestUtils.randomPoint(); + return H3.geoToH3(point.getLat(), point.getLon(), randomIntBetween(1, H3.MAX_H3_RES)); + }; + spatialGrid(cases, name, evaluatorName, DataType.GEOHEX, expectedDataType, supplier, matcher); + } + + /** + * Build many test cases for spatial grid values + */ + protected static void spatialGrid( + List cases, + String name, + String evaluatorName, + DataType dataType, + DataType expectedDataType, + Supplier randomGridId, + BiFunction, Matcher> matcher + ) { + cases.add(new TestCaseSupplier(name + "(" + dataType.typeName() + ")", List.of(dataType), () -> { + long gridId = randomGridId.get(); + return new TestCaseSupplier.TestCase( + List.of(new TestCaseSupplier.TypedData(List.of(gridId), dataType, "field")), + evaluatorName + "[field=Attribute[channel=0]]", + expectedDataType, + matcher.apply(1, Stream.of(gridId)) + ); + })); + for (Block.MvOrdering ordering : Block.MvOrdering.values()) { + cases.add(new TestCaseSupplier(name + "(<" + dataType.typeName() + "s>) " + ordering, List.of(dataType), () -> { + List mvData = randomList(1, 100, randomGridId); + putInOrder(mvData, ordering); + return new TestCaseSupplier.TestCase( + List.of(new TestCaseSupplier.TypedData(mvData, dataType, "field")), + evaluatorName + "[field=Attribute[channel=0]]", + expectedDataType, + matcher.apply(mvData.size(), mvData.stream()) + ); + })); + } + } + /** * Build many test cases with unsigned {@code long} values. */ diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppendTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppendTests.java index c0c14499fa744..d485d990693b1 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppendTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvAppendTests.java @@ -29,6 +29,7 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; +import static org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvSliceTests.randomGrid; import static org.hamcrest.Matchers.equalTo; public class MvAppendTests extends AbstractScalarFunctionTestCase { @@ -89,21 +90,13 @@ private static void ints(List suppliers) { } private static void longs(List suppliers) { - suppliers.add(new TestCaseSupplier(List.of(DataType.LONG, DataType.LONG), () -> { - List field1 = randomList(1, 10, () -> randomLong()); - List field2 = randomList(1, 10, () -> randomLong()); - var result = new ArrayList<>(field1); - result.addAll(field2); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field1, DataType.LONG, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.LONG, "field2") - ), - "MvAppendLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.LONG, - equalTo(result) - ); - })); + addLongTestCase(suppliers, DataType.LONG, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATETIME, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATE_NANOS, ESTestCase::randomNonNegativeLong); + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + addLongTestCase(suppliers, gridType, () -> randomGrid(gridType)); + } + suppliers.add(new TestCaseSupplier(List.of(DataType.UNSIGNED_LONG, DataType.UNSIGNED_LONG), () -> { List field1 = randomList(1, 10, ESTestCase::randomLong); List field2 = randomList(1, 10, ESTestCase::randomLong); @@ -118,33 +111,21 @@ private static void longs(List suppliers) { equalTo(result) ); })); - suppliers.add(new TestCaseSupplier(List.of(DataType.DATETIME, DataType.DATETIME), () -> { - List field1 = randomList(1, 10, () -> randomLong()); - List field2 = randomList(1, 10, () -> randomLong()); - var result = new ArrayList<>(field1); - result.addAll(field2); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field1, DataType.DATETIME, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.DATETIME, "field2") - ), - "MvAppendLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.DATETIME, - equalTo(result) - ); - })); - suppliers.add(new TestCaseSupplier(List.of(DataType.DATE_NANOS, DataType.DATE_NANOS), () -> { - List field1 = randomList(1, 10, () -> randomNonNegativeLong()); - List field2 = randomList(1, 10, () -> randomNonNegativeLong()); + } + + private static void addLongTestCase(List suppliers, DataType dataType, Supplier longSupplier) { + suppliers.add(new TestCaseSupplier(List.of(dataType, dataType), () -> { + List field1 = randomList(1, 10, longSupplier); + List field2 = randomList(1, 10, longSupplier); var result = new ArrayList<>(field1); result.addAll(field2); return new TestCaseSupplier.TestCase( List.of( - new TestCaseSupplier.TypedData(field1, DataType.DATE_NANOS, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.DATE_NANOS, "field2") + new TestCaseSupplier.TypedData(field1, dataType, "field1"), + new TestCaseSupplier.TypedData(field2, dataType, "field2") ), "MvAppendLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.DATE_NANOS, + dataType, equalTo(result) ); })); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCountTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCountTests.java index 6aeab0339c172..a1bcca42a8d93 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCountTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvCountTests.java @@ -41,6 +41,9 @@ public static Iterable parameters() { cartesianPoints(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); geoShape(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); cartesianShape(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); + geohashGrid(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); + geotileGrid(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); + geohexGrid(cases, "mv_count", "MvCount", DataType.INTEGER, (size, values) -> equalTo(Math.toIntExact(values.count()))); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, cases); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupeTests.java index 24fd0a349796c..78e51b802c191 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvDedupeTests.java @@ -47,6 +47,9 @@ public static Iterable parameters() { cartesianShape(cases, "mv_dedupe", "MvDedupe", DataType.CARTESIAN_SHAPE, (size, values) -> getMatcher(values)); geoPoints(cases, "mv_dedupe", "MvDedupe", (size, values) -> getMatcher(values)); geoShape(cases, "mv_dedupe", "MvDedupe", DataType.GEO_SHAPE, (size, values) -> getMatcher(values)); + geohashGrid(cases, "mv_dedupe", "MvDedupe", DataType.GEOHASH, (size, values) -> getMatcher(values)); + geotileGrid(cases, "mv_dedupe", "MvDedupe", DataType.GEOTILE, (size, values) -> getMatcher(values)); + geohexGrid(cases, "mv_dedupe", "MvDedupe", DataType.GEOHEX, (size, values) -> getMatcher(values)); unsignedLongs(cases, "mv_dedupe", "MvDedupe", (size, values) -> getMatcher(values)); return parameterSuppliersFromTypedData(anyNullIsNull(false, cases)); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirstTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirstTests.java index 3ee98364141c6..5d0a4b4b43cda 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirstTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvFirstTests.java @@ -42,6 +42,9 @@ public static Iterable parameters() { cartesianPoints(cases, "mv_first", "MvFirst", DataType.CARTESIAN_POINT, (size, values) -> equalTo(values.findFirst().get())); geoShape(cases, "mv_first", "MvFirst", DataType.GEO_SHAPE, (size, values) -> equalTo(values.findFirst().get())); cartesianShape(cases, "mv_first", "MvFirst", DataType.CARTESIAN_SHAPE, (size, values) -> equalTo(values.findFirst().get())); + geohashGrid(cases, "mv_first", "MvFirst", DataType.GEOHASH, (size, values) -> equalTo(values.findFirst().get())); + geotileGrid(cases, "mv_first", "MvFirst", DataType.GEOTILE, (size, values) -> equalTo(values.findFirst().get())); + geohexGrid(cases, "mv_first", "MvFirst", DataType.GEOHEX, (size, values) -> equalTo(values.findFirst().get())); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(false, cases); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLastTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLastTests.java index a7a13360ce443..a725b03c860f5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLastTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvLastTests.java @@ -42,6 +42,9 @@ public static Iterable parameters() { cartesianPoints(cases, "mv_last", "MvLast", DataType.CARTESIAN_POINT, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); geoShape(cases, "mv_last", "MvLast", DataType.GEO_SHAPE, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); cartesianShape(cases, "mv_last", "MvLast", DataType.CARTESIAN_SHAPE, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); + geohashGrid(cases, "mv_first", "MvLast", DataType.GEOHASH, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); + geotileGrid(cases, "mv_first", "MvLast", DataType.GEOTILE, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); + geohexGrid(cases, "mv_first", "MvLast", DataType.GEOHEX, (size, values) -> equalTo(values.reduce((f, s) -> s).get())); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(false, cases); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSliceTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSliceTests.java index abecd38cfbba1..a6aa700617f79 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSliceTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvSliceTests.java @@ -13,6 +13,11 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geo.ShapeTestUtils; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.h3.H3; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; +import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -27,6 +32,9 @@ import java.util.function.Supplier; import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; import static org.hamcrest.Matchers.equalTo; @@ -52,7 +60,7 @@ public static Iterable parameters() { String evaluatorTypePart = switch (firstArgumentType) { case BOOLEAN -> "Boolean"; case INTEGER -> "Int"; - case LONG, DATE_NANOS, DATETIME, UNSIGNED_LONG -> "Long"; + case LONG, DATE_NANOS, DATETIME, UNSIGNED_LONG, GEOHASH, GEOTILE, GEOHEX -> "Long"; case DOUBLE -> "Double"; case KEYWORD, TEXT, IP, VERSION, GEO_POINT, CARTESIAN_POINT, GEO_SHAPE, CARTESIAN_SHAPE -> "BytesRef"; default -> throw new IllegalArgumentException("Unsupported type: " + firstArgumentType); @@ -210,74 +218,59 @@ private static void ints(List suppliers) { } private static void longs(List suppliers) { - suppliers.add(new TestCaseSupplier(List.of(DataType.LONG, DataType.INTEGER, DataType.INTEGER), () -> { - List field = randomList(1, 10, () -> randomLong()); - int length = field.size(); - int start = randomIntBetween(0, length - 1); - int end = randomIntBetween(start, length - 1); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field, DataType.LONG, "field"), - new TestCaseSupplier.TypedData(start, DataType.INTEGER, "start"), - new TestCaseSupplier.TypedData(end, DataType.INTEGER, "end") - ), - "MvSliceLongEvaluator[field=Attribute[channel=0], start=Attribute[channel=1], end=Attribute[channel=2]]", - DataType.LONG, - equalTo(start == end ? field.get(start) : field.subList(start, end + 1)) - ); - })); + addLongTestCase(suppliers, DataType.LONG, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATETIME, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATE_NANOS, ESTestCase::randomLong); + for (DataType gridType : new DataType[] { GEOHASH, GEOTILE, GEOHEX }) { + addLongTestCase(suppliers, gridType, () -> randomGrid(gridType)); + } - suppliers.add(new TestCaseSupplier(List.of(DataType.DATETIME, DataType.INTEGER, DataType.INTEGER), () -> { - List field = randomList(1, 10, () -> randomLong()); + suppliers.add(new TestCaseSupplier(List.of(DataType.UNSIGNED_LONG, DataType.INTEGER, DataType.INTEGER), () -> { + List field = randomList(1, 10, () -> randomNonNegativeLong()); + List result = field.stream().map(NumericUtils::unsignedLongAsBigInteger).toList(); int length = field.size(); int start = randomIntBetween(0, length - 1); int end = randomIntBetween(start, length - 1); return new TestCaseSupplier.TestCase( List.of( - new TestCaseSupplier.TypedData(field, DataType.DATETIME, "field"), + new TestCaseSupplier.TypedData(field, DataType.UNSIGNED_LONG, "field"), new TestCaseSupplier.TypedData(start, DataType.INTEGER, "start"), new TestCaseSupplier.TypedData(end, DataType.INTEGER, "end") ), "MvSliceLongEvaluator[field=Attribute[channel=0], start=Attribute[channel=1], end=Attribute[channel=2]]", - DataType.DATETIME, - equalTo(start == end ? field.get(start) : field.subList(start, end + 1)) + DataType.UNSIGNED_LONG, + equalTo(start == end ? result.get(start) : result.subList(start, end + 1)) ); })); + } - suppliers.add(new TestCaseSupplier(List.of(DataType.DATE_NANOS, DataType.INTEGER, DataType.INTEGER), () -> { - List field = randomList(1, 10, () -> randomLong()); + private static void addLongTestCase(List suppliers, DataType dataType, Supplier longSupplier) { + suppliers.add(new TestCaseSupplier(List.of(dataType, DataType.INTEGER, DataType.INTEGER), () -> { + List field = randomList(1, 10, longSupplier); int length = field.size(); int start = randomIntBetween(0, length - 1); int end = randomIntBetween(start, length - 1); return new TestCaseSupplier.TestCase( List.of( - new TestCaseSupplier.TypedData(field, DataType.DATE_NANOS, "field"), + new TestCaseSupplier.TypedData(field, dataType, "field"), new TestCaseSupplier.TypedData(start, DataType.INTEGER, "start"), new TestCaseSupplier.TypedData(end, DataType.INTEGER, "end") ), "MvSliceLongEvaluator[field=Attribute[channel=0], start=Attribute[channel=1], end=Attribute[channel=2]]", - DataType.DATE_NANOS, + dataType, equalTo(start == end ? field.get(start) : field.subList(start, end + 1)) ); })); + } - suppliers.add(new TestCaseSupplier(List.of(DataType.UNSIGNED_LONG, DataType.INTEGER, DataType.INTEGER), () -> { - List field = randomList(1, 10, () -> randomNonNegativeLong()); - List result = field.stream().map(NumericUtils::unsignedLongAsBigInteger).toList(); - int length = field.size(); - int start = randomIntBetween(0, length - 1); - int end = randomIntBetween(start, length - 1); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field, DataType.UNSIGNED_LONG, "field"), - new TestCaseSupplier.TypedData(start, DataType.INTEGER, "start"), - new TestCaseSupplier.TypedData(end, DataType.INTEGER, "end") - ), - "MvSliceLongEvaluator[field=Attribute[channel=0], start=Attribute[channel=1], end=Attribute[channel=2]]", - DataType.UNSIGNED_LONG, - equalTo(start == end ? result.get(start) : result.subList(start, end + 1)) - ); - })); + static long randomGrid(DataType gridType) { + Point point = GeometryTestUtils.randomPoint(); + return switch (gridType) { + case GEOHASH -> Geohash.longEncode(point.getX(), point.getY(), randomIntBetween(1, Geohash.PRECISION)); + case GEOTILE -> GeoTileUtils.longEncode(point.getX(), point.getY(), randomIntBetween(1, GeoTileUtils.MAX_ZOOM)); + case GEOHEX -> H3.geoToH3(point.getLat(), point.getLon(), randomIntBetween(1, H3.MAX_H3_RES)); + default -> throw new IllegalStateException("Invalid grid type: " + gridType); + }; } private static void doubles(List suppliers) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index 68dd600489393..34b7dde0d2978 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -10,6 +10,7 @@ import joptsimple.internal.Strings; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.geometry.Geometry; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.TypeResolutions; import org.elasticsearch.xpack.esql.core.type.DataType; @@ -28,7 +29,10 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction.compatibleTypeNames; @@ -60,6 +64,9 @@ public static TestCaseSupplier.TypedDataSupplier testCaseSupplier(DataType dataT case "geo_shape" -> TestCaseSupplier.geoShapeCases(() -> false).get(0); case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); case "cartesian_shape" -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); + case "geohash" -> TestCaseSupplier.geoGridCases(GEOHASH, () -> false).get(0); + case "geotile" -> TestCaseSupplier.geoGridCases(GEOTILE, () -> false).get(0); + case "geohex" -> TestCaseSupplier.geoGridCases(GEOHEX, () -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } @@ -94,6 +101,39 @@ protected static void addSpatialCombinations( } } + /** + * Binary spatial functions that take two spatial arguments, one of which is a gridId, + * should use this to generate combinations of test cases. + */ + protected static void addSpatialGridCombinations(List suppliers, DataType[] dataTypes, DataType returnType) { + for (DataType leftType : dataTypes) { + TestCaseSupplier.TypedDataSupplier leftDataSupplier = testCaseSupplier(leftType, true); + for (DataType rightType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + if (typeCompatible(leftType, rightType)) { + TestCaseSupplier.TypedDataSupplier rightDataSupplier = testCaseSupplier(rightType, false); + suppliers.add( + TestCaseSupplier.testCaseSupplier( + leftDataSupplier, + rightDataSupplier, + BinarySpatialFunctionTestCase::spatialEvaluatorString, + returnType, + (l, r) -> expected(l, leftType, r, rightType) + ) + ); + suppliers.add( + TestCaseSupplier.testCaseSupplier( + rightDataSupplier, + leftDataSupplier, + BinarySpatialFunctionTestCase::spatialEvaluatorString, + returnType, + (l, r) -> expected(l, rightType, r, leftType) + ) + ); + } + } + } + } + /** * Build the expected error message for an invalid type signature. * For two args, this assumes they are both spatial. @@ -103,7 +143,8 @@ protected static String typeErrorMessage( boolean includeOrdinal, List> validPerPosition, List types, - boolean pointsOnly + boolean pointsOnly, + boolean supportsGrid ) { boolean argInvalid = false; List badArgPositions = new ArrayList<>(); @@ -127,15 +168,22 @@ protected static String typeErrorMessage( if (badArgPositions.size() == 1) { int badArgPosition = badArgPositions.get(0); int goodArgPosition = badArgPosition == 0 ? 1 : 0; - if (isSpatial(types.get(goodArgPosition)) == false) { - return oneInvalid(badArgPosition, -1, includeOrdinal, types, pointsOnly); + if (DataType.isGeoGrid(types.get(goodArgPosition))) { + // When the valid position is a grid, the other type can only be points + return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, true, supportsGrid); + } else if (isSpatialAndGrid(types.get(goodArgPosition)) == false) { + return oneInvalid(badArgPosition, -1, includeOrdinal, types, pointsOnly, supportsGrid); } else { - return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, pointsOnly); + return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, pointsOnly, supportsGrid); } } else if (argInvalid && badArgPositions.size() != 2) { return invalidArg(types.get(2)); + } else if (supportsGrid && DataType.isGeoGrid(types.get(0))) { + return invalidGrid(1, types, true); + } else if (supportsGrid && DataType.isGeoGrid(types.get(1))) { + return invalidGrid(0, types, true); } else { - return oneInvalid(0, -1, includeOrdinal, types, pointsOnly); + return oneInvalid(0, -1, includeOrdinal, types, pointsOnly, supportsGrid); } } @@ -151,14 +199,26 @@ private static String invalidArg(DataType invalidType) { ); } + private static String invalidGrid(int badArgPosition, List types, boolean pointsOnly) { + String expectedType = pointsOnly ? "geo_point" : "geo_point or geo_shape"; + String ordinal = TypeResolutions.ParamOrdinal.fromIndex(badArgPosition).name().toLowerCase(Locale.ROOT) + " "; + String name = types.get(badArgPosition).typeName(); + return ordinal + "argument of [source] must be [" + expectedType + "], found value [" + name + "] type [" + name + "]"; + } + private static String oneInvalid( int badArgPosition, int goodArgPosition, boolean includeOrdinal, List types, - boolean pointsOnly + boolean pointsOnly, + boolean supportsGrid ) { - String expected = pointsOnly ? "geo_point or cartesian_point" : "geo_point, cartesian_point, geo_shape or cartesian_shape"; + String expected = pointsOnly + ? "geo_point or cartesian_point" + : (supportsGrid + ? "geo_point, cartesian_point, geo_shape, cartesian_shape, geohash, geotile or geohex" + : "geo_point, cartesian_point, geo_shape or cartesian_shape"); String ordinal = includeOrdinal ? TypeResolutions.ParamOrdinal.fromIndex(badArgPosition).name().toLowerCase(Locale.ROOT) + " " : ""; String expectedType = goodArgPosition >= 0 ? compatibleTypes(types.get(goodArgPosition)) : expected; String name = types.get(badArgPosition).typeName(); @@ -173,17 +233,33 @@ protected static Object expected(Object left, DataType leftType, Object right, D if (typeCompatible(leftType, rightType) == false) { return null; } - // TODO cast objects to right type and check intersection - BytesRef leftWKB = asGeometryWKB(left, leftType); - BytesRef rightWKB = asGeometryWKB(right, rightType); BinarySpatialFunction.BinarySpatialComparator spatialRelations = spatialRelations(left, leftType, right, rightType); try { - return spatialRelations.compare(leftWKB, rightWKB); + if (DataType.isGeoGrid(leftType)) { + return expectedGrid(spatialRelations, asGeometryWKB(right, rightType), left, leftType); + } else if (DataType.isGeoGrid(rightType)) { + return expectedGrid(spatialRelations, asGeometryWKB(left, leftType), right, rightType); + } else { + BytesRef leftWKB = asGeometryWKB(left, leftType); + BytesRef rightWKB = asGeometryWKB(right, rightType); + return spatialRelations.compare(leftWKB, rightWKB); + } } catch (IOException e) { throw new RuntimeException(e); } } + private static boolean expectedGrid( + BinarySpatialFunction.BinarySpatialComparator spatialRelations, + BytesRef wkb, + Object grid, + DataType gridType + ) { + Geometry geometry = SpatialCoordinateTypes.UNSPECIFIED.wkbToGeometry(wkb); + long gridId = Long.parseLong(grid.toString()); + return ((SpatialRelatesFunction.SpatialRelations) spatialRelations).compareGeometryAndGrid(geometry, gridId, gridType); + } + /** * When two spatial arguments are processed and then compared with a third argument, * we need to process this argument too, before producing the final result. @@ -221,7 +297,7 @@ private static BinarySpatialFunction.BinarySpatialComparator spatialRelations ) { if (isSpatialGeo(leftType) || isSpatialGeo(rightType)) { return getRelationsField("GEO"); - } else if (isSpatial(leftType) || isSpatial(rightType)) { + } else if (isSpatialAndGrid(leftType) || isSpatialAndGrid(rightType)) { return getRelationsField("CARTESIAN"); } else { throw new IllegalArgumentException( @@ -249,7 +325,7 @@ protected static BytesRef asGeometryWKB(Object object, DataType dataType) { } protected static boolean typeCompatible(DataType leftType, DataType rightType) { - if (isSpatial(leftType) && isSpatial(rightType)) { + if (isSpatialAndGrid(leftType) && isSpatialAndGrid(rightType)) { // Both must be GEO_* or both must be CARTESIAN_* return countGeo(leftType, rightType) != 1; } @@ -257,9 +333,9 @@ protected static boolean typeCompatible(DataType leftType, DataType rightType) { } private static DataType pickSpatialType(DataType leftType, DataType rightType) { - if (isSpatial(leftType)) { + if (isSpatialAndGrid(leftType)) { return leftType; - } else if (isSpatial(rightType)) { + } else if (isSpatialAndGrid(rightType)) { return rightType; } else { throw new IllegalArgumentException("Invalid spatial types: " + leftType + " and " + rightType); @@ -268,6 +344,12 @@ private static DataType pickSpatialType(DataType leftType, DataType rightType) { private static Matcher spatialEvaluatorString(DataType leftType, DataType rightType) { String crsType = isSpatialGeo(pickSpatialType(leftType, rightType)) ? "Geo" : "Cartesian"; + if (DataType.isGeoGrid(leftType) || DataType.isGeoGrid(rightType)) { + int[] c = DataType.isGeoGrid(leftType) ? new int[] { 1, 0 } : new int[] { 0, 1 }; + DataType gridType = DataType.isGeoGrid(leftType) ? leftType : rightType; + String channelText = "wkb=Attribute[channel=" + c[0] + "], gridId=Attribute[channel=" + c[1] + "], gridType=" + gridType; + return equalTo(getFunctionClassName() + crsType + "SourceAndSourceGridEvaluator[" + channelText + "]"); + } String channels = channelsText("left", "right"); return equalTo(getFunctionClassName() + crsType + "SourceAndSourceEvaluator[" + channels + "]"); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java index b3feac5619c16..2c1ccb347d8bc 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java @@ -18,8 +18,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.function.Supplier; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; + @FunctionName("st_disjoint") public class SpatialDisjointTests extends SpatialRelatesFunctionTestCase { public SpatialDisjointTests(@Name("TestCase") Supplier testCaseSupplier) { @@ -29,6 +32,7 @@ public SpatialDisjointTests(@Name("TestCase") Supplier parameters() { List suppliers = new ArrayList<>(); + SpatialRelatesFunctionTestCase.addSpatialGridCombinations(suppliers, GEO_POINT); DataType[] geoDataTypes = { DataType.GEO_POINT, DataType.GEO_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, geoDataTypes); DataType[] cartesianDataTypes = { DataType.CARTESIAN_POINT, DataType.CARTESIAN_SHAPE }; @@ -42,4 +46,8 @@ public static Iterable parameters() { protected Expression build(Source source, List args) { return new SpatialDisjoint(source, args.get(0), args.get(1)); } + + protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { + return typeErrorMessage(includeOrdinal, validPerPosition, types, false, true); + } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java index 328e166ede5e9..db921e75b7651 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java @@ -26,7 +26,6 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; -import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; import static org.hamcrest.Matchers.containsString; @@ -70,6 +69,7 @@ private static String getFunctionClassName() { protected static void addTestCaseSuppliers( List suppliers, DataType[] dataTypes, + DataType gridType, BiFunction expectedValue, TriFunction expectedValueWithBounds ) { @@ -91,7 +91,7 @@ protected static void addTestCaseSuppliers( return new TestCaseSupplier.TestCase( List.of(geoTypedData, precisionData), getFunctionClassName() + evaluatorName, - LONG, + gridType, equalTo(expectedValue.apply(geometry, precision)) ); })); @@ -115,7 +115,7 @@ protected static void addTestCaseSuppliers( return new TestCaseSupplier.TestCase( List.of(geoTypedData, precisionData, boundsData), startsWith(getFunctionClassName() + evaluatorName), - LONG, + gridType, equalTo(expectedValueWithBounds.apply(geometry, precision, SpatialGridFunction.asGeoBoundingBox(bounds))) ); })); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java index ccf94bf6d2760..d651402214a10 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java @@ -18,8 +18,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.function.Supplier; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; + @FunctionName("st_intersects") public class SpatialIntersectsTests extends SpatialRelatesFunctionTestCase { public SpatialIntersectsTests(@Name("TestCase") Supplier testCaseSupplier) { @@ -29,7 +32,8 @@ public SpatialIntersectsTests(@Name("TestCase") Supplier parameters() { List suppliers = new ArrayList<>(); - DataType[] geoDataTypes = { DataType.GEO_POINT, DataType.GEO_SHAPE }; + SpatialRelatesFunctionTestCase.addSpatialGridCombinations(suppliers, GEO_POINT); + DataType[] geoDataTypes = { GEO_POINT, DataType.GEO_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, geoDataTypes); DataType[] cartesianDataTypes = { DataType.CARTESIAN_POINT, DataType.CARTESIAN_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, cartesianDataTypes); @@ -42,4 +46,8 @@ public static Iterable parameters() { protected Expression build(Source source, List args) { return new SpatialIntersects(source, args.get(0), args.get(1)); } + + protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { + return typeErrorMessage(includeOrdinal, validPerPosition, types, false, true); + } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java index 53ed472a4d43f..756ebc08bab0a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java @@ -15,11 +15,15 @@ public abstract class SpatialRelatesFunctionTestCase extends BinarySpatialFunctionTestCase { - protected static void addSpatialCombinations(List suppliers, DataType[] dataTypes) { + protected static void addSpatialCombinations(List suppliers, DataType... dataTypes) { addSpatialCombinations(suppliers, dataTypes, DataType.BOOLEAN, false); } + protected static void addSpatialGridCombinations(List suppliers, DataType... dataTypes) { + addSpatialGridCombinations(suppliers, dataTypes, DataType.BOOLEAN); + } + protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, false); + return typeErrorMessage(includeOrdinal, validPerPosition, types, false, false); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java index c78977918fc5e..06958b94a492f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java @@ -49,6 +49,6 @@ protected static void addSpatialCombinations(List suppliers, D } protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, true); + return typeErrorMessage(includeOrdinal, validPerPosition, types, true, false); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashTests.java index 625f23f4c9a3c..d962ab8066668 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashTests.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.function.Supplier; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; import static org.hamcrest.Matchers.containsString; @@ -42,7 +44,7 @@ public static License.OperationMode licenseRequirement(List fieldTypes @ParametersFactory public static Iterable parameters() { final List suppliers = new ArrayList<>(); - addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeohashTests::valueOf, StGeohashTests::boundedValueOf); + addTestCaseSuppliers(suppliers, new DataType[] { GEO_POINT }, GEOHASH, StGeohashTests::valueOf, StGeohashTests::boundedValueOf); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongTests.java deleted file mode 100644 index fab3655677774..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.geometry.utils.Geohash; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geohash_to_long") -public class StGeohashToLongTests extends SpatialGridTypeConversionTestCases { - public StGeohashToLongTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "Attribute[channel=0]", - DataType.LONG, - g -> StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeohashToLongTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "StGeohashToLongFromStringEvaluator[gridId=Attribute[channel=0]]", - DataType.LONG, - g -> new BytesRef(Geohash.stringEncode(StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeohashToLongTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static long valueOf(Object gridid) { - return (gridid instanceof Long hash) ? hash : Geohash.longEncode(((BytesRef) gridid).utf8ToString()); - } - - @Override - protected Expression build(Source source, List args) { - return new StGeohashToLong(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringTests.java deleted file mode 100644 index 58feda75a8ab9..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.geometry.utils.Geohash; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geohash_to_string") -public class StGeohashToStringTests extends SpatialGridTypeConversionTestCases { - public StGeohashToStringTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "StGeohashToStringFromLongEvaluator[gridId=Attribute[channel=0]]", - KEYWORD, - g -> StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeohashToStringTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "Attribute[channel=0]", - KEYWORD, - g -> new BytesRef(Geohash.stringEncode(StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeohashToStringTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static BytesRef valueOf(Object gridid) { - return (gridid instanceof Long hash) ? new BytesRef(Geohash.stringEncode(hash)) : (BytesRef) gridid; - } - - @Override - protected Expression build(Source source, List args) { - return new StGeohashToString(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexTests.java index e48b65df050af..b543851e74085 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexTests.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.function.Supplier; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; import static org.hamcrest.Matchers.containsString; @@ -42,7 +44,7 @@ public static License.OperationMode licenseRequirement(List fieldTypes @ParametersFactory public static Iterable parameters() { final List suppliers = new ArrayList<>(); - addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeohexTests::valueOf, StGeohexTests::boundedValueOf); + addTestCaseSuppliers(suppliers, new DataType[] { GEO_POINT }, GEOHEX, StGeohexTests::valueOf, StGeohexTests::boundedValueOf); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongTests.java deleted file mode 100644 index 7c28fdb551079..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.h3.H3; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geohex_to_long") -public class StGeohexToLongTests extends SpatialGridTypeConversionTestCases { - public StGeohexToLongTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "Attribute[channel=0]", - DataType.LONG, - g -> StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeohexToLongTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "StGeohexToLongFromStringEvaluator[gridId=Attribute[channel=0]]", - DataType.LONG, - g -> new BytesRef(H3.h3ToString(StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeohexToLongTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static long valueOf(Object gridid) { - return (gridid instanceof Long hash) ? hash : H3.stringToH3(((BytesRef) gridid).utf8ToString()); - } - - @Override - protected Expression build(Source source, List args) { - return new StGeohexToLong(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringTests.java deleted file mode 100644 index bf3c734869330..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.h3.H3; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geohex_to_string") -public class StGeohexToStringTests extends SpatialGridTypeConversionTestCases { - public StGeohexToStringTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "StGeohexToStringFromLongEvaluator[gridId=Attribute[channel=0]]", - KEYWORD, - g -> StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeohexToStringTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "Attribute[channel=0]", - KEYWORD, - g -> new BytesRef(H3.h3ToString(StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeohexToStringTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static BytesRef valueOf(Object gridid) { - return (gridid instanceof Long hash) ? new BytesRef(H3.h3ToString(hash)) : (BytesRef) gridid; - } - - @Override - protected Expression build(Source source, List args) { - return new StGeohexToString(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileTests.java index 01632fb07bf38..f120091ade33b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileTests.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.function.Supplier; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; import static org.hamcrest.Matchers.containsString; @@ -39,10 +41,11 @@ public static License.OperationMode licenseRequirement(List fieldTypes return SpatialGridFunctionTestCase.licenseRequirement(fieldTypes); } + @SuppressWarnings("checkstyle:LineLength") @ParametersFactory public static Iterable parameters() { final List suppliers = new ArrayList<>(); - addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeotileTests::valueOf, StGeotileTests::boundedValueOf); + addTestCaseSuppliers(suppliers, new DataType[] { GEO_POINT }, GEOTILE, StGeotileTests::valueOf, StGeotileTests::boundedValueOf); return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongTests.java deleted file mode 100644 index 1f43536719fd8..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geotile_to_long") -public class StGeotileToLongTests extends SpatialGridTypeConversionTestCases { - public StGeotileToLongTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "Attribute[channel=0]", - DataType.LONG, - g -> StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeotileToLongTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "StGeotileToLongFromStringEvaluator[gridId=Attribute[channel=0]]", - DataType.LONG, - g -> new BytesRef(GeoTileUtils.stringEncode(StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeotileToLongTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static long valueOf(Object gridid) { - return (gridid instanceof Long hash) ? hash : GeoTileUtils.longEncode(((BytesRef) gridid).utf8ToString()); - } - - @Override - protected Expression build(Source source, List args) { - return new StGeotileToLong(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringTests.java deleted file mode 100644 index fd558887c0fda..0000000000000 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.expression.function.scalar.spatial; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; -import org.elasticsearch.xpack.esql.core.expression.Expression; -import org.elasticsearch.xpack.esql.core.tree.Source; -import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.FunctionName; -import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; - -import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; - -@FunctionName("st_geotile_to_string") -public class StGeotileToStringTests extends SpatialGridTypeConversionTestCases { - public StGeotileToStringTests(@Name("TestCase") Supplier testCaseSupplier) { - this.testCase = testCaseSupplier.get(); - } - - @ParametersFactory - public static Iterable parameters() { - final List suppliers = new ArrayList<>(); - forUnaryGeoPoint( - DataType.LONG, - suppliers, - "StGeotileToStringFromLongEvaluator[gridId=Attribute[channel=0]]", - KEYWORD, - g -> StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), - StGeotileToStringTests::valueOf - ); - forUnaryGeoPoint( - DataType.KEYWORD, - suppliers, - "Attribute[channel=0]", - KEYWORD, - g -> new BytesRef(GeoTileUtils.stringEncode(StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), - StGeotileToStringTests::valueOf - ); - return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); - } - - private static BytesRef valueOf(Object gridid) { - return (gridid instanceof Long hash) ? new BytesRef(GeoTileUtils.stringEncode(hash)) : (BytesRef) gridid; - } - - @Override - protected Expression build(Source source, List args) { - return new StGeotileToString(source, args.get(0)); - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EqualsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EqualsTests.java index 4b9f21187f425..410919ac0fad5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EqualsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/EqualsTests.java @@ -236,6 +236,22 @@ public static Iterable parameters() { ) ); + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "EqualsLongsEvaluator", + "lhs", + "rhs", + Object::equals, + DataType.BOOLEAN, + TestCaseSupplier.geoGridCases(gridType), + TestCaseSupplier.geoGridCases(gridType), + List.of(), + false + ) + ); + } + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java index 95001366f1cad..f7646489419c3 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java @@ -233,6 +233,22 @@ public static Iterable parameters() { ) ); + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "NotEqualsLongsEvaluator", + "lhs", + "rhs", + (l, r) -> false == l.equals(r), + DataType.BOOLEAN, + TestCaseSupplier.geoGridCases(gridType), + TestCaseSupplier.geoGridCases(gridType), + List.of(), + false + ) + ); + } + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java index d5aa1af7feec2..6d5ed4f16f242 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java @@ -664,7 +664,7 @@ private static Block.Builder blockBuilder( }; if (extractPreference == DOC_VALUES && DataType.isSpatialPoint(dataType)) { return blockFactory.newLongBlockBuilder(estimatedSize); - } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatial(dataType)) { + } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatialAndGrid(dataType)) { return blockFactory.newIntBlockBuilder(estimatedSize); } else { return elementType.newBlockBuilder(estimatedSize, blockFactory); @@ -674,7 +674,7 @@ private static Block.Builder blockBuilder( private static TestBlockCopier blockCopier(DataType dataType, FieldExtractPreference extractPreference, IntVector docIndices) { if (extractPreference == DOC_VALUES && DataType.isSpatialPoint(dataType)) { return TestSpatialPointStatsBlockCopier.create(docIndices, dataType); - } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatial(dataType)) { + } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatialAndGrid(dataType)) { return TestSpatialShapeExtentBlockCopier.create(docIndices, dataType); } else { return new TestBlockCopier(docIndices); From 9963d1d430d5e2db216624291cca544112095e17 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 17 Jun 2025 19:14:04 +0200 Subject: [PATCH 02/47] Update docs/changelog/129581.yaml --- docs/changelog/129581.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/129581.yaml diff --git a/docs/changelog/129581.yaml b/docs/changelog/129581.yaml new file mode 100644 index 0000000000000..a18b7d1841540 --- /dev/null +++ b/docs/changelog/129581.yaml @@ -0,0 +1,5 @@ +pr: 129581 +summary: "Support geohash, geotile and geohex grid types" +area: "ES|QL, Geo" +type: enhancement +issues: [] From b84befe3d608aa9455d228f6d0e13cd7c99f3ee1 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 17 Jun 2025 19:14:55 +0200 Subject: [PATCH 03/47] Use type-casting syntax to be sure it works --- .../testFixtures/src/main/resources/spatial-grid.csv-spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 9279c58019e1d..1ef97ca05e68c 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -275,7 +275,7 @@ required_capability: spatial_grid ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (6.351574736181647 51.8981519783847)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) | MV_EXPAND location -| WHERE ST_INTERSECTS(location, TO_GEOHASH("u1")) +| WHERE ST_INTERSECTS(location, "u1"::geohash) ; location:geo_point @@ -610,7 +610,7 @@ required_capability: spatial_grid ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (24.516750878736943 23.93036561181085)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) | MV_EXPAND location -| WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3")) +| WHERE ST_INTERSECTS(location, "3/4/3"::geotile) ; location:geo_point @@ -1014,7 +1014,7 @@ required_capability: spatial_grid ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (2.475211258445467 41.32352174592337)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) | MV_EXPAND location -| WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff")) +| WHERE ST_INTERSECTS(location, "81397ffffffffff"::geohex) ; location:geo_point From a095433bf9ec816b9dd5f0213d657356b7f20a93 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 17 Jun 2025 19:19:30 +0200 Subject: [PATCH 04/47] Fix changelog yaml --- docs/changelog/129581.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog/129581.yaml b/docs/changelog/129581.yaml index a18b7d1841540..a7fd38838836d 100644 --- a/docs/changelog/129581.yaml +++ b/docs/changelog/129581.yaml @@ -1,5 +1,5 @@ pr: 129581 summary: "Support geohash, geotile and geohex grid types" -area: "ES|QL, Geo" +area: "ES|QL" type: enhancement issues: [] From 996d1ed9c55afa5a23f881d015fea04853fcf77e Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 18 Jun 2025 13:56:53 +0200 Subject: [PATCH 05/47] New capability due to behaviour change --- .../src/main/resources/spatial-grid.csv-spec | 116 +++++++++--------- .../xpack/esql/action/EsqlCapabilities.java | 5 + 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 1ef97ca05e68c..03d7eda82bee6 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -3,7 +3,7 @@ ############################################### toGeohash -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geohash[] ROW string = "u3bu" @@ -18,7 +18,7 @@ u3bu | u3bu ; toGeohashToLong -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geohash_to_long[] ROW string = "u3bu" @@ -34,7 +34,7 @@ u3bu | u3bu | 13686180 ; geohashLongToString -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::geohash_to_string[] ROW geohash = 13686180::long @@ -49,7 +49,7 @@ geohash:long | geohashString:keyword ; geohashStringToGeoShape -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::geohash_to_geoshape[] ROW hash = "u3bu" @@ -64,7 +64,7 @@ u3bu | POLYGON((12.3046875 55.546875, 12.65625 55.546875, 12.65625 55.72 ; geohashLongToGeoShape -required_capability: spatial_grid +required_capability: spatial_grid_types ROW hash = TO_LONG(13686180) | EVAL boundary = TO_GEOSHAPE(TO_GEOHASH(hash)) @@ -75,7 +75,7 @@ hash:long | boundary:geo_shape ; geohashLiteral -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geohash_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") @@ -93,7 +93,7 @@ POINT(12.6493508684508 55.6285017221528) | u3bu | u3b ; geohashLiteralString -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohash4 = TO_STRING(ST_GEOHASH(location, 4)), @@ -107,7 +107,7 @@ POINT(12.6493508684508 55.6285017221528) | u3bu | u3b | u3 | u ; geohashLiteralLong -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohash4 = TO_LONG(ST_GEOHASH(location, 4)), @@ -121,7 +121,7 @@ POINT (12.6493508684508 55.6285017221528) | 13686180 | 427683 | 1336 ; geohashField -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE abbrev == "CPH" @@ -134,7 +134,7 @@ u3buryf | CPH | Copenhagen | POINT (12.6493508684508 55.62850 ; gridGeohashStatsBy -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::st_geohash-grid[] FROM airports @@ -173,7 +173,7 @@ count:long | centroid:geo_point | geohashString:keyw ; gridGeohashQuery -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_GEOHASH(location, 1) == TO_GEOHASH("7") @@ -196,7 +196,7 @@ count:long | centroid:geo_point | geohashString:keyw ; gridGeohashStatsByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL geohash = ST_GEOHASH(location, 2, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) @@ -226,7 +226,7 @@ count:long | centroid:geo_point | geohashString:keywo ; gridGeohashStatsByBoundsEnvelope -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | 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))"))) @@ -256,7 +256,7 @@ count:long | centroid:geo_point | geohashString:keywo ; gridGeohashDocsFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOHASH("u1")) @@ -270,7 +270,7 @@ count:long | centroid:geo_point ; gridGeohashLiteralFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (6.351574736181647 51.8981519783847)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) @@ -283,7 +283,7 @@ POINT (6.351574736181647 51.8981519783847) ; gridGeohashStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -304,7 +304,7 @@ count:long | centroid:geo_point | geohashString:keywo ; gridGeohashStatsByBoundsUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL bounds = ST_ENVELOPE(TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -329,7 +329,7 @@ count:long | centroid:geo_point | geohashString:keywo ; gridGeohashInStatsBy -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | STATS @@ -355,7 +355,7 @@ count:long | centroid:geo_point ; gridGeohashInStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -377,7 +377,7 @@ count:long | centroid:geo_point ############################################### toGeotile -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geotile[] ROW string = "4/8/5" @@ -392,7 +392,7 @@ string:keyword | geotile:geotile ; toGeotileToLong -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geotile_to_long[] ROW string = "4/8/5" @@ -408,7 +408,7 @@ string:keyword | geotile:geotile | geotileLong:long ; geotileLongToString -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::geotile_to_string[] ROW geotile = 1152921508901814277 @@ -423,7 +423,7 @@ geotile:long | geotileString:keyword ; geotileStringToGeoshape -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::geotile_to_geoshape[] ROW tile = "4/8/5" @@ -438,7 +438,7 @@ tile:keyword | boundary:geo_shape ; geotileLiteral -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::st_geotile_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") @@ -456,7 +456,7 @@ POINT (12.6493508684508 55.6285017221528) | 4/8/5 | 3/4/2 ; geotileLiteralString -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geotile4 = TO_STRING(ST_GEOTILE(location, 4)), @@ -470,7 +470,7 @@ POINT (12.6493508684508 55.6285017221528) | 4/8/5 | 3/4/2 ; geotileLiteralLong -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geotile4 = TO_LONG(ST_GEOTILE(location, 4)), @@ -484,7 +484,7 @@ POINT (12.6493508684508 55.6285017221528) | 1152921508901814277 | 86469113060261 ; geotileField -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE abbrev == "CPH" @@ -497,7 +497,7 @@ geotile:geotile | abbrev:keyword | name:text | location:geo_point ; gridGeotileStatsBy -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::st_geotile-grid[] FROM airports @@ -529,7 +529,7 @@ count:long | centroid:geo_point | geotileString:key ; gridGeotileQuery -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_GEOTILE(location, 2) == TO_GEOTILE("2/0/2") @@ -549,7 +549,7 @@ count:long | centroid:geo_point | geotileString:keyw ; gridGeotileStatsByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL geotile = ST_GEOTILE(location, 3, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) @@ -570,7 +570,7 @@ count:long | centroid:geo_point | geotileString:keywor ; gridGeotileStatsByBoundsEnvelope -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | 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))"))) @@ -591,7 +591,7 @@ count:long | centroid:geo_point | geotileString:keywor ; gridGeotileDocsFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3")) @@ -605,7 +605,7 @@ count:long | centroid:geo_point ; gridGeotileLiteralFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (24.516750878736943 23.93036561181085)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) @@ -618,7 +618,7 @@ POINT (24.516750878736943 23.93036561181085) ; gridGeotileStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -639,7 +639,7 @@ count:long | centroid:geo_point | geotileString:keywo ; gridGeotileStatsByBoundsUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL bounds = ST_ENVELOPE(TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -663,7 +663,7 @@ count:long | centroid:geo_point | geotileString:keywo ; gridGeotileInStatsBy -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | STATS @@ -683,7 +683,7 @@ count:long | centroid:geo_point ; gridGeotileInStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -704,7 +704,7 @@ count:long | centroid:geo_point ############################################### toGeohex -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geohex[] ROW string = "841f059ffffffff" @@ -719,7 +719,7 @@ string:keyword | geohex:geohex ; toGeohexToLong -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::to_geohex_to_long[] ROW string = "841f059ffffffff" @@ -735,7 +735,7 @@ string:keyword | geohex:geohex | geohexLong:long ; geohexLongToGeoHex -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::long_to_geohex[] ROW gridId = 595020895127339007 @@ -750,7 +750,7 @@ gridId:long | geohex:geohex ; geohexStringToGeoshape -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::geohex_to_geoshape[] ROW hex = "841f059ffffffff" @@ -765,7 +765,7 @@ hex:keyword | boundary:geo_shape ; geohexLiteral -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::st_geohex_literal[] ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") @@ -783,7 +783,7 @@ POINT (12.6493508684508 55.6285017221528) | 841f059ffffffff | 831f05fffffffff | ; geohexLiteralString -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohex4 = TO_STRING(ST_GEOHEX(location, 4)), @@ -797,7 +797,7 @@ POINT (12.6493508684508 55.6285017221528) | 841f059ffffffff | 831f05fffffffff | ; geohexLiteralLong -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohex4 = TO_LONG(ST_GEOHEX(location, 4)), @@ -811,7 +811,7 @@ POINT (12.6493508684508 55.6285017221528) | 595020895127339007 | 590517321269772 ; geohexField -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE abbrev == "CPH" @@ -824,7 +824,7 @@ geohex:geohex | abbrev:keyword | name:text | location:geo_point ; gridGeohexStatsBy -required_capability: spatial_grid +required_capability: spatial_grid_types // tag::st_geohex-grid[] FROM airports @@ -857,7 +857,7 @@ count:long | centroid:geo_point | geohexString:keywo ; gridGeohexQuery -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_GEOHEX(location, 1) == TO_GEOHEX("812bbffffffffff") @@ -881,7 +881,7 @@ count:long | centroid:geo_point | geohexString:keywor ; gridGeohexStatsByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) @@ -911,7 +911,7 @@ count:long | centroid:geo_point | geohexString:keywor ; gridGeohexStatsByBoundsEnvelope -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | 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))"))) @@ -940,7 +940,7 @@ count:long | centroid:geo_point | geohexString:keywor ; gridGeohexQueryBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) @@ -959,7 +959,7 @@ TLL | POINT (24.798964869983 59.4165014697451) | 8108bffffffffff ; gridGeohexByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE abbrev IN ("RTW", "TIP", "XMN") @@ -975,7 +975,7 @@ XMN | POINT (118.12696884672 24.537192570557) | null ; literalGridGeohexByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = ["POINT (46.035023249891 51.5606456508842)", "POINT (13.1442589810713 32.6691695504993)", "POINT (118.12696884672 24.537192570557)"] | MV_EXPAND location @@ -995,7 +995,7 @@ POINT (118.12696884672 24.537192570557) | 8141bffffffffff | null ; gridGeohexDocsFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff")) @@ -1009,7 +1009,7 @@ count:long | centroid:geo_point ; gridGeohexLiteralFromCell -required_capability: spatial_grid +required_capability: spatial_grid_types ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (2.475211258445467 41.32352174592337)", "POINT (5.268637698941997 42.747250193330856)"] | EVAL location = TO_GEOPOINT(location) @@ -1023,7 +1023,7 @@ POINT (5.268637698941997 42.747250193330856) ; gridGeohexStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -1046,7 +1046,7 @@ count:long | centroid:geo_point | geohexString:keywor ; gridGeohexStatsByBoundsUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | EVAL bounds = ST_ENVELOPE(TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) @@ -1080,7 +1080,7 @@ count:long | centroid:geo_point | geohexString:keywo ; gridGeohexInStatsByBounds -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | STATS @@ -1100,7 +1100,7 @@ count:long | centroid:geo_point ; gridGeohexInStatsByWhereUK -required_capability: spatial_grid +required_capability: spatial_grid_types FROM airports | WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))")) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index f685804ae6ad3..bf122a6da3964 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -384,6 +384,11 @@ public enum Cap { */ SPATIAL_GRID, + /** + * Support geohash, geotile and geohex data types. Done in #129581 + */ + SPATIAL_GRID_TYPES, + /** * Fix to GROK and DISSECT that allows extracting attributes with the same name as the input * https://github.com/elastic/elasticsearch/issues/110184 From 71ca7bbea39807997bdd4a5591974d4aff69d297 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 18 Jun 2025 14:12:58 +0200 Subject: [PATCH 06/47] Fix failing tests Added EsqlCapabily to block older BWC Changed license IT to new API --- .../spatial/SpatialGridLicenseTestCase.java | 30 ++++++++++++++----- .../esql/spatial/StGeohashLicenseIT.java | 17 +++++------ .../xpack/esql/spatial/StGeohexLicenseIT.java | 17 +++++------ .../esql/spatial/StGeotileLicenseIT.java | 17 +++++------ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java index 421bea9c0d69c..934b7d742273d 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java @@ -15,9 +15,12 @@ import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import org.junit.Before; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -40,7 +43,18 @@ public void setupIndex() throws Exception { protected abstract String gridFunction(); - protected abstract Map expectedValues(); + protected abstract DataType gridType(); + + protected abstract long pointToGridId(Point point); + + protected Map expectedValues() { + Map expected = new HashMap<>(); + for (Point point : testData) { + long gridId = pointToGridId(point); + expected.compute(EsqlDataTypeConverter.geoGridToString(gridId, gridType()), (k, v) -> v == null ? 1 : v + 1); + } + return expected; + } protected int precision() { return 1; // Default precision for grid function tests, can be overridden in subclasses @@ -69,11 +83,11 @@ protected void assertGeoGridFromIndex(String index) { """, index, gridFunction(), precision()); try (var resp = run(query)) { assertColumnNames(resp.columns(), List.of("gridId", "count")); - assertColumnTypes(resp.columns(), List.of("long", "long")); - Map values = getValuesMap(resp.values()); - Map expected = expectedValues(); + assertColumnTypes(resp.columns(), List.of(gridType().typeName(), "long")); + Map values = getValuesMap(resp.values()); + Map expected = expectedValues(); assertThat(values.size(), equalTo(expected.size())); - for (Long gridId : expected.keySet()) { + for (String gridId : expected.keySet()) { assertThat("Missing grid-id: " + gridId, values.containsKey(gridId), equalTo(true)); assertThat("Unexpected count for grid-id: " + gridId, values.get(gridId), equalTo(expected.get(gridId))); } @@ -97,9 +111,9 @@ protected void assertGeoGridFailsWith(String index) { assertThat(e.getMessage(), containsString(expectedError)); } - public static Map getValuesMap(Iterator> values) { - var valuesMap = new LinkedHashMap(); - values.forEachRemaining(row -> { valuesMap.put(((Number) row.next()).longValue(), ((Number) row.next()).longValue()); }); + public static Map getValuesMap(Iterator> values) { + var valuesMap = new LinkedHashMap(); + values.forEachRemaining(row -> { valuesMap.put(row.next().toString(), ((Number) row.next()).longValue()); }); return valuesMap; } diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohashLicenseIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohashLicenseIT.java index c3e50b9b87b5d..ade5753087a49 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohashLicenseIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohashLicenseIT.java @@ -10,13 +10,12 @@ import org.elasticsearch.geometry.Point; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.esql.action.EsqlPluginWithEnterpriseOrTrialLicense; +import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash; import org.elasticsearch.xpack.spatial.SpatialPlugin; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class StGeohashLicenseIT extends SpatialGridLicenseTestCase { @Override @@ -30,13 +29,13 @@ protected String gridFunction() { } @Override - protected Map expectedValues() { - Map expected = new HashMap<>(); - for (Point point : testData) { - long gridId = StGeohash.unboundedGrid.calculateGridId(point, precision()); - expected.compute(gridId, (k, v) -> v == null ? 1 : v + 1); - } - return expected; + protected DataType gridType() { + return DataType.GEOHASH; + } + + @Override + protected long pointToGridId(Point point) { + return StGeohash.unboundedGrid.calculateGridId(point, precision()); } public void testGeoGridWithShapes() { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohexLicenseIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohexLicenseIT.java index 5bc4eef4e78a7..55e2002b997c0 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohexLicenseIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeohexLicenseIT.java @@ -10,13 +10,12 @@ import org.elasticsearch.geometry.Point; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.esql.action.EsqlPluginWithEnterpriseOrTrialLicense; +import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex; import org.elasticsearch.xpack.spatial.SpatialPlugin; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class StGeohexLicenseIT extends SpatialGridLicenseTestCase { @Override @@ -30,13 +29,13 @@ protected String gridFunction() { } @Override - protected Map expectedValues() { - Map expected = new HashMap<>(); - for (Point point : testData) { - long gridId = StGeohex.unboundedGrid.calculateGridId(point, precision()); - expected.compute(gridId, (k, v) -> v == null ? 1 : v + 1); - } - return expected; + protected DataType gridType() { + return DataType.GEOHEX; + } + + @Override + protected long pointToGridId(Point point) { + return StGeohex.unboundedGrid.calculateGridId(point, precision()); } public void testGeoGridWithShapes() { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeotileLicenseIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeotileLicenseIT.java index d5f42c43587e2..ad0200bd32ce5 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeotileLicenseIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/StGeotileLicenseIT.java @@ -10,13 +10,12 @@ import org.elasticsearch.geometry.Point; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.esql.action.EsqlPluginWithEnterpriseOrTrialLicense; +import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile; import org.elasticsearch.xpack.spatial.SpatialPlugin; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class StGeotileLicenseIT extends SpatialGridLicenseTestCase { @Override @@ -30,13 +29,13 @@ protected String gridFunction() { } @Override - protected Map expectedValues() { - Map expected = new HashMap<>(); - for (Point point : testData) { - long gridId = StGeotile.unboundedGrid.calculateGridId(point, precision()); - expected.compute(gridId, (k, v) -> v == null ? 1 : v + 1); - } - return expected; + protected DataType gridType() { + return DataType.GEOTILE; + } + + @Override + protected long pointToGridId(Point point) { + return StGeotile.unboundedGrid.calculateGridId(point, precision()); } public void testGeoGridWithShapes() { From 625d918f9d99000473f341adf5a48ac7f1cc71b2 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 18 Jun 2025 22:18:37 +0200 Subject: [PATCH 07/47] Disable broken lucene pushdown --- .../scalar/spatial/BinarySpatialFunction.java | 14 ++++++++------ .../scalar/spatial/SpatialRelatesFunction.java | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index 6fc237a91fa5a..3f0b77baa0355 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -297,17 +297,19 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd // The use of foldable here instead of SpatialEvaluatorFieldKey.isConstant is intentional to match the behavior of the // Lucene pushdown code in EsqlTranslationHandler::SpatialRelatesTranslator // We could enhance both places to support ReferenceAttributes that refer to constants, but that is a larger change - return isPushableSpatialAttribute(left(), pushdownPredicates) && right().foldable() - || isPushableSpatialAttribute(right(), pushdownPredicates) && left().foldable() + return isPushableSpatialAttribute(left(), pushdownPredicates) && isPushableLiteralAttribute(right()) + || isPushableSpatialAttribute(right(), pushdownPredicates) && isPushableLiteralAttribute(left()) ? TranslationAware.Translatable.YES : TranslationAware.Translatable.NO; } private static boolean isPushableSpatialAttribute(Expression exp, LucenePushdownPredicates p) { - return exp instanceof FieldAttribute fa - && DataType.isSpatialAndGrid(fa.dataType()) - && fa.getExactInfo().hasExact() - && p.isIndexed(fa); + return exp instanceof FieldAttribute fa && DataType.isSpatial(fa.dataType()) && fa.getExactInfo().hasExact() && p.isIndexed(fa); + } + + private static boolean isPushableLiteralAttribute(Expression exp) { + // TODO: Support pushdown of geo-grid queries where the constant is a geo-grid-id literal + return DataType.isSpatial(exp.dataType()) && exp.foldable(); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java index feade885653bb..292156f541542 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java @@ -316,6 +316,7 @@ private Query translate(TranslatorHandler handler, Expression spatialExpression, String name = handler.nameOf(attribute); try { + // TODO: Support geo-grid query pushdown Geometry shape = SpatialRelatesUtils.makeGeometryFromLiteral(FoldContext.small() /* TODO remove me */, constantExpression); return new SpatialRelatesQuery(source(), name, queryRelation(), shape, attribute.dataType()); } catch (IllegalArgumentException e) { From 53ea500c44a7ca671c1cfcb4dea4e45ccd2720af Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 20 Jun 2025 13:32:21 +0200 Subject: [PATCH 08/47] Fix failing tests --- .../elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java | 5 ++++- .../elasticsearch/xpack/esql/action/LookupJoinTypesIT.java | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java index 1ef49652c3afc..195e777efeee5 100644 --- a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java +++ b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java @@ -689,6 +689,9 @@ public void testSuggestedCast() throws IOException { Set shouldBeSupported = Stream.of(DataType.values()).filter(DataType::isRepresentable).collect(Collectors.toSet()); shouldBeSupported.remove(DataType.CARTESIAN_POINT); shouldBeSupported.remove(DataType.CARTESIAN_SHAPE); + shouldBeSupported.remove(DataType.GEOHASH); + shouldBeSupported.remove(DataType.GEOTILE); + shouldBeSupported.remove(DataType.GEOHEX); shouldBeSupported.remove(DataType.NULL); shouldBeSupported.remove(DataType.DOC_DATA_TYPE); shouldBeSupported.remove(DataType.TSID_DATA_TYPE); @@ -697,7 +700,7 @@ public void testSuggestedCast() throws IOException { shouldBeSupported.remove(DataType.AGGREGATE_METRIC_DOUBLE); } for (DataType type : shouldBeSupported) { - assertTrue(typesAndValues.containsKey(type)); + assertTrue(type.typeName(), typesAndValues.containsKey(type)); } assertThat(typesAndValues.size(), equalTo(shouldBeSupported.size())); diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/LookupJoinTypesIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/LookupJoinTypesIT.java index df021f27a31fe..e34d90e7ba206 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/LookupJoinTypesIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/LookupJoinTypesIT.java @@ -48,6 +48,9 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DOC_DATA_TYPE; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; import static org.elasticsearch.xpack.esql.core.type.DataType.FLOAT; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.HALF_FLOAT; import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.IP; @@ -176,6 +179,9 @@ protected Collection> nodePlugins() { || type == DOC_DATA_TYPE || type == TSID_DATA_TYPE || type == AGGREGATE_METRIC_DOUBLE + || type == GEOHASH + || type == GEOTILE + || type == GEOHEX || type.esType() == null || type.isCounter() || DataType.isRepresentable(type) == false) { From ade842b86abffd1320dac4f3c89250dc6ea62a48 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 4 Jul 2025 15:26:28 +0200 Subject: [PATCH 09/47] Regenerate docs after merging main --- .../esql/_snippets/functions/description/md5.md | 2 +- .../esql/_snippets/functions/examples/knn.md | 10 ++-------- .../_snippets/functions/functionNamedParams/knn.md | 3 --- .../esql/_snippets/functions/parameters/knn.md | 3 +++ .../esql/kibana/definition/functions/md5.json | 2 +- .../esql/kibana/definition/functions/st_geohash.json | 2 +- .../esql/kibana/definition/functions/st_geohex.json | 2 +- .../esql/kibana/definition/functions/st_geotile.json | 2 +- .../esql/kibana/definition/operators/is_not_null.json | 6 +++--- .../esql/kibana/definition/operators/is_null.json | 6 +++--- .../query-languages/esql/kibana/docs/functions/knn.md | 2 +- .../query-languages/esql/kibana/docs/functions/md5.md | 2 +- 12 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/md5.md b/docs/reference/query-languages/esql/_snippets/functions/description/md5.md index 976d3e48a6bfa..cf702ee523749 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/description/md5.md +++ b/docs/reference/query-languages/esql/_snippets/functions/description/md5.md @@ -2,5 +2,5 @@ **Description** -Computes the MD5 hash of the input. +Computes the MD5 hash of the input (if the MD5 hash is available on the JVM). diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/knn.md b/docs/reference/query-languages/esql/_snippets/functions/examples/knn.md index 2a474d7bfef13..df15bde7deb55 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/knn.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/knn.md @@ -1,10 +1,10 @@ % This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. -**Examples** +**Example** ```esql from colors metadata _score -| where knn(rgb_vector, [0, 120, 0]) +| where knn(rgb_vector, [0, 120, 0], 10) | sort _score desc, color asc ``` @@ -21,10 +21,4 @@ from colors metadata _score | gray | [128.0, 128.0, 128.0] | | chartreuse | [127.0, 255.0, 0.0] | -```esql -from colors metadata _score -| where knn(rgb_vector, [0,255,255], {"k": 4}) -| sort _score desc, color asc -``` - diff --git a/docs/reference/query-languages/esql/_snippets/functions/functionNamedParams/knn.md b/docs/reference/query-languages/esql/_snippets/functions/functionNamedParams/knn.md index d663e403f8a42..1e87271707676 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/functionNamedParams/knn.md +++ b/docs/reference/query-languages/esql/_snippets/functions/functionNamedParams/knn.md @@ -8,9 +8,6 @@ `boost` : (float) Floating point number used to decrease or increase the relevance scores of the query.Defaults to 1.0. -`k` -: (integer) The number of nearest neighbors to return from each shard. Elasticsearch collects k results from each shard, then merges them to find the global top results. This value must be less than or equal to num_candidates. Defaults to 10. - `rescore_oversample` : (double) Applies the specified oversampling for rescoring quantized vectors. See [oversampling and rescoring quantized vectors](docs-content://solutions/search/vector/knn.md#dense-vector-knn-search-rescoring) for details. diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/knn.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/knn.md index fb1b98a1e8a7a..e33acabbd014f 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/knn.md +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/knn.md @@ -8,6 +8,9 @@ `query` : Vector value to find top nearest neighbours for. +`k` +: The number of nearest neighbors to return from each shard. Elasticsearch collects k results from each shard, then merges them to find the global top results. This value must be less than or equal to num_candidates. + `options` : (Optional) kNN additional options as [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params). See [knn query](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-knn-query) for more information. diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/md5.json b/docs/reference/query-languages/esql/kibana/definition/functions/md5.json index b3d320ad838b4..b08d3681e6169 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/md5.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/md5.json @@ -2,7 +2,7 @@ "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", "type" : "scalar", "name" : "md5", - "description" : "Computes the MD5 hash of the input.", + "description" : "Computes the MD5 hash of the input (if the MD5 hash is available on the JVM).", "signatures" : [ { "params" : [ diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json index 725d1613aa8d2..6c041ebe4b43d 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json @@ -51,5 +51,5 @@ "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" ], "preview" : true, - "snapshot_only" : true + "snapshot_only" : false } diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json index fa5d2c7662891..8a017d5bf2bfc 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json @@ -54,5 +54,5 @@ "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" ], "preview" : true, - "snapshot_only" : true + "snapshot_only" : false } diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json index 53cda0965e257..bbfcd42b60ec2 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json @@ -51,5 +51,5 @@ "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" ], "preview" : true, - "snapshot_only" : true + "snapshot_only" : false } diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json b/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json index 6530c9496f550..c3cc8fae2a14e 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/is_not_null.json @@ -144,7 +144,7 @@ "name" : "field", "type" : "geohash", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, @@ -156,7 +156,7 @@ "name" : "field", "type" : "geohex", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, @@ -168,7 +168,7 @@ "name" : "field", "type" : "geotile", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, diff --git a/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json b/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json index 63ee0689233b2..08c98810ddede 100644 --- a/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json +++ b/docs/reference/query-languages/esql/kibana/definition/operators/is_null.json @@ -144,7 +144,7 @@ "name" : "field", "type" : "geohash", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, @@ -156,7 +156,7 @@ "name" : "field", "type" : "geohex", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, @@ -168,7 +168,7 @@ "name" : "field", "type" : "geotile", "optional" : false, - "description" : "Input value. The input can be a single- or multi-valued column or an expression." + "description" : "Value to check. It can be a single- or multi-valued column or an expression." } ], "variadic" : false, diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/knn.md b/docs/reference/query-languages/esql/kibana/docs/functions/knn.md index c7af797488ba4..f32319b080dbb 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/knn.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/knn.md @@ -1,4 +1,4 @@ -% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. ### KNN Finds the k nearest vectors to a query vector, as measured by a similarity metric. knn function finds nearest vectors through approximate search on indexed dense_vectors. diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/md5.md b/docs/reference/query-languages/esql/kibana/docs/functions/md5.md index 4229afca7398a..e96666870dc97 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/md5.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/md5.md @@ -1,7 +1,7 @@ % This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. ### MD5 -Computes the MD5 hash of the input. +Computes the MD5 hash of the input (if the MD5 hash is available on the JVM). ```esql FROM sample_data From c152331527563cabe2afc2f9bd93bad250c7af4c Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 4 Jul 2025 16:09:28 +0200 Subject: [PATCH 10/47] Some fixes after review --- .../elasticsearch/xpack/esql/CsvTestUtils.java | 4 +--- .../predicate/operator/comparison/In.java | 8 ++++++-- .../xpack/esql/type/EsqlDataTypeConverter.java | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java index d5b359d4f79a9..0c4a38a933bed 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java @@ -491,9 +491,7 @@ public enum Type { GEO_SHAPE(x -> x == null ? null : GEO.wktToWkb(x), BytesRef.class), CARTESIAN_SHAPE(x -> x == null ? null : CARTESIAN.wktToWkb(x), BytesRef.class), GEOHASH(x -> x == null ? null : Geohash.longEncode(x), Long.class), - GEOTILE(x -> x == null ? null : GeoTileUtils.longEncode(x), (l, r) -> { - return 0; - }, Long.class), + GEOTILE(x -> x == null ? null : GeoTileUtils.longEncode(x), Long.class), GEOHEX(x -> x == null ? null : H3.stringToH3(x), Long.class), AGGREGATE_METRIC_DOUBLE( x -> x == null ? null : stringToAggregateMetricDoubleLiteral(x), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java index 50493f73a6ae9..3178914080bd0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java @@ -339,7 +339,11 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua if (commonType == INTEGER) { return new InIntEvaluator.Factory(source(), lhs, factories); } - if (commonType == LONG || commonType == DATETIME || commonType == DATE_NANOS || commonType == UNSIGNED_LONG) { + if (commonType == LONG + || commonType == DATETIME + || commonType == DATE_NANOS + || commonType == UNSIGNED_LONG + || DataType.isGeoGrid(commonType)) { return new InLongEvaluator.Factory(source(), lhs, factories); } if (commonType == KEYWORD @@ -347,7 +351,7 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua || commonType == IP || commonType == VERSION || commonType == UNSUPPORTED - || DataType.isSpatialAndGrid(commonType)) { + || DataType.isSpatial(commonType)) { return new InBytesRefEvaluator.Factory(source(), toEvaluator.apply(value), factories); } if (commonType == NULL) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java index 67a60a57a73dc..43eec77135e14 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java @@ -253,9 +253,18 @@ public static Converter converterFor(DataType from, DataType to) { if (DataType.isSpatialGeo(to)) { return EsqlConverter.STRING_TO_GEO; } - if (DataType.isSpatialAndGrid(to)) { + if (DataType.isSpatial(to)) { return EsqlConverter.STRING_TO_SPATIAL; } + if (to == DataType.GEOHASH) { + return EsqlConverter.STRING_TO_GEOHASH; + } + if (to == DataType.GEOTILE) { + return EsqlConverter.STRING_TO_GEOTILE; + } + if (to == DataType.GEOHEX) { + return EsqlConverter.STRING_TO_GEOHEX; + } if (to == DataType.TIME_DURATION) { return EsqlConverter.STRING_TO_TIME_DURATION; } @@ -814,7 +823,10 @@ public enum EsqlConverter implements Converter { STRING_TO_INT(x -> EsqlDataTypeConverter.stringToInt(BytesRefs.toString(x))), STRING_TO_BOOLEAN(x -> EsqlDataTypeConverter.stringToBoolean(BytesRefs.toString(x))), STRING_TO_GEO(x -> EsqlDataTypeConverter.stringToGeo(BytesRefs.toString(x))), - STRING_TO_SPATIAL(x -> EsqlDataTypeConverter.stringToSpatial(BytesRefs.toString(x))); + STRING_TO_SPATIAL(x -> EsqlDataTypeConverter.stringToSpatial(BytesRefs.toString(x))), + STRING_TO_GEOHASH(x -> Geohash.longEncode(BytesRefs.toString(x))), + STRING_TO_GEOTILE(x -> GeoTileUtils.longEncode(BytesRefs.toString(x))), + STRING_TO_GEOHEX(x -> H3.stringToH3(BytesRefs.toString(x))); private static final String NAME = "esql-converter"; private final Function converter; From bbd8c1d7452d78427cc1979c0e966b99400fa022 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 4 Jul 2025 16:18:10 +0200 Subject: [PATCH 11/47] Remove unneeded change --- .../xpack/esql/planner/TestPhysicalOperationProviders.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java index 35a514a1cd996..a8916f140ea1f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java @@ -666,7 +666,7 @@ private static Block.Builder blockBuilder( }; if (extractPreference == DOC_VALUES && DataType.isSpatialPoint(dataType)) { return blockFactory.newLongBlockBuilder(estimatedSize); - } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatialAndGrid(dataType)) { + } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatial(dataType)) { return blockFactory.newIntBlockBuilder(estimatedSize); } else { return elementType.newBlockBuilder(estimatedSize, blockFactory); @@ -676,7 +676,7 @@ private static Block.Builder blockBuilder( private static TestBlockCopier blockCopier(DataType dataType, FieldExtractPreference extractPreference, IntVector docIndices) { if (extractPreference == DOC_VALUES && DataType.isSpatialPoint(dataType)) { return TestSpatialPointStatsBlockCopier.create(docIndices, dataType); - } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatialAndGrid(dataType)) { + } else if (extractPreference == EXTRACT_SPATIAL_BOUNDS && DataType.isSpatial(dataType)) { return TestSpatialShapeExtentBlockCopier.create(docIndices, dataType); } else { return new TestBlockCopier(docIndices); From 7b5c3da8c71a03304ebd45383093d84104c4e2e3 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Thu, 10 Jul 2025 16:53:13 +0200 Subject: [PATCH 12/47] Code review updates --- .../xpack/esql/core/type/DataType.java | 18 ++++++------------ .../esql/expression/EsqlTypeResolutions.java | 4 ++-- .../function/scalar/multivalue/MvMax.java | 4 ++-- .../function/scalar/multivalue/MvMin.java | 4 ++-- .../scalar/spatial/BinarySpatialFunction.java | 6 +++--- .../scalar/spatial/SpatialRelatesFunction.java | 7 +++---- .../predicate/operator/comparison/In.java | 4 ++-- .../xpack/esql/planner/PlannerUtils.java | 2 +- .../spatial/BinarySpatialFunctionTestCase.java | 12 ++++++------ 9 files changed, 27 insertions(+), 34 deletions(-) diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java index 7e1b7eb5bad25..b01c63a0ce524 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java @@ -276,9 +276,9 @@ public enum DataType { // wild estimate for size, based on some test data (airport_city_boundaries) CARTESIAN_SHAPE(builder().esType("cartesian_shape").estimatedSize(200).docValues()), GEO_SHAPE(builder().esType("geo_shape").estimatedSize(200).docValues()), - GEOHASH(builder().esType("geohash").typeName("GEOHASH").estimatedSize(Long.BYTES)), - GEOTILE(builder().esType("geotile").typeName("GEOTILE").estimatedSize(Long.BYTES)), - GEOHEX(builder().esType("geohex").typeName("GEOHEX").estimatedSize(Long.BYTES)), + GEOHASH(builder().typeName("GEOHASH").estimatedSize(Long.BYTES)), + GEOTILE(builder().typeName("GEOTILE").estimatedSize(Long.BYTES)), + GEOHEX(builder().typeName("GEOHEX").estimatedSize(Long.BYTES)), /** * Fields with this type represent a Lucene doc id. This field is a bit magic in that: @@ -581,14 +581,8 @@ public static boolean isSpatial(DataType t) { return t == GEO_POINT || t == CARTESIAN_POINT || t == GEO_SHAPE || t == CARTESIAN_SHAPE; } - public static boolean isSpatialAndGrid(DataType t) { - return t == GEO_POINT - || t == CARTESIAN_POINT - || t == GEO_SHAPE - || t == CARTESIAN_SHAPE - || t == GEOHASH - || t == GEOTILE - || t == GEOHEX; + public static boolean isSpatialOrGrid(DataType t) { + return isSpatial(t) || isGeoGrid(t); } public static boolean isGeoGrid(DataType t) { @@ -596,7 +590,7 @@ public static boolean isGeoGrid(DataType t) { } public static boolean isSortable(DataType t) { - return false == (t == SOURCE || isCounter(t) || isSpatialAndGrid(t) || t == AGGREGATE_METRIC_DOUBLE); + return false == (t == SOURCE || isCounter(t) || isSpatialOrGrid(t) || t == AGGREGATE_METRIC_DOUBLE); } public String nameUpper() { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java index 01ac78a1f21ff..befeedb01cc9c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/EsqlTypeResolutions.java @@ -83,7 +83,7 @@ public static Expression.TypeResolution isSpatial(Expression e, String operation return isType(e, DataType::isSpatial, operationName, paramOrd, SPATIAL_TYPE_NAMES); } - public static Expression.TypeResolution isSpatialAndGrid(Expression e, String operationName, TypeResolutions.ParamOrdinal paramOrd) { - return isType(e, DataType::isSpatialAndGrid, operationName, paramOrd, SPATIAL_AND_GRID_TYPE_NAMES); + public static Expression.TypeResolution isSpatialOrGrid(Expression e, String operationName, TypeResolutions.ParamOrdinal paramOrd) { + return isType(e, DataType::isSpatialOrGrid, operationName, paramOrd, SPATIAL_AND_GRID_TYPE_NAMES); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java index 2bafe1ec45ac3..d02716f41999a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java @@ -27,7 +27,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.isRepresentable; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; /** * Reduce a multivalued field to a single valued field containing the maximum value. @@ -69,7 +69,7 @@ public String getWriteableName() { @Override protected TypeResolution resolveFieldType() { - return isType(field(), t -> isSpatialAndGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); + return isType(field(), t -> isSpatialOrGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java index efc281aa867bf..566dc5acf4067 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java @@ -27,7 +27,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.isRepresentable; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; /** * Reduce a multivalued field to a single valued field containing the minimum value. @@ -69,7 +69,7 @@ public String getWriteableName() { @Override protected TypeResolution resolveFieldType() { - return isType(field(), t -> isSpatialAndGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); + return isType(field(), t -> isSpatialOrGrid(t) == false && isRepresentable(t), sourceText(), null, "representableNonSpatial"); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index 3f0b77baa0355..2a3fa71faa04a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -157,7 +157,7 @@ protected Expression.TypeResolution isSpatial(Expression e, TypeResolutions.Para return pointsOnly ? EsqlTypeResolutions.isSpatialPoint(e, sourceText(), paramOrd) : (supportsGrid - ? EsqlTypeResolutions.isSpatialAndGrid(e, sourceText(), paramOrd) + ? EsqlTypeResolutions.isSpatialOrGrid(e, sourceText(), paramOrd) : EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd)); } @@ -217,7 +217,7 @@ protected TypeResolution isSameSpatialType( Predicate isSpatialType = pointsOnly ? dt -> dt == spatialDataType : (supportsGrid - ? dt -> DataType.isSpatialAndGrid(dt) && spatialCRSCompatible(spatialDataType, dt) + ? dt -> DataType.isSpatialOrGrid(dt) && spatialCRSCompatible(spatialDataType, dt) : dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt)); return isType(expression, isSpatialType, operationName, paramOrd, compatibleTypeNames(spatialDataType)); } @@ -267,7 +267,7 @@ public enum SpatialCrsType { public static SpatialCrsType fromDataType(DataType dataType) { return DataType.isSpatialGeo(dataType) ? SpatialCrsType.GEO - : DataType.isSpatialAndGrid(dataType) ? SpatialCrsType.CARTESIAN + : DataType.isSpatialOrGrid(dataType) ? SpatialCrsType.CARTESIAN : SpatialCrsType.UNSPECIFIED; } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java index 292156f541542..199ea60538905 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java @@ -12,7 +12,6 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.geo.ShapeRelation; import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.compute.data.BooleanBlock; import org.elasticsearch.compute.data.BytesRefBlock; import org.elasticsearch.compute.data.LongBlock; @@ -205,7 +204,7 @@ protected void processGeoPointDocValuesAndSourceGrid( } } - private long getGridId(Point point, @Fixed long gridId, @Fixed DataType gridType) { + private long getGridId(Point point, long gridId, DataType gridType) { return switch (gridType) { case GEOHASH -> Geohash.longEncode(point.getX(), point.getY(), Geohash.stringEncode(gridId).length()); case GEOTILE -> GeoTileUtils.longEncode( @@ -220,7 +219,7 @@ private long getGridId(Point point, @Fixed long gridId, @Fixed DataType gridType }; } - protected void processSourceAndConstant(BooleanBlock.Builder builder, int position, BytesRefBlock left, @Fixed Component2D right) + protected void processSourceAndConstant(BooleanBlock.Builder builder, int position, BytesRefBlock left, Component2D right) throws IOException { if (left.getValueCount(position) < 1) { builder.appendNull(); @@ -245,7 +244,7 @@ protected void processPointDocValuesAndConstant( BooleanBlock.Builder builder, int position, LongBlock leftValue, - @Fixed Component2D rightValue + Component2D rightValue ) throws IOException { if (leftValue.getValueCount(position) < 1) { builder.appendNull(); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java index 3178914080bd0..8bb62df1643bf 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java @@ -236,7 +236,7 @@ protected boolean areCompatible(DataType left, DataType right) { // automatic numerical conversions not applicable for UNSIGNED_LONG, see Verifier#validateUnsignedLongOperator(). return left == right; } - if (DataType.isSpatialAndGrid(left) && DataType.isSpatialAndGrid(right)) { + if (DataType.isSpatialOrGrid(left) && DataType.isSpatialOrGrid(right)) { return left == right; } return DataType.areCompatible(left, right); @@ -366,7 +366,7 @@ private DataType commonType() { if (e.dataType() == NULL && value.dataType() != NULL) { continue; } - if (DataType.isSpatialAndGrid(commonType)) { + if (DataType.isSpatialOrGrid(commonType)) { if (e.dataType() == commonType) { continue; } else { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java index 6d76732e78df5..29603ddbad523 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java @@ -266,7 +266,7 @@ && translatable(exp, ctx).finish() == TranslationAware.FinishedTranslatable.YES) * This specifically excludes spatial data types, which are not themselves sortable. */ public static ElementType toSortableElementType(DataType dataType) { - if (DataType.isSpatialAndGrid(dataType)) { + if (DataType.isSpatialOrGrid(dataType)) { return ElementType.UNKNOWN; } return toElementType(dataType); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index 34b7dde0d2978..28e486a0b954f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -32,7 +32,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialAndGrid; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction.compatibleTypeNames; @@ -171,7 +171,7 @@ protected static String typeErrorMessage( if (DataType.isGeoGrid(types.get(goodArgPosition))) { // When the valid position is a grid, the other type can only be points return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, true, supportsGrid); - } else if (isSpatialAndGrid(types.get(goodArgPosition)) == false) { + } else if (isSpatialOrGrid(types.get(goodArgPosition)) == false) { return oneInvalid(badArgPosition, -1, includeOrdinal, types, pointsOnly, supportsGrid); } else { return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, pointsOnly, supportsGrid); @@ -297,7 +297,7 @@ private static BinarySpatialFunction.BinarySpatialComparator spatialRelations ) { if (isSpatialGeo(leftType) || isSpatialGeo(rightType)) { return getRelationsField("GEO"); - } else if (isSpatialAndGrid(leftType) || isSpatialAndGrid(rightType)) { + } else if (isSpatialOrGrid(leftType) || isSpatialOrGrid(rightType)) { return getRelationsField("CARTESIAN"); } else { throw new IllegalArgumentException( @@ -325,7 +325,7 @@ protected static BytesRef asGeometryWKB(Object object, DataType dataType) { } protected static boolean typeCompatible(DataType leftType, DataType rightType) { - if (isSpatialAndGrid(leftType) && isSpatialAndGrid(rightType)) { + if (isSpatialOrGrid(leftType) && isSpatialOrGrid(rightType)) { // Both must be GEO_* or both must be CARTESIAN_* return countGeo(leftType, rightType) != 1; } @@ -333,9 +333,9 @@ protected static boolean typeCompatible(DataType leftType, DataType rightType) { } private static DataType pickSpatialType(DataType leftType, DataType rightType) { - if (isSpatialAndGrid(leftType)) { + if (isSpatialOrGrid(leftType)) { return leftType; - } else if (isSpatialAndGrid(rightType)) { + } else if (isSpatialOrGrid(rightType)) { return rightType; } else { throw new IllegalArgumentException("Invalid spatial types: " + leftType + " and " + rightType); From bc6ce57d0a7066084157555d790f0b96c10e68fc Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Thu, 10 Jul 2025 15:07:47 +0000 Subject: [PATCH 13/47] [CI] Auto commit changes from spotless --- .../function/scalar/spatial/BinarySpatialFunctionTestCase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index 28e486a0b954f..b79f3daeb9b5a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -32,8 +32,8 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction.compatibleTypeNames; import static org.hamcrest.Matchers.equalTo; From 0a81d1db15040b7bf48e33999984f9ce74f4eafd Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 11 Jul 2025 17:12:07 +0200 Subject: [PATCH 14/47] Fix some errors after moving from esType --- .../BinarySpatialFunctionTestCase.java | 24 +++++++++---------- .../spatial/SpatialGridFunctionTestCase.java | 16 ++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index 28e486a0b954f..ab0ef54599077 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -32,8 +32,8 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction.compatibleTypeNames; import static org.hamcrest.Matchers.equalTo; @@ -53,20 +53,20 @@ protected static Class getSpatialRelatesFunctionClass() throws ClassNotFoundE public static TestCaseSupplier.TypedDataSupplier testCaseSupplier(DataType dataType, boolean pointsOnly) { if (pointsOnly) { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } else { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case "geo_shape" -> TestCaseSupplier.geoShapeCases(() -> false).get(0); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); - case "cartesian_shape" -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); - case "geohash" -> TestCaseSupplier.geoGridCases(GEOHASH, () -> false).get(0); - case "geotile" -> TestCaseSupplier.geoGridCases(GEOTILE, () -> false).get(0); - case "geohex" -> TestCaseSupplier.geoGridCases(GEOHEX, () -> false).get(0); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case GEO_SHAPE -> TestCaseSupplier.geoShapeCases(() -> false).get(0); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + case CARTESIAN_SHAPE -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); + case GEOHASH -> TestCaseSupplier.geoGridCases(GEOHASH, () -> false).get(0); + case GEOTILE -> TestCaseSupplier.geoGridCases(GEOTILE, () -> false).get(0); + case GEOHEX -> TestCaseSupplier.geoGridCases(GEOHEX, () -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java index 3a3a09ea99b00..d25e98abefd7e 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java @@ -121,17 +121,17 @@ protected static void addTestCaseSuppliers( public static TestCaseSupplier.TypedDataSupplier testCaseSupplier(DataType dataType, boolean pointsOnly) { if (pointsOnly) { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).getFirst(); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).getFirst(); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).getFirst(); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).getFirst(); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } else { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).getFirst(); - case "geo_shape" -> TestCaseSupplier.geoShapeCases(() -> false).getFirst(); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).getFirst(); - case "cartesian_shape" -> TestCaseSupplier.cartesianShapeCases(() -> false).getFirst(); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).getFirst(); + case GEO_SHAPE -> TestCaseSupplier.geoShapeCases(() -> false).getFirst(); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).getFirst(); + case CARTESIAN_SHAPE -> TestCaseSupplier.cartesianShapeCases(() -> false).getFirst(); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } From 30614fc79d3ed051eb610f72dcb75d513817c069 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 11 Jul 2025 17:13:30 +0200 Subject: [PATCH 15/47] Bring back esType since it is required for outputType --- .../org/elasticsearch/xpack/esql/core/type/DataType.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java index b01c63a0ce524..b3f7acfe2eac4 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java @@ -276,9 +276,9 @@ public enum DataType { // wild estimate for size, based on some test data (airport_city_boundaries) CARTESIAN_SHAPE(builder().esType("cartesian_shape").estimatedSize(200).docValues()), GEO_SHAPE(builder().esType("geo_shape").estimatedSize(200).docValues()), - GEOHASH(builder().typeName("GEOHASH").estimatedSize(Long.BYTES)), - GEOTILE(builder().typeName("GEOTILE").estimatedSize(Long.BYTES)), - GEOHEX(builder().typeName("GEOHEX").estimatedSize(Long.BYTES)), + GEOHASH(builder().esType("geohash").typeName("GEOHASH").estimatedSize(Long.BYTES)), + GEOTILE(builder().esType("geotile").typeName("GEOTILE").estimatedSize(Long.BYTES)), + GEOHEX(builder().esType("geohex").typeName("GEOHEX").estimatedSize(Long.BYTES)), /** * Fields with this type represent a Lucene doc id. This field is a bit magic in that: From 100bb3bf478e258dfe9388f673347c2d43cdb3f7 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Fri, 11 Jul 2025 17:53:10 +0200 Subject: [PATCH 16/47] Remove int support from to_geo* functions The previous support kept the underlying IntBlock, which later would cause exceptions since the type expected a LongBock. --- .../esql/expression/function/scalar/convert/ToGeohash.java | 2 -- .../xpack/esql/expression/function/scalar/convert/ToGeohex.java | 2 -- .../esql/expression/function/scalar/convert/ToGeotile.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java index 02555e7793d97..f289d7f878514 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java @@ -27,7 +27,6 @@ import java.util.Map; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; -import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; @@ -40,7 +39,6 @@ public class ToGeohash extends AbstractConvertFunction { ); private static final Map EVALUATORS = Map.ofEntries( - Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeohashFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeohashFromStringEvaluator.Factory::new) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java index ea17e2cd9dbd4..1fbb14818a06a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java @@ -27,7 +27,6 @@ import java.util.Map; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; -import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; @@ -36,7 +35,6 @@ public class ToGeohex extends AbstractConvertFunction { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToGeohex", ToGeohex::new); private static final Map EVALUATORS = Map.ofEntries( - Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeohexFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeohexFromStringEvaluator.Factory::new) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java index 16b82bab3243b..05a83e30dcb1a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java @@ -27,7 +27,6 @@ import java.util.Map; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; -import static org.elasticsearch.xpack.esql.core.type.DataType.INTEGER; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; @@ -40,7 +39,6 @@ public class ToGeotile extends AbstractConvertFunction { ); private static final Map EVALUATORS = Map.ofEntries( - Map.entry(INTEGER, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeotileFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeotileFromStringEvaluator.Factory::new) From 891de41a62eb8ed132075437a0af146230300d67 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 20 Aug 2025 17:03:10 +0200 Subject: [PATCH 17/47] Fixed min/max after merging main --- .../xpack/esql/core/expression/TypeResolutions.java | 4 ++-- .../esql/expression/function/scalar/multivalue/MvMax.java | 3 +-- .../esql/expression/function/scalar/multivalue/MvMin.java | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java index 814adfde50e74..c0ca5d18dc63d 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java @@ -22,7 +22,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; import static org.elasticsearch.xpack.esql.core.type.DataType.IP; import static org.elasticsearch.xpack.esql.core.type.DataType.NULL; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; public final class TypeResolutions { @@ -82,7 +82,7 @@ public static TypeResolution isRepresentableExceptCounters(Expression e, String public static TypeResolution isRepresentableExceptCountersAndSpatial(Expression e, String operationName, ParamOrdinal paramOrd) { return isType( e, - (t) -> isSpatial(t) == false && DataType.isRepresentable(t), + (t) -> isSpatialOrGrid(t) == false && DataType.isRepresentable(t), operationName, paramOrd, "any type except counter and spatial types" diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java index 1055d1266d793..fc8281188c067 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMax.java @@ -27,7 +27,6 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isRepresentableExceptCountersAndSpatial; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; /** * Reduce a multivalued field to a single valued field containing the maximum value. @@ -69,7 +68,7 @@ public String getWriteableName() { @Override protected TypeResolution resolveFieldType() { - return isType(field(), t -> isSpatial(t) == false && isRepresentableExceptCountersAndSpatial(t), sourceText(), null, "representableNonSpatial"); + return isRepresentableExceptCountersAndSpatial(field(), sourceText(), DEFAULT); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java index b821fe0cee354..36dac6658aa5a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvMin.java @@ -27,7 +27,6 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isRepresentableExceptCountersAndSpatial; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; /** * Reduce a multivalued field to a single valued field containing the minimum value. From bd6c5c24669f4dacb31fd92a7d4fd6f012980db4 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 20 Aug 2025 17:18:06 +0200 Subject: [PATCH 18/47] Fixed intersects/disjoint after merging main --- .../expression/function/scalar/spatial/SpatialDisjoint.java | 2 +- .../expression/function/scalar/spatial/SpatialIntersects.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java index e8725f256db0c..0e108df7c4ed3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Map; -import static org.elasticsearch.xpack.esql.core.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; @@ -44,6 +43,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java index 8e94bdd5ced8e..b3705b5ca9ea3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Map; -import static org.elasticsearch.xpack.esql.core.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; @@ -44,6 +43,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; From cc506a9500fd5243d474fdf40abac55e992643ba Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 20 Aug 2025 17:34:03 +0200 Subject: [PATCH 19/47] Fix after merging main --- .../xpack/esql/expression/function/TestCaseSupplier.java | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java index 7e58a21314f13..cc5ac1b98f5a2 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java @@ -53,6 +53,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Collectors; +import static org.elasticsearch.test.ESTestCase.randomIntBetween; import static org.elasticsearch.xpack.esql.core.util.NumericUtils.UNSIGNED_LONG_MAX; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; From bee7b70142e6eb96e963903af6f5bf75fa6265ab Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Thu, 21 Aug 2025 14:28:21 +0200 Subject: [PATCH 20/47] Fix tests after merging main --- .../_snippets/functions/types/coalesce.md | 3 ++ .../esql/_snippets/functions/types/count.md | 3 ++ .../kibana/definition/functions/coalesce.json | 54 +++++++++++++++++++ .../kibana/definition/functions/count.json | 36 +++++++++++++ .../expression/function/aggregate/Count.java | 3 ++ .../function/aggregate/CountOverTime.java | 3 ++ .../expression/function/aggregate/Sample.java | 6 +++ .../function/scalar/nulls/Coalesce.java | 9 ++++ .../predicate/operator/comparison/Equals.java | 6 +++ .../predicate/operator/comparison/In.java | 6 +++ .../operator/comparison/NotEquals.java | 6 +++ .../function/aggregate/CountTests.java | 3 ++ .../function/aggregate/SampleTests.java | 5 +- .../function/scalar/nulls/CoalesceTests.java | 13 ++++- .../predicate/operator/CastOperatorTests.java | 3 ++ 15 files changed, 156 insertions(+), 3 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/coalesce.md b/docs/reference/query-languages/esql/_snippets/functions/types/coalesce.md index e38b4d261cf84..8fb034b63a6a3 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/coalesce.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/coalesce.md @@ -12,6 +12,9 @@ | date_nanos | date_nanos | date_nanos | | geo_point | geo_point | geo_point | | geo_shape | geo_shape | geo_shape | +| geohash | geohash | geohash | +| geohex | geohex | geohex | +| geotile | geotile | geotile | | integer | integer | integer | | integer | | integer | | ip | ip | ip | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/count.md b/docs/reference/query-languages/esql/_snippets/functions/types/count.md index 364b0c0353491..175336bd98374 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/count.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/count.md @@ -12,6 +12,9 @@ | double | long | | geo_point | long | | geo_shape | long | +| geohash | long | +| geohex | long | +| geotile | long | | integer | long | | ip | long | | keyword | long | diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/coalesce.json b/docs/reference/query-languages/esql/kibana/definition/functions/coalesce.json index 644fec38ff385..eca399992b3c3 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/coalesce.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/coalesce.json @@ -142,6 +142,60 @@ "variadic" : true, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "first", + "type" : "geohash", + "optional" : false, + "description" : "Expression to evaluate." + }, + { + "name" : "rest", + "type" : "geohash", + "optional" : true, + "description" : "Other expression to evaluate." + } + ], + "variadic" : true, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "first", + "type" : "geohex", + "optional" : false, + "description" : "Expression to evaluate." + }, + { + "name" : "rest", + "type" : "geohex", + "optional" : true, + "description" : "Other expression to evaluate." + } + ], + "variadic" : true, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "first", + "type" : "geotile", + "optional" : false, + "description" : "Expression to evaluate." + }, + { + "name" : "rest", + "type" : "geotile", + "optional" : true, + "description" : "Other expression to evaluate." + } + ], + "variadic" : true, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/count.json b/docs/reference/query-languages/esql/kibana/definition/functions/count.json index 09da0ee7dbb28..4510ef427fbda 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/count.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/count.json @@ -100,6 +100,42 @@ "variadic" : false, "returnType" : "long" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : true, + "description" : "Expression that outputs values to be counted. If omitted, equivalent to `COUNT(*)` (the number of rows)." + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : true, + "description" : "Expression that outputs values to be counted. If omitted, equivalent to `COUNT(*)` (the number of rows)." + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : true, + "description" : "Expression that outputs values to be counted. If omitted, equivalent to `COUNT(*)` (the number of rows)." + } + ], + "variadic" : false, + "returnType" : "long" + }, { "params" : [ { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Count.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Count.java index 9c6e4145759ca..cbf281f1bc86b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Count.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Count.java @@ -83,6 +83,9 @@ public Count( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountOverTime.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountOverTime.java index 6da92bc2ec3b5..8bd46d6d52d10 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountOverTime.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountOverTime.java @@ -58,6 +58,9 @@ public CountOverTime( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Sample.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Sample.java index 50cb44b186045..1ed7e439a9f06 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Sample.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Sample.java @@ -59,6 +59,9 @@ public class Sample extends AggregateFunction implements ToAggregator, PostOptim "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -84,6 +87,9 @@ public Sample( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java index ad300465d34cf..642eb27f7fb63 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/Coalesce.java @@ -51,6 +51,9 @@ public class Coalesce extends EsqlScalarFunction implements OptionalArgument { "date", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -71,6 +74,9 @@ public Coalesce( "date", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -89,6 +95,9 @@ public Coalesce( "date", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java index 90faa64f273ac..63cda52368eb8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java @@ -77,6 +77,9 @@ public Equals( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -96,6 +99,9 @@ public Equals( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java index 59be72960d32c..3162a6acddf5b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java @@ -140,6 +140,9 @@ public In( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -157,6 +160,9 @@ public In( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEquals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEquals.java index 0e7fc7beee077..73a97686ada7f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEquals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEquals.java @@ -70,6 +70,9 @@ public NotEquals( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -89,6 +92,9 @@ public NotEquals( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountTests.java index 863a8cc5f255b..b4aafef8fa467 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/CountTests.java @@ -51,6 +51,9 @@ public static Iterable parameters() { MultiRowTestCaseSupplier.geoPointCases(1, 1000, IncludingAltitude.YES), MultiRowTestCaseSupplier.geoShapeCasesWithoutCircle(1, 1000, IncludingAltitude.YES), MultiRowTestCaseSupplier.cartesianShapeCasesWithoutCircle(1, 1000, IncludingAltitude.YES), + MultiRowTestCaseSupplier.geohashCases(1, 1000), + MultiRowTestCaseSupplier.geotileCases(1, 1000), + MultiRowTestCaseSupplier.geohexCases(1, 1000), MultiRowTestCaseSupplier.stringCases(1, 1000, DataType.KEYWORD), MultiRowTestCaseSupplier.stringCases(1, 1000, DataType.TEXT) ).flatMap(List::stream).map(CountTests::makeSupplier).collect(Collectors.toCollection(() -> suppliers)); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SampleTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SampleTests.java index 8b66da40ddb27..e61447a65a820 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SampleTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SampleTests.java @@ -59,7 +59,10 @@ public static Iterable parameters() { MultiRowTestCaseSupplier.geoPointCases(1, 1000, MultiRowTestCaseSupplier.IncludingAltitude.NO), MultiRowTestCaseSupplier.cartesianPointCases(1, 1000, MultiRowTestCaseSupplier.IncludingAltitude.NO), MultiRowTestCaseSupplier.geoShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO), - MultiRowTestCaseSupplier.cartesianShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO) + MultiRowTestCaseSupplier.cartesianShapeCasesWithoutCircle(1, 20, MultiRowTestCaseSupplier.IncludingAltitude.NO), + MultiRowTestCaseSupplier.geohashCases(1, 1000), + MultiRowTestCaseSupplier.geotileCases(1, 1000), + MultiRowTestCaseSupplier.geohexCases(1, 1000) ) .flatMap(List::stream) .map(fieldCaseSupplier -> makeSupplier(fieldCaseSupplier, limitCaseSupplier)) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/CoalesceTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/CoalesceTests.java index e7d34e17b44c8..9a9592e36d2c8 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/CoalesceTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/nulls/CoalesceTests.java @@ -183,14 +183,23 @@ private static TestCaseSupplier.TestCase nullCase(TestCaseSupplier.TestCase dele } protected static void addSpatialCombinations(List suppliers) { - for (DataType dataType : List.of(DataType.GEO_POINT, DataType.GEO_SHAPE, DataType.CARTESIAN_POINT, DataType.CARTESIAN_SHAPE)) { + for (DataType dataType : List.of( + DataType.GEO_POINT, + DataType.GEO_SHAPE, + DataType.CARTESIAN_POINT, + DataType.CARTESIAN_SHAPE, + DataType.GEOHASH, + DataType.GEOTILE, + DataType.GEOHEX + )) { + String blockType = DataType.isGeoGrid(dataType) ? "Long" : "BytesRef"; TestCaseSupplier.TypedDataSupplier leftDataSupplier = SpatialRelatesFunctionTestCase.testCaseSupplier(dataType, false); TestCaseSupplier.TypedDataSupplier rightDataSupplier = SpatialRelatesFunctionTestCase.testCaseSupplier(dataType, false); suppliers.add( TestCaseSupplier.testCaseSupplier( leftDataSupplier, rightDataSupplier, - (l, r) -> equalTo("CoalesceBytesRefEagerEvaluator[values=[Attribute[channel=0], Attribute[channel=1]]]"), + (l, r) -> equalTo("Coalesce" + blockType + "EagerEvaluator[values=[Attribute[channel=0], Attribute[channel=1]]]"), dataType, (l, r) -> l ) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java index af53a1c666859..020bde8b623af 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java @@ -74,6 +74,9 @@ public TestCastOperator( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", From 879abcda9d54c4ed63ed901e314eee84789cfa3e Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Thu, 21 Aug 2025 17:30:31 +0200 Subject: [PATCH 21/47] Fix tests after merging main --- .../functions/types/count_over_time.md | 3 ++ .../esql/_snippets/functions/types/sample.md | 3 ++ .../definition/functions/count_over_time.json | 36 +++++++++++++ .../kibana/definition/functions/sample.json | 54 +++++++++++++++++++ 4 files changed, 96 insertions(+) diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/count_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/types/count_over_time.md index 364b0c0353491..175336bd98374 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/count_over_time.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/count_over_time.md @@ -12,6 +12,9 @@ | double | long | | geo_point | long | | geo_shape | long | +| geohash | long | +| geohex | long | +| geotile | long | | integer | long | | ip | long | | keyword | long | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/sample.md b/docs/reference/query-languages/esql/_snippets/functions/types/sample.md index 8e9d0114da060..ca03db0f978f5 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/sample.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/sample.md @@ -12,6 +12,9 @@ | double | integer | double | | geo_point | integer | geo_point | | geo_shape | integer | geo_shape | +| geohash | integer | geohash | +| geohex | integer | geohex | +| geotile | integer | geotile | | integer | integer | integer | | ip | integer | ip | | keyword | integer | keyword | diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/count_over_time.json b/docs/reference/query-languages/esql/kibana/definition/functions/count_over_time.json index 724bd3abd6b99..c8c1527b6f2a7 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/count_over_time.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/count_over_time.json @@ -101,6 +101,42 @@ "variadic" : false, "returnType" : "long" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "long" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "long" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/sample.json b/docs/reference/query-languages/esql/kibana/definition/functions/sample.json index 65af7520c2d96..28487b604e15b 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/sample.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/sample.json @@ -148,6 +148,60 @@ "variadic" : false, "returnType" : "geo_shape" }, + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "The field to collect sample values for." + }, + { + "name" : "limit", + "type" : "integer", + "optional" : false, + "description" : "The maximum number of values to collect." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "The field to collect sample values for." + }, + { + "name" : "limit", + "type" : "integer", + "optional" : false, + "description" : "The maximum number of values to collect." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "The field to collect sample values for." + }, + { + "name" : "limit", + "type" : "integer", + "optional" : false, + "description" : "The maximum number of values to collect." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { From e8ac2adead27605f1ed7234e4965c4db736e1c4a Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 15:20:32 +0200 Subject: [PATCH 22/47] Put grid types back into snapshot and assert that functions only work in snapshot mode --- .../spatial/SpatialGridLicenseTestCase.java | 23 ++++++++++++++++++- .../xpack/esql/action/EsqlCapabilities.java | 2 +- .../function/EsqlFunctionRegistry.java | 8 +++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java index 934b7d742273d..e7297f49f0cea 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/spatial/SpatialGridLicenseTestCase.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.esql.spatial; +import org.elasticsearch.Build; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.index.IndexRequest; @@ -35,7 +36,6 @@ public abstract class SpatialGridLicenseTestCase extends AbstractEsqlIntegTestCa @Before public void setupIndex() throws Exception { - assumeTrue("requires SPATIAL_GRID capability", EsqlCapabilities.Cap.SPATIAL_GRID.isEnabled()); createAndPopulateIndexes(10); } @@ -60,6 +60,13 @@ protected int precision() { return 1; // Default precision for grid function tests, can be overridden in subclasses } + /** + * Test that the geo_grid functions are disabled outside of SNAPSHOT. + */ + public void testGeoGridDisabled() { + assertGeoGridDisabledWith("index_geo_point"); + } + /** * This test will fail without a platinum license */ @@ -74,6 +81,7 @@ public void testGeoGridWithPoints() { } protected void assertGeoGridFromIndex(String index) { + assumeTrue("requires SPATIAL_GRID_TYPES capability", EsqlCapabilities.Cap.SPATIAL_GRID_TYPES.isEnabled()); assumeTrue("geo_shape capability not yet implemented", index.equals("index_geo_point")); var query = String.format(Locale.ROOT, """ FROM %s @@ -95,6 +103,7 @@ protected void assertGeoGridFromIndex(String index) { } protected void assertGeoGridFailsWith(String index) { + assumeTrue("requires SPATIAL_GRID_TYPES capability", EsqlCapabilities.Cap.SPATIAL_GRID_TYPES.isEnabled()); assumeTrue("geo_shape capability not yet implemented", index.equals("index_geo_point")); var query = String.format(Locale.ROOT, """ FROM %s @@ -111,6 +120,18 @@ protected void assertGeoGridFailsWith(String index) { assertThat(e.getMessage(), containsString(expectedError)); } + protected void assertGeoGridDisabledWith(String index) { + assumeFalse("testing feature is disabled in non-snapshot builds", Build.current().isSnapshot()); + var query = String.format(Locale.ROOT, """ + FROM %s + | EVAL gridId = %s(location, %d) + | STATS count=COUNT() BY gridId + """, index, gridFunction(), precision()); + var expectedError = String.format(Locale.ROOT, "Unknown function [%s]", gridFunction()); + ElasticsearchException e = expectThrows(VerificationException.class, () -> run(query)); + assertThat(e.getMessage(), containsString(expectedError)); + } + public static Map getValuesMap(Iterator> values) { var valuesMap = new LinkedHashMap(); values.forEachRemaining(row -> { valuesMap.put(row.next().toString(), ((Number) row.next()).longValue()); }); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 0b31f0969f2b4..ed7ddd379ce93 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -408,7 +408,7 @@ public enum Cap { /** * Support geohash, geotile and geohex data types. Done in #129581 */ - SPATIAL_GRID_TYPES, + SPATIAL_GRID_TYPES(Build.current().isSnapshot()), /** * Fix to GROK and DISSECT that allows extracting attributes with the same name as the input diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index 65c4b5c554df7..954acb9ed7da3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -417,10 +417,7 @@ private static FunctionDefinition[][] functions() { def(StYMax.class, StYMax::new, "st_ymax"), def(StYMin.class, StYMin::new, "st_ymin"), def(StX.class, StX::new, "st_x"), - def(StY.class, StY::new, "st_y"), - def(StGeohash.class, StGeohash::new, "st_geohash"), - def(StGeotile.class, StGeotile::new, "st_geotile"), - def(StGeohex.class, StGeohex::new, "st_geohex") }, + def(StY.class, StY::new, "st_y") }, // conditional new FunctionDefinition[] { def(Case.class, Case::new, "case") }, // null @@ -504,6 +501,9 @@ private static FunctionDefinition[][] snapshotFunctions() { def(Score.class, uni(Score::new), Score.NAME), def(Term.class, bi(Term::new), "term"), def(Knn.class, quad(Knn::new), "knn"), + def(StGeohash.class, StGeohash::new, "st_geohash"), + def(StGeotile.class, StGeotile::new, "st_geotile"), + def(StGeohex.class, StGeohex::new, "st_geohex"), def(CosineSimilarity.class, CosineSimilarity::new, "v_cosine"), def(DotProduct.class, DotProduct::new, "v_dot_product"), def(L1Norm.class, L1Norm::new, "v_l1_norm"), From 0f5ddefbc376d4624fbdd56a519e7dd9258c5d7b Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 17:10:14 +0200 Subject: [PATCH 23/47] Move type-conversion functions to snapshot as well --- .../esql/expression/function/EsqlFunctionRegistry.java | 6 +++--- .../elasticsearch/xpack/esql/telemetry/PlanTelemetry.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index 954acb9ed7da3..614b73cff46b3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -440,9 +440,6 @@ private static FunctionDefinition[][] functions() { def(ToDouble.class, ToDouble::new, "to_double", "to_dbl"), def(ToGeoPoint.class, ToGeoPoint::new, "to_geopoint"), def(ToGeoShape.class, ToGeoShape::new, "to_geoshape"), - def(ToGeohash.class, ToGeohash::new, "to_geohash"), - def(ToGeotile.class, ToGeotile::new, "to_geotile"), - def(ToGeohex.class, ToGeohex::new, "to_geohex"), def(ToIp.class, ToIp::new, "to_ip"), def(ToInteger.class, ToInteger::new, "to_integer", "to_int"), def(ToLong.class, ToLong::new, "to_long"), @@ -501,6 +498,9 @@ private static FunctionDefinition[][] snapshotFunctions() { def(Score.class, uni(Score::new), Score.NAME), def(Term.class, bi(Term::new), "term"), def(Knn.class, quad(Knn::new), "knn"), + def(ToGeohash.class, ToGeohash::new, "to_geohash"), + def(ToGeotile.class, ToGeotile::new, "to_geotile"), + def(ToGeohex.class, ToGeohex::new, "to_geohex"), def(StGeohash.class, StGeohash::new, "st_geohash"), def(StGeotile.class, StGeotile::new, "st_geotile"), def(StGeohex.class, StGeohex::new, "st_geohex"), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java index 10b48c243d3b1..aa6b8d4873832 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java @@ -46,7 +46,7 @@ public void function(String name) { } public void function(Class clazz) { - add(functions, functionRegistry.functionName(clazz)); + add(functions, functionRegistry.snapshotRegistry().functionName(clazz)); } public Map commands() { From 589720f90746534338ebf5d63c40fcd8dfbc8a35 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 17:52:31 +0200 Subject: [PATCH 24/47] Fix failing test after moving functions to snapshot --- .../org/elasticsearch/xpack/esql/analysis/ParsingTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java index 01242b19e3074..35bcb75714d4b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java @@ -104,7 +104,7 @@ public void testInlineCast() throws IOException { assertThat(row.fields(), hasSize(1)); Function functionCall = (Function) row.fields().get(0).child(); assertThat(functionCall.dataType(), equalTo(expectedType)); - report.field(nameOrAlias, registry.functionName(functionCall.getClass())); + report.field(nameOrAlias, registry.snapshotRegistry().functionName(functionCall.getClass())); } report.endObject(); } From b5830f012c5f55b74e71a292cc7b9babf87ce03d Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 17:52:54 +0200 Subject: [PATCH 25/47] Commit kibana specs after moving function to snapshot --- .../esql/kibana/definition/functions/st_geohash.json | 2 +- .../esql/kibana/definition/functions/st_geohex.json | 2 +- .../esql/kibana/definition/functions/st_geotile.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json index 6c041ebe4b43d..725d1613aa8d2 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json @@ -51,5 +51,5 @@ "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" ], "preview" : true, - "snapshot_only" : false + "snapshot_only" : true } diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json index 8a017d5bf2bfc..fa5d2c7662891 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json @@ -54,5 +54,5 @@ "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" ], "preview" : true, - "snapshot_only" : false + "snapshot_only" : true } diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json index bbfcd42b60ec2..53cda0965e257 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json @@ -51,5 +51,5 @@ "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" ], "preview" : true, - "snapshot_only" : false + "snapshot_only" : true } From 7ac9c8dead8e8d452baaf9f56f10696f825d4624 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 18:50:51 +0200 Subject: [PATCH 26/47] Add missing unit tests for new conversion functions --- .../esql/expression/ExpressionWritables.java | 6 ++ .../expression/function/TestCaseSupplier.java | 61 +++++++++++++++++-- .../scalar/convert/ToGeoShapeTests.java | 2 +- .../scalar/convert/ToGeohashErrorTests.java | 37 +++++++++++ .../convert/ToGeohashSerializationTests.java | 19 ++++++ .../scalar/convert/ToGeohashTests.java | 54 ++++++++++++++++ .../convert/ToGeohexSerializationTests.java | 19 ++++++ .../scalar/convert/ToGeohexTests.java | 54 ++++++++++++++++ .../scalar/convert/ToGeohexhErrorTests.java | 37 +++++++++++ .../scalar/convert/ToGeotileErrorTests.java | 37 +++++++++++ .../convert/ToGeotileSerializationTests.java | 19 ++++++ .../scalar/convert/ToGeotileTests.java | 54 ++++++++++++++++ .../scalar/convert/ToStringTests.java | 2 +- 13 files changed, 395 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashSerializationTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexSerializationTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileSerializationTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java index 1b9c0f0d9bf7c..354709e57732a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java @@ -25,6 +25,9 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoPoint; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeoShape; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohash; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeohex; +import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToGeotile; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIpLeadingZerosDecimal; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToIpLeadingZerosOctal; @@ -204,6 +207,9 @@ public static List unaryScalars() { entries.add(ToGeoShape.ENTRY); entries.add(ToCartesianShape.ENTRY); entries.add(ToGeoPoint.ENTRY); + entries.add(ToGeohash.ENTRY); + entries.add(ToGeotile.ENTRY); + entries.add(ToGeohex.ENTRY); entries.add(ToIpLeadingZerosDecimal.ENTRY); entries.add(ToIpLeadingZerosOctal.ENTRY); entries.add(ToIpLeadingZerosRejected.ENTRY); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java index cc5ac1b98f5a2..930bfc7cf7203 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java @@ -666,12 +666,41 @@ public static void forUnaryBoolean( public static void forUnaryGeoGrid( List suppliers, String expectedEvaluatorToString, - DataType gridType, + DataType sourceType, DataType expectedType, - Function expectedValue, + Function expectedValue, List warnings ) { - unary(suppliers, expectedEvaluatorToString, geoGridCases(gridType), expectedType, n -> expectedValue.apply((long) n), warnings); + if (DataType.isGeoGrid(sourceType)) { + unary(suppliers, expectedEvaluatorToString, geoGridCases(sourceType), expectedType, expectedValue, warnings); + + } else if (DataType.isGeoGrid(expectedType)) { + if (sourceType == DataType.LONG) { + unary( + suppliers, + expectedEvaluatorToString, + geoGridCasesAsLongs(expectedType, ESTestCase::randomBoolean), + expectedType, + expectedValue, + warnings + ); + } else if (sourceType.noText() == DataType.KEYWORD) { + unary( + suppliers, + expectedEvaluatorToString, + geoGridCasesAsStrings(expectedType, sourceType, ESTestCase::randomBoolean), + expectedType, + expectedValue, + warnings + ); + } else { + throw new IllegalArgumentException( + "Expected gro-grid types, got source [" + sourceType + "], expected [" + expectedType + "]" + ); + } + } else { + throw new IllegalArgumentException("Expected gro-grid types, got source [" + sourceType + "], expected [" + expectedType + "]"); + } } /** @@ -1247,6 +1276,14 @@ public static List cartesianShapeCases() { * Generate cases for {@link DataType#GEOHASH}. */ public static List geoGridCases(DataType gridType, Supplier hasAlt) { + return geoGridCasesAsType(gridType, gridType, hasAlt); + } + + public static List geoGridCasesAsLongs(DataType gridType, Supplier hasAlt) { + return geoGridCasesAsType(gridType, DataType.LONG, hasAlt); + } + + private static List geoGridCasesAsType(DataType gridType, DataType sourceType, Supplier hasAlt) { Supplier gridId = () -> { Point point = GeometryTestUtils.randomPoint(hasAlt.get()); return switch (gridType) { @@ -1256,7 +1293,23 @@ public static List geoGridCases(DataType gridType, Supplier throw new IllegalArgumentException("Unsupported grid type: " + gridType); }; }; - return List.of(new TypedDataSupplier("<" + gridType.esType() + ">", gridId, gridType)); + return List.of(new TypedDataSupplier("<" + gridType.esType() + ">", gridId, sourceType)); + } + + public static List geoGridCasesAsStrings(DataType gridType, DataType sourceType, Supplier hasAlt) { + Supplier gridId = () -> { + Point point = GeometryTestUtils.randomPoint(hasAlt.get()); + String gridAddress = switch (gridType) { + case GEOHASH -> Geohash.stringEncode(point.getX(), point.getY(), randomIntBetween(1, Geohash.PRECISION)); + case GEOTILE -> GeoTileUtils.stringEncode( + GeoTileUtils.longEncode(point.getX(), point.getY(), randomIntBetween(0, GeoTileUtils.MAX_ZOOM)) + ); + case GEOHEX -> H3.geoToH3Address(point.getLat(), point.getLon(), randomIntBetween(0, H3.MAX_H3_RES)); + default -> throw new IllegalArgumentException("Unsupported grid type: " + gridType); + }; + return new BytesRef(gridAddress); + }; + return List.of(new TypedDataSupplier("<" + gridType.esType() + ">", gridId, sourceType)); } /** diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java index 11c7c4e2d2def..a2148a61f4fb1 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeTests.java @@ -50,7 +50,7 @@ public static Iterable parameters() { "ToGeoShapeFromGeoGridEvaluator[in=Attribute[channel=0], dataType=" + gridType + "]", gridType, DataType.GEO_SHAPE, - v -> EsqlDataTypeConverter.geoGridToShape(v, gridType), + v -> EsqlDataTypeConverter.geoGridToShape((long) v, gridType), List.of() ); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java new file mode 100644 index 0000000000000..7c8a154ea1371 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.ErrorsForCasesWithoutExamplesTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.hamcrest.Matcher; + +import java.util.List; +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; + +public class ToGeohashErrorTests extends ErrorsForCasesWithoutExamplesTestCase { + @Override + protected List cases() { + return paramsToSuppliers(ToGeohashTests.parameters()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeohash(source, args.get(0)); + } + + @Override + protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashSerializationTests.java new file mode 100644 index 0000000000000..244094a627589 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToGeohashSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToGeohash create(Source source, Expression child) { + return new ToGeohash(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java new file mode 100644 index 0000000000000..d6551404f9ed7 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.FunctionName; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +@FunctionName("to_geohash") +public class ToGeohashTests extends AbstractScalarFunctionTestCase { + public ToGeohashTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final String attribute = "Attribute[channel=0]"; + final String evaluator = "ToGeohashFromStringEvaluator[in=Attribute[channel=0]]"; + final List suppliers = new ArrayList<>(); + + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOHASH, v -> v, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOHASH, ToGeohashTests::valueOf, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOHASH, ToGeohashTests::valueOf, List.of()); + + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(Object gridAddress) { + assert gridAddress instanceof BytesRef; + return Geohash.longEncode(((BytesRef) gridAddress).utf8ToString()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeohash(source, args.get(0)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexSerializationTests.java new file mode 100644 index 0000000000000..a76c8e4a1e535 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToGeohexSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToGeohex create(Source source, Expression child) { + return new ToGeohex(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java new file mode 100644 index 0000000000000..819c133e676fc --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.h3.H3; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.FunctionName; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +@FunctionName("to_Geohex") +public class ToGeohexTests extends AbstractScalarFunctionTestCase { + public ToGeohexTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final String attribute = "Attribute[channel=0]"; + final String evaluator = "ToGeohexFromStringEvaluator[in=Attribute[channel=0]]"; + final List suppliers = new ArrayList<>(); + + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOHEX, v -> v, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOHEX, ToGeohexTests::valueOf, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOHEX, ToGeohexTests::valueOf, List.of()); + + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(Object gridAddress) { + assert gridAddress instanceof BytesRef; + return H3.stringToH3(((BytesRef) gridAddress).utf8ToString()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeohex(source, args.get(0)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java new file mode 100644 index 0000000000000..63f578c2c34a7 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.ErrorsForCasesWithoutExamplesTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.hamcrest.Matcher; + +import java.util.List; +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; + +public class ToGeohexhErrorTests extends ErrorsForCasesWithoutExamplesTestCase { + @Override + protected List cases() { + return paramsToSuppliers(ToGeohexTests.parameters()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeohex(source, args.get(0)); + } + + @Override + protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java new file mode 100644 index 0000000000000..6e5e41c965a21 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.ErrorsForCasesWithoutExamplesTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.hamcrest.Matcher; + +import java.util.List; +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; + +public class ToGeotileErrorTests extends ErrorsForCasesWithoutExamplesTestCase { + @Override + protected List cases() { + return paramsToSuppliers(ToGeotileTests.parameters()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeotile(source, args.get(0)); + } + + @Override + protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileSerializationTests.java new file mode 100644 index 0000000000000..dc6838a96343d --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileSerializationTests.java @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.AbstractUnaryScalarSerializationTests; + +public class ToGeotileSerializationTests extends AbstractUnaryScalarSerializationTests { + @Override + protected ToGeotile create(Source source, Expression child) { + return new ToGeotile(source, child); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java new file mode 100644 index 0000000000000..aa3e5c143f66e --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.convert; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.FunctionName; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +@FunctionName("to_geotile") +public class ToGeotileTests extends AbstractScalarFunctionTestCase { + public ToGeotileTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final String attribute = "Attribute[channel=0]"; + final String evaluator = "ToGeotileFromStringEvaluator[in=Attribute[channel=0]]"; + final List suppliers = new ArrayList<>(); + + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOTILE, v -> v, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOTILE, ToGeotileTests::valueOf, List.of()); + TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOTILE, ToGeotileTests::valueOf, List.of()); + + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(Object gridAddress) { + assert gridAddress instanceof BytesRef; + return GeoTileUtils.longEncode(((BytesRef) gridAddress).utf8ToString()); + } + + @Override + protected Expression build(Source source, List args) { + return new ToGeotile(source, args.get(0)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java index f378a56e5c451..8d8f59b78114d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToStringTests.java @@ -149,7 +149,7 @@ public static Iterable parameters() { "ToStringFromGeoGridEvaluator[gridId=Attribute[channel=0], dataType=" + gridType + "]", gridType, DataType.KEYWORD, - v -> new BytesRef(EsqlDataTypeConverter.geoGridToString(v, gridType)), + v -> new BytesRef(EsqlDataTypeConverter.geoGridToString((long) v, gridType)), List.of() ); } From 8669be9fd5645024f16ed210f6002a0ede82849a Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 21:36:38 +0200 Subject: [PATCH 27/47] Add missing docs for to_geo-grid functions --- .../functions/description/to_geohash.md | 6 +++ .../functions/description/to_geohex.md | 6 +++ .../functions/description/to_geotile.md | 6 +++ .../functions/examples/to_geohash.md | 14 ++++++ .../_snippets/functions/examples/to_geohex.md | 14 ++++++ .../functions/examples/to_geotile.md | 14 ++++++ .../_snippets/functions/layout/to_geohash.md | 27 ++++++++++ .../_snippets/functions/layout/to_geohex.md | 27 ++++++++++ .../_snippets/functions/layout/to_geotile.md | 27 ++++++++++ .../functions/parameters/to_geohash.md | 7 +++ .../functions/parameters/to_geohex.md | 7 +++ .../functions/parameters/to_geotile.md | 7 +++ .../_snippets/functions/types/to_geohash.md | 10 ++++ .../_snippets/functions/types/to_geohex.md | 10 ++++ .../_snippets/functions/types/to_geotile.md | 10 ++++ .../esql/images/functions/to_geohash.svg | 1 + .../esql/images/functions/to_geohex.svg | 1 + .../esql/images/functions/to_geotile.svg | 1 + .../definition/functions/to_geohash.json | 49 +++++++++++++++++++ .../definition/functions/to_geohex.json | 49 +++++++++++++++++++ .../definition/functions/to_geotile.json | 49 +++++++++++++++++++ .../esql/kibana/docs/functions/to_geohash.md | 11 +++++ .../esql/kibana/docs/functions/to_geohex.md | 11 +++++ .../esql/kibana/docs/functions/to_geotile.md | 11 +++++ .../scalar/convert/ToGeohexTests.java | 2 +- 25 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/to_geohash.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/to_geohex.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/description/to_geotile.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/to_geohash.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/to_geohex.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/examples/to_geotile.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/to_geohash.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/to_geohex.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/layout/to_geotile.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohash.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohex.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/parameters/to_geotile.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md create mode 100644 docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md create mode 100644 docs/reference/query-languages/esql/images/functions/to_geohash.svg create mode 100644 docs/reference/query-languages/esql/images/functions/to_geohex.svg create mode 100644 docs/reference/query-languages/esql/images/functions/to_geotile.svg create mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json create mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json create mode 100644 docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json create mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/to_geohash.md create mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/to_geohex.md create mode 100644 docs/reference/query-languages/esql/kibana/docs/functions/to_geotile.md diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/description/to_geohash.md new file mode 100644 index 0000000000000..0c588cfc2a876 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/to_geohash.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geohash` value. A string will only be successfully converted if it respects the `geohash` format. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/description/to_geohex.md new file mode 100644 index 0000000000000..78eaa369454ca --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/to_geohex.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geohex` value. A string will only be successfully converted if it respects the `geohex` format. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/description/to_geotile.md new file mode 100644 index 0000000000000..b5a2c3812e254 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/to_geotile.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geotile` value. A string will only be successfully converted if it respects the `geotile` format. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohash.md new file mode 100644 index 0000000000000..1e48d726698d6 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohash.md @@ -0,0 +1,14 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +ROW string = "u3bu" +| EVAL geohash = TO_GEOHASH(string) +``` + +| string:keyword | geohash:geohash | +| --- | --- | +| u3bu | u3bu | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohex.md new file mode 100644 index 0000000000000..32543f3c3f415 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geohex.md @@ -0,0 +1,14 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +ROW string = "841f059ffffffff" +| EVAL geohex = TO_GEOHEX(string) +``` + +| string:keyword | geohex:geohex | +| --- | --- | +| 841f059ffffffff | 841f059ffffffff | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geotile.md new file mode 100644 index 0000000000000..a47072cd3a1e8 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/to_geotile.md @@ -0,0 +1,14 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +ROW string = "4/8/5" +| EVAL geotile = TO_GEOTILE(string) +``` + +| string:keyword | geotile:geotile | +| --- | --- | +| 4/8/5 | 4/8/5 | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohash.md new file mode 100644 index 0000000000000..92fad1c051bb0 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohash.md @@ -0,0 +1,27 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `TO_GEOHASH` [esql-to_geohash] +```{applies_to} +stack: preview +serverless: preview +``` + +**Syntax** + +:::{image} ../../../images/functions/to_geohash.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/to_geohash.md +::: + +:::{include} ../description/to_geohash.md +::: + +:::{include} ../types/to_geohash.md +::: + +:::{include} ../examples/to_geohash.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohex.md new file mode 100644 index 0000000000000..7177922df3120 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geohex.md @@ -0,0 +1,27 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `TO_GEOHEX` [esql-to_geohex] +```{applies_to} +stack: preview +serverless: preview +``` + +**Syntax** + +:::{image} ../../../images/functions/to_geohex.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/to_geohex.md +::: + +:::{include} ../description/to_geohex.md +::: + +:::{include} ../types/to_geohex.md +::: + +:::{include} ../examples/to_geohex.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geotile.md new file mode 100644 index 0000000000000..4208d0b61d12a --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/to_geotile.md @@ -0,0 +1,27 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `TO_GEOTILE` [esql-to_geotile] +```{applies_to} +stack: preview +serverless: preview +``` + +**Syntax** + +:::{image} ../../../images/functions/to_geotile.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/to_geotile.md +::: + +:::{include} ../description/to_geotile.md +::: + +:::{include} ../types/to_geotile.md +::: + +:::{include} ../examples/to_geotile.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohash.md new file mode 100644 index 0000000000000..b218f4be18a25 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohash.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`field` +: Input value. The input can be a single- or multi-valued column or an expression. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohex.md new file mode 100644 index 0000000000000..b218f4be18a25 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geohex.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`field` +: Input value. The input can be a single- or multi-valued column or an expression. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geotile.md new file mode 100644 index 0000000000000..b218f4be18a25 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/to_geotile.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`field` +: Input value. The input can be a single- or multi-valued column or an expression. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md new file mode 100644 index 0000000000000..dadea0b9fba6d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| field | result | +| --- | --- | +| keyword | geohash | +| long | geohash | +| text | geohash | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md new file mode 100644 index 0000000000000..350d8a9f19c3e --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| field | result | +| --- | --- | +| keyword | geohex | +| long | geohex | +| text | geohex | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md new file mode 100644 index 0000000000000..72636c88e1abf --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| field | result | +| --- | --- | +| keyword | geotile | +| long | geotile | +| text | geotile | + diff --git a/docs/reference/query-languages/esql/images/functions/to_geohash.svg b/docs/reference/query-languages/esql/images/functions/to_geohash.svg new file mode 100644 index 0000000000000..09238c61d1fa4 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/to_geohash.svg @@ -0,0 +1 @@ +TO_GEOHASH(field) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/to_geohex.svg b/docs/reference/query-languages/esql/images/functions/to_geohex.svg new file mode 100644 index 0000000000000..a97e160058e78 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/to_geohex.svg @@ -0,0 +1 @@ +TO_GEOHEX(field) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/to_geotile.svg b/docs/reference/query-languages/esql/images/functions/to_geotile.svg new file mode 100644 index 0000000000000..3afd3b77f8b80 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/to_geotile.svg @@ -0,0 +1 @@ +TO_GEOTILE(field) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json new file mode 100644 index 0000000000000..e49f0c22fba6a --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "scalar", + "name" : "to_geohash", + "description" : "Converts an input value to a `geohash` value.\nA string will only be successfully converted if it respects the\n`geohash` format.", + "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "keyword", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "long", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, + { + "params" : [ + { + "name" : "field", + "type" : "text", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + } + ], + "examples" : [ + "ROW string = \"u3bu\"\n| EVAL geohash = TO_GEOHASH(string)" + ], + "preview" : true, + "snapshot_only" : true +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json new file mode 100644 index 0000000000000..43bc359fc0f9e --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "scalar", + "name" : "to_geohex", + "description" : "Converts an input value to a `geohex` value.\nA string will only be successfully converted if it respects the\n`geohex` format.", + "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "keyword", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "long", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, + { + "params" : [ + { + "name" : "field", + "type" : "text", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + } + ], + "examples" : [ + "ROW string = \"841f059ffffffff\"\n| EVAL geohex = TO_GEOHEX(string)" + ], + "preview" : true, + "snapshot_only" : true +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json new file mode 100644 index 0000000000000..34da9be3a9c65 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "scalar", + "name" : "to_geotile", + "description" : "Converts an input value to a `geotile` value.\nA string will only be successfully converted if it respects the\n`geotile` format.", + "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "keyword", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, + { + "params" : [ + { + "name" : "field", + "type" : "long", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, + { + "params" : [ + { + "name" : "field", + "type" : "text", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + } + ], + "examples" : [ + "ROW string = \"4/8/5\"\n| EVAL geotile = TO_GEOTILE(string)" + ], + "preview" : true, + "snapshot_only" : true +} diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/to_geohash.md b/docs/reference/query-languages/esql/kibana/docs/functions/to_geohash.md new file mode 100644 index 0000000000000..59277639cf6f3 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/to_geohash.md @@ -0,0 +1,11 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### TO GEOHASH +Converts an input value to a `geohash` value. +A string will only be successfully converted if it respects the +`geohash` format. + +```esql +ROW string = "u3bu" +| EVAL geohash = TO_GEOHASH(string) +``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/to_geohex.md b/docs/reference/query-languages/esql/kibana/docs/functions/to_geohex.md new file mode 100644 index 0000000000000..1d6e3b968995e --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/to_geohex.md @@ -0,0 +1,11 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### TO GEOHEX +Converts an input value to a `geohex` value. +A string will only be successfully converted if it respects the +`geohex` format. + +```esql +ROW string = "841f059ffffffff" +| EVAL geohex = TO_GEOHEX(string) +``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/to_geotile.md b/docs/reference/query-languages/esql/kibana/docs/functions/to_geotile.md new file mode 100644 index 0000000000000..a123797d01d7b --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/to_geotile.md @@ -0,0 +1,11 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### TO GEOTILE +Converts an input value to a `geotile` value. +A string will only be successfully converted if it respects the +`geotile` format. + +```esql +ROW string = "4/8/5" +| EVAL geotile = TO_GEOTILE(string) +``` diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java index 819c133e676fc..ca0b3b9c06bc5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.function.Supplier; -@FunctionName("to_Geohex") +@FunctionName("to_geohex") public class ToGeohexTests extends AbstractScalarFunctionTestCase { public ToGeohexTests(@Name("TestCase") Supplier testCaseSupplier) { this.testCase = testCaseSupplier.get(); From 8c271a708d462b9b8e8a4368955f51fe45545f22 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 21:50:17 +0200 Subject: [PATCH 28/47] Simplify type checks --- .../scalar/spatial/BinarySpatialFunction.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index 2a3fa71faa04a..b088761b3ae5b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -191,15 +191,14 @@ protected TypeResolution resolveType( return isSpatial(otherExpression, otherParamOrdinal); } TypeResolution resolution = isSameSpatialType(spatialExpression.dataType(), otherExpression, sourceText(), otherParamOrdinal); - if (resolution.unresolved()) { - return resolution; - } // TODO Remove these grid checks once we support geo_shape relation to geoGrid - if (resolution.resolved() && DataType.isGeoGrid(spatialExpression.dataType())) { - resolution = isGeoPoint(otherExpression, otherParamOrdinal); - } - if (resolution.resolved() && DataType.isGeoGrid(otherExpression.dataType())) { - resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); + if (resolution.resolved()) { + if (DataType.isGeoGrid(spatialExpression.dataType())) { + resolution = isGeoPoint(otherExpression, otherParamOrdinal); + } + if (DataType.isGeoGrid(otherExpression.dataType())) { + resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); + } } if (resolution.unresolved()) { return resolution; From 819e89608d94be2ee61009a91ce36891867b645f Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 22:11:27 +0200 Subject: [PATCH 29/47] Redirects to work around build issue in docs-builder --- docs/redirects.yml | 60 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index 646937892e06a..0801f3a1b5af4 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -1,7 +1,7 @@ redirects: # Related to https://github.com/elastic/elasticsearch/pull/130716/ 'reference/query-languages/eql/eql-ex-threat-detection.md': 'docs-content://explore-analyze/query-filter/languages/example-detect-threats-with-eql.md' - + # https://github.com/elastic/elasticsearch/pull/131385 'reference/elasticsearch/rest-apis/retrievers.md': to: 'reference/elasticsearch/rest-apis/retrievers.md' @@ -23,7 +23,7 @@ redirects: anchors: {'rule-retriever'} - to: 'reference/elasticsearch/rest-apis/retrievers/pinned-retriever.md' anchors: {'pinned-retriever'} - + # ESQL command redirects - split from aggregate pages to individual pages 'reference/query-languages/esql/commands/source-commands.md': to: 'reference/query-languages/esql/commands/source-commands.md' @@ -35,7 +35,7 @@ redirects: anchors: {'esql-row'} - to: 'reference/query-languages/esql/commands/show.md' anchors: {'esql-show'} - + # Handle old anchor references to esql-commands.md 'reference/query-languages/esql/esql-commands.md': to: 'reference/query-languages/esql/esql-commands.md' @@ -45,7 +45,7 @@ redirects: anchors: {'esql-source-commands'} - to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {'esql-processing-commands'} - + 'reference/query-languages/esql/commands/processing-commands.md': to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {} # pass-through unlisted anchors in the `many` ruleset @@ -85,4 +85,54 @@ redirects: - to: 'reference/query-languages/esql/commands/stats-by.md' anchors: {'esql-stats-by'} - to: 'reference/query-languages/esql/commands/where.md' - anchors: {'esql-where'} \ No newline at end of file + anchors: {'esql-where'} + + # Dummy redirects for deleted snippets to get round a bug in redirects validation + 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohash_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geotile_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohex_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohash_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geotile_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohex_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' From 0360aa2b1795f45d2f19c8b10ff278edd6984156 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 22:18:07 +0200 Subject: [PATCH 30/47] Redirects to work around build issue in docs-builder --- docs/redirects.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index 0801f3a1b5af4..bd988364850a1 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -86,7 +86,7 @@ redirects: anchors: {'esql-stats-by'} - to: 'reference/query-languages/esql/commands/where.md' anchors: {'esql-where'} - + # Dummy redirects for deleted snippets to get round a bug in redirects validation 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' From 0351442e662d315f98a3788130ea43f8919ea859 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Mon, 25 Aug 2025 22:20:59 +0200 Subject: [PATCH 31/47] Using joe to add back trailing whitespace --- docs/redirects.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index bd988364850a1..d4b32ef00ba32 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -1,7 +1,7 @@ redirects: # Related to https://github.com/elastic/elasticsearch/pull/130716/ 'reference/query-languages/eql/eql-ex-threat-detection.md': 'docs-content://explore-analyze/query-filter/languages/example-detect-threats-with-eql.md' - + # https://github.com/elastic/elasticsearch/pull/131385 'reference/elasticsearch/rest-apis/retrievers.md': to: 'reference/elasticsearch/rest-apis/retrievers.md' @@ -23,7 +23,7 @@ redirects: anchors: {'rule-retriever'} - to: 'reference/elasticsearch/rest-apis/retrievers/pinned-retriever.md' anchors: {'pinned-retriever'} - + # ESQL command redirects - split from aggregate pages to individual pages 'reference/query-languages/esql/commands/source-commands.md': to: 'reference/query-languages/esql/commands/source-commands.md' @@ -35,7 +35,7 @@ redirects: anchors: {'esql-row'} - to: 'reference/query-languages/esql/commands/show.md' anchors: {'esql-show'} - + # Handle old anchor references to esql-commands.md 'reference/query-languages/esql/esql-commands.md': to: 'reference/query-languages/esql/esql-commands.md' @@ -45,7 +45,7 @@ redirects: anchors: {'esql-source-commands'} - to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {'esql-processing-commands'} - + 'reference/query-languages/esql/commands/processing-commands.md': to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {} # pass-through unlisted anchors in the `many` ruleset From 3669cb23dc2147c9f47d137a733e1d60130502bf Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 10:51:10 +0200 Subject: [PATCH 32/47] Try multi-line redirects --- docs/redirects.yml | 154 +++++++++++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 53 deletions(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index d4b32ef00ba32..d067e007f7e43 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -1,7 +1,7 @@ redirects: # Related to https://github.com/elastic/elasticsearch/pull/130716/ 'reference/query-languages/eql/eql-ex-threat-detection.md': 'docs-content://explore-analyze/query-filter/languages/example-detect-threats-with-eql.md' - + # https://github.com/elastic/elasticsearch/pull/131385 'reference/elasticsearch/rest-apis/retrievers.md': to: 'reference/elasticsearch/rest-apis/retrievers.md' @@ -23,7 +23,7 @@ redirects: anchors: {'rule-retriever'} - to: 'reference/elasticsearch/rest-apis/retrievers/pinned-retriever.md' anchors: {'pinned-retriever'} - + # ESQL command redirects - split from aggregate pages to individual pages 'reference/query-languages/esql/commands/source-commands.md': to: 'reference/query-languages/esql/commands/source-commands.md' @@ -35,7 +35,7 @@ redirects: anchors: {'esql-row'} - to: 'reference/query-languages/esql/commands/show.md' anchors: {'esql-show'} - + # Handle old anchor references to esql-commands.md 'reference/query-languages/esql/esql-commands.md': to: 'reference/query-languages/esql/esql-commands.md' @@ -45,7 +45,7 @@ redirects: anchors: {'esql-source-commands'} - to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {'esql-processing-commands'} - + 'reference/query-languages/esql/commands/processing-commands.md': to: 'reference/query-languages/esql/commands/processing-commands.md' anchors: {} # pass-through unlisted anchors in the `many` ruleset @@ -86,53 +86,101 @@ redirects: anchors: {'esql-stats-by'} - to: 'reference/query-languages/esql/commands/where.md' anchors: {'esql-where'} - + # Dummy redirects for deleted snippets to get round a bug in redirects validation - 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohash_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geotile_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohex_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohash_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geotile_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohex_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohash_to_string.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geotile_to_string.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohex_to_string.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohash_to_long.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geotile_to_long.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/images/functions/st_geohex_to_long.svg': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' + 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': + to: 'reference/query-languages/esql/esql-functions-operators.md' From 681dc30cfc6af4ba0d55c36d9d98622846b2b215 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 10:54:31 +0200 Subject: [PATCH 33/47] Try absolute path --- docs/redirects.yml | 96 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index d067e007f7e43..23bad8808929a 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -88,99 +88,99 @@ redirects: anchors: {'esql-where'} # Dummy redirects for deleted snippets to get round a bug in redirects validation - 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohash_to_string.svg': + 'docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geotile_to_string.svg': + 'docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohex_to_string.svg': + 'docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohash_to_long.svg': + 'docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geotile_to_long.svg': + 'docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/images/functions/st_geohex_to_long.svg': + 'docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' - 'reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': to: 'reference/query-languages/esql/esql-functions-operators.md' From 1c4ee72d37acc7aae2643ca50151346a26c223ea Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 11:01:37 +0200 Subject: [PATCH 34/47] Fixed failing tests after type resolution simplification The simplification favoured placing the error on the first parameter, but we'd rather place it on the second. --- .../scalar/spatial/BinarySpatialFunction.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index b088761b3ae5b..6a90bd61b2e36 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -192,13 +192,11 @@ protected TypeResolution resolveType( } TypeResolution resolution = isSameSpatialType(spatialExpression.dataType(), otherExpression, sourceText(), otherParamOrdinal); // TODO Remove these grid checks once we support geo_shape relation to geoGrid - if (resolution.resolved()) { - if (DataType.isGeoGrid(spatialExpression.dataType())) { - resolution = isGeoPoint(otherExpression, otherParamOrdinal); - } - if (DataType.isGeoGrid(otherExpression.dataType())) { - resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); - } + if (resolution.resolved() && DataType.isGeoGrid(spatialExpression.dataType())) { + resolution = isGeoPoint(otherExpression, otherParamOrdinal); + } + if (resolution.resolved() && DataType.isGeoGrid(otherExpression.dataType())) { + resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); } if (resolution.unresolved()) { return resolution; From f12945e3cd49e7070e9ffb169701f7495bf5711c Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 11:02:57 +0200 Subject: [PATCH 35/47] Return to single-line redirects --- docs/redirects.yml | 144 +++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 96 deletions(-) diff --git a/docs/redirects.yml b/docs/redirects.yml index 23bad8808929a..f62713e095338 100644 --- a/docs/redirects.yml +++ b/docs/redirects.yml @@ -88,99 +88,51 @@ redirects: anchors: {'esql-where'} # Dummy redirects for deleted snippets to get round a bug in redirects validation - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' - 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': - to: 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' + 'docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md': 'reference/query-languages/esql/esql-functions-operators.md' From 355c18d548e5066818575bf9c2761c50493b7239 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 12:54:11 +0200 Subject: [PATCH 36/47] Rename function to improve clarity --- .../function/scalar/spatial/BinarySpatialFunction.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index 6a90bd61b2e36..cffd98fc7b9e5 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -153,7 +153,7 @@ protected TypeResolution resolveType() { } } - protected Expression.TypeResolution isSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) { + protected Expression.TypeResolution isCompatibleSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) { return pointsOnly ? EsqlTypeResolutions.isSpatialPoint(e, sourceText(), paramOrd) : (supportsGrid @@ -171,8 +171,8 @@ private TypeResolution resolveType( TypeResolutions.ParamOrdinal leftOrdinal, TypeResolutions.ParamOrdinal rightOrdinal ) { - TypeResolution leftResolution = isSpatial(leftExpression, leftOrdinal); - TypeResolution rightResolution = isSpatial(rightExpression, rightOrdinal); + TypeResolution leftResolution = isCompatibleSpatial(leftExpression, leftOrdinal); + TypeResolution rightResolution = isCompatibleSpatial(rightExpression, rightOrdinal); if (leftResolution.resolved()) { return resolveType(leftExpression, rightExpression, rightOrdinal); } else if (rightResolution.resolved()) { @@ -188,7 +188,7 @@ protected TypeResolution resolveType( TypeResolutions.ParamOrdinal otherParamOrdinal ) { if (isNull(spatialExpression.dataType())) { - return isSpatial(otherExpression, otherParamOrdinal); + return isCompatibleSpatial(otherExpression, otherParamOrdinal); } TypeResolution resolution = isSameSpatialType(spatialExpression.dataType(), otherExpression, sourceText(), otherParamOrdinal); // TODO Remove these grid checks once we support geo_shape relation to geoGrid From 2d700d98555c85d85f8f2d217b0ee80cc4571219 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 14:13:34 +0200 Subject: [PATCH 37/47] Remove support for geogrid in ST_INTERSECTS --- .../functions/parameters/st_disjoint.md | 4 +- .../functions/parameters/st_intersects.md | 4 +- .../_snippets/functions/types/st_disjoint.md | 6 - .../functions/types/st_intersects.md | 6 - .../definition/functions/st_disjoint.json | 140 ++---------------- .../definition/functions/st_intersects.json | 140 ++---------------- .../src/main/resources/spatial-grid.csv-spec | 82 ---------- .../scalar/spatial/BinarySpatialFunction.java | 65 +++----- .../scalar/spatial/SpatialDisjoint.java | 115 ++------------ .../spatial/SpatialEvaluatorFactory.java | 21 --- .../scalar/spatial/SpatialIntersects.java | 115 ++------------ .../spatial/SpatialRelatesFunction.java | 113 +------------- .../scalar/spatial/SpatialRelatesUtils.java | 16 +- .../function/scalar/spatial/StDistance.java | 6 +- .../BinarySpatialFunctionTestCase.java | 130 +++------------- .../scalar/spatial/SpatialDisjointTests.java | 8 - .../spatial/SpatialIntersectsTests.java | 10 +- .../SpatialRelatesFunctionTestCase.java | 8 +- .../scalar/spatial/StDistanceTests.java | 2 +- 19 files changed, 113 insertions(+), 878 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md index 4d0e35831157c..ea2f95d29fead 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_disjoint.md @@ -3,8 +3,8 @@ **Parameters** `geomA` -: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. +: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. `geomB` -: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. +: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md index 4d0e35831157c..ea2f95d29fead 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_intersects.md @@ -3,8 +3,8 @@ **Parameters** `geomA` -: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. +: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. `geomB` -: Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. +: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md index 858e2a29d6404..b26626ad71ffa 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_disjoint.md @@ -10,12 +10,6 @@ | cartesian_shape | cartesian_shape | boolean | | geo_point | geo_point | boolean | | geo_point | geo_shape | boolean | -| geo_point | geohash | boolean | -| geo_point | geohex | boolean | -| geo_point | geotile | boolean | | geo_shape | geo_point | boolean | | geo_shape | geo_shape | boolean | -| geohash | geo_point | boolean | -| geohex | geo_point | boolean | -| geotile | geo_point | boolean | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md index 858e2a29d6404..b26626ad71ffa 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_intersects.md @@ -10,12 +10,6 @@ | cartesian_shape | cartesian_shape | boolean | | geo_point | geo_point | boolean | | geo_point | geo_shape | boolean | -| geo_point | geohash | boolean | -| geo_point | geohex | boolean | -| geo_point | geotile | boolean | | geo_shape | geo_point | boolean | | geo_shape | geo_shape | boolean | -| geohash | geo_point | boolean | -| geohex | geo_point | boolean | -| geotile | geo_point | boolean | diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json index a0fd759e954d1..c86eb75ceaf52 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_disjoint.json @@ -10,13 +10,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -28,13 +28,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -46,13 +46,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -64,13 +64,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -82,13 +82,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -100,67 +100,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geohash", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geohex", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geotile", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -172,13 +118,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -190,67 +136,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geohash", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geohex", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geotile", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json index 4073c12e75c23..cf90c9f67fda0 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_intersects.json @@ -10,13 +10,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -28,13 +28,13 @@ "name" : "geomA", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -46,13 +46,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -64,13 +64,13 @@ "name" : "geomA", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "cartesian_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -82,13 +82,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -100,67 +100,13 @@ "name" : "geomA", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geohash", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geohex", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geotile", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -172,13 +118,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_point", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, @@ -190,67 +136,13 @@ "name" : "geomA", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`." }, { "name" : "geomB", "type" : "geo_shape", "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geohash", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geohex", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." - } - ], - "variadic" : false, - "returnType" : "boolean" - }, - { - "params" : [ - { - "name" : "geomA", - "type" : "geotile", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`." - }, - { - "name" : "geomB", - "type" : "geo_point", - "optional" : false, - "description" : "Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) or a geo-grid value (`geohash`, `geotile`, `geohex`). If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." + "description" : "Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters." } ], "variadic" : false, diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 03d7eda82bee6..c8c14958e2811 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -255,33 +255,6 @@ count:long | centroid:geo_point | geohashString:keywo 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)) ; -gridGeohashDocsFromCell -required_capability: spatial_grid_types - -FROM airports -| WHERE ST_INTERSECTS(location, TO_GEOHASH("u1")) -| STATS - count = COUNT(*), - centroid = ST_CENTROID_AGG(location) -; - -count:long | centroid:geo_point -8 | POINT (6.351574736181647 51.8981519783847) -; - -gridGeohashLiteralFromCell -required_capability: spatial_grid_types - -ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (6.351574736181647 51.8981519783847)", "POINT (5.268637698941997 42.747250193330856)"] -| EVAL location = TO_GEOPOINT(location) -| MV_EXPAND location -| WHERE ST_INTERSECTS(location, "u1"::geohash) -; - -location:geo_point -POINT (6.351574736181647 51.8981519783847) -; - gridGeohashStatsByWhereUK required_capability: spatial_grid_types @@ -590,33 +563,6 @@ count:long | centroid:geo_point | geotileString:keywor 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)) ; -gridGeotileDocsFromCell -required_capability: spatial_grid_types - -FROM airports -| WHERE ST_INTERSECTS(location, TO_GEOTILE("3/4/3")) -| STATS - count = COUNT(*), - centroid = ST_CENTROID_AGG(location) -; - -count:long | centroid:geo_point -79 | POINT (24.516750878736943 23.93036561181085) -; - -gridGeotileLiteralFromCell -required_capability: spatial_grid_types - -ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (24.516750878736943 23.93036561181085)", "POINT (5.268637698941997 42.747250193330856)"] -| EVAL location = TO_GEOPOINT(location) -| MV_EXPAND location -| WHERE ST_INTERSECTS(location, "3/4/3"::geotile) -; - -location:geo_point -POINT (24.516750878736943 23.93036561181085) -; - gridGeotileStatsByWhereUK required_capability: spatial_grid_types @@ -994,34 +940,6 @@ POINT (13.1442589810713 32.6691695504993) | 813fbffffffffff | 813fbffffffffff 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)) ; -gridGeohexDocsFromCell -required_capability: spatial_grid_types - -FROM airports -| WHERE ST_INTERSECTS(location, TO_GEOHEX("81397ffffffffff")) -| STATS - count = COUNT(*), - centroid = ST_CENTROID_AGG(location) -; - -count:long | centroid:geo_point -7 | POINT (2.475211258445467 41.32352174592337) -; - -gridGeohexLiteralFromCell -required_capability: spatial_grid_types - -ROW location = ["POINT (6.360728044651057 47.94084087577894)", "POINT (2.475211258445467 41.32352174592337)", "POINT (5.268637698941997 42.747250193330856)"] -| EVAL location = TO_GEOPOINT(location) -| MV_EXPAND location -| WHERE ST_INTERSECTS(location, "81397ffffffffff"::geohex) -; - -location:geo_point -POINT (2.475211258445467 41.32352174592337) -POINT (5.268637698941997 42.747250193330856) -; - gridGeohexStatsByWhereUK required_capability: spatial_grid_types diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java index cffd98fc7b9e5..437973705f343 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunction.java @@ -27,7 +27,6 @@ import java.io.IOException; import java.util.Objects; -import java.util.function.Predicate; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; @@ -56,17 +55,15 @@ protected BinarySpatialFunction( Expression right, boolean leftDocValues, boolean rightDocValues, - boolean pointsOnly, - boolean supportsGrid + boolean pointsOnly ) { super(source, left, right); this.leftDocValues = leftDocValues; this.rightDocValues = rightDocValues; - this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly, supportsGrid); + this.spatialTypeResolver = new SpatialTypeResolver(this, pointsOnly); } - protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly, boolean supportsGrid) - throws IOException { + protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues, boolean pointsOnly) throws IOException { // The doc-values fields are only used on data nodes local planning, and therefor never serialized this( in.getTransportVersion().onOrAfter(TransportVersions.ESQL_SERIALIZE_SOURCE_FUNCTIONS_WARNINGS) @@ -76,8 +73,7 @@ protected BinarySpatialFunction(StreamInput in, boolean leftDocValues, boolean r in.readNamedWriteable(Expression.class), leftDocValues, rightDocValues, - pointsOnly, - supportsGrid + pointsOnly ); } @@ -123,12 +119,10 @@ protected TypeResolution resolveType() { static class SpatialTypeResolver { private final SpatialEvaluatorFactory.SpatialSourceResolution supplier; private final boolean pointsOnly; - private final boolean supportsGrid; - SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly, boolean supportsGrid) { + SpatialTypeResolver(SpatialEvaluatorFactory.SpatialSourceResolution supplier, boolean pointsOnly) { this.supplier = supplier; this.pointsOnly = pointsOnly; - this.supportsGrid = supportsGrid; } public Expression left() { @@ -153,16 +147,10 @@ protected TypeResolution resolveType() { } } - protected Expression.TypeResolution isCompatibleSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) { + protected Expression.TypeResolution isSpatial(Expression e, TypeResolutions.ParamOrdinal paramOrd) { return pointsOnly ? EsqlTypeResolutions.isSpatialPoint(e, sourceText(), paramOrd) - : (supportsGrid - ? EsqlTypeResolutions.isSpatialOrGrid(e, sourceText(), paramOrd) - : EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd)); - } - - protected Expression.TypeResolution isGeoPoint(Expression e, TypeResolutions.ParamOrdinal paramOrd) { - return isType(e, GEO_POINT::equals, sourceText(), paramOrd, GEO_POINT.typeName()); + : EsqlTypeResolutions.isSpatial(e, sourceText(), paramOrd); } private TypeResolution resolveType( @@ -171,8 +159,8 @@ private TypeResolution resolveType( TypeResolutions.ParamOrdinal leftOrdinal, TypeResolutions.ParamOrdinal rightOrdinal ) { - TypeResolution leftResolution = isCompatibleSpatial(leftExpression, leftOrdinal); - TypeResolution rightResolution = isCompatibleSpatial(rightExpression, rightOrdinal); + TypeResolution leftResolution = isSpatial(leftExpression, leftOrdinal); + TypeResolution rightResolution = isSpatial(rightExpression, rightOrdinal); if (leftResolution.resolved()) { return resolveType(leftExpression, rightExpression, rightOrdinal); } else if (rightResolution.resolved()) { @@ -188,16 +176,9 @@ protected TypeResolution resolveType( TypeResolutions.ParamOrdinal otherParamOrdinal ) { if (isNull(spatialExpression.dataType())) { - return isCompatibleSpatial(otherExpression, otherParamOrdinal); + return isSpatial(otherExpression, otherParamOrdinal); } TypeResolution resolution = isSameSpatialType(spatialExpression.dataType(), otherExpression, sourceText(), otherParamOrdinal); - // TODO Remove these grid checks once we support geo_shape relation to geoGrid - if (resolution.resolved() && DataType.isGeoGrid(spatialExpression.dataType())) { - resolution = isGeoPoint(otherExpression, otherParamOrdinal); - } - if (resolution.resolved() && DataType.isGeoGrid(otherExpression.dataType())) { - resolution = isGeoPoint(spatialExpression, otherParamOrdinal == FIRST ? SECOND : FIRST); - } if (resolution.unresolved()) { return resolution; } @@ -211,12 +192,15 @@ protected TypeResolution isSameSpatialType( String operationName, TypeResolutions.ParamOrdinal paramOrd ) { - Predicate isSpatialType = pointsOnly - ? dt -> dt == spatialDataType - : (supportsGrid - ? dt -> DataType.isSpatialOrGrid(dt) && spatialCRSCompatible(spatialDataType, dt) - : dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt)); - return isType(expression, isSpatialType, operationName, paramOrd, compatibleTypeNames(spatialDataType)); + return pointsOnly + ? isType(expression, dt -> dt == spatialDataType, operationName, paramOrd, compatibleTypeNames(spatialDataType)) + : isType( + expression, + dt -> DataType.isSpatial(dt) && spatialCRSCompatible(spatialDataType, dt), + operationName, + paramOrd, + compatibleTypeNames(spatialDataType) + ); } } @@ -264,7 +248,7 @@ public enum SpatialCrsType { public static SpatialCrsType fromDataType(DataType dataType) { return DataType.isSpatialGeo(dataType) ? SpatialCrsType.GEO - : DataType.isSpatialOrGrid(dataType) ? SpatialCrsType.CARTESIAN + : DataType.isSpatial(dataType) ? SpatialCrsType.CARTESIAN : SpatialCrsType.UNSPECIFIED; } } @@ -294,8 +278,8 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd // The use of foldable here instead of SpatialEvaluatorFieldKey.isConstant is intentional to match the behavior of the // Lucene pushdown code in EsqlTranslationHandler::SpatialRelatesTranslator // We could enhance both places to support ReferenceAttributes that refer to constants, but that is a larger change - return isPushableSpatialAttribute(left(), pushdownPredicates) && isPushableLiteralAttribute(right()) - || isPushableSpatialAttribute(right(), pushdownPredicates) && isPushableLiteralAttribute(left()) + return isPushableSpatialAttribute(left(), pushdownPredicates) && right().foldable() + || isPushableSpatialAttribute(right(), pushdownPredicates) && left().foldable() ? TranslationAware.Translatable.YES : TranslationAware.Translatable.NO; @@ -304,9 +288,4 @@ public TranslationAware.Translatable translatable(LucenePushdownPredicates pushd private static boolean isPushableSpatialAttribute(Expression exp, LucenePushdownPredicates p) { return exp instanceof FieldAttribute fa && DataType.isSpatial(fa.dataType()) && fa.getExactInfo().hasExact() && p.isIndexed(fa); } - - private static boolean isPushableLiteralAttribute(Expression exp) { - // TODO: Support pushdown of geo-grid queries where the constant is a geo-grid-id literal - return DataType.isSpatial(exp.dataType()) && exp.foldable(); - } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java index 0e108df7c4ed3..3e16fa163fcd6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjoint.java @@ -38,15 +38,10 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; -import static org.elasticsearch.xpack.esql.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; -import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; /** * This is the primary class for supporting the function ST_DISJOINT. @@ -86,30 +81,20 @@ public class SpatialDisjoint extends SpatialRelatesFunction { ) public SpatialDisjoint( Source source, - @Param( - name = "geomA", - type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, - description = """ - Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) - or a geo-grid value (`geohash`, `geotile`, `geohex`). - If `null`, the function returns `null`.""" - ) Expression left, - @Param( - name = "geomB", - type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, - description = """ - Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) - or a geo-grid value (`geohash`, `geotile`, `geohex`). - If `null`, the function returns `null`. - The second parameter must also have the same coordinate system as the first. - This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""" - ) Expression right + @Param(name = "geomA", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ + Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. + If `null`, the function returns `null`.""") Expression left, + @Param(name = "geomB", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ + Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. + If `null`, the function returns `null`. + The second parameter must also have the same coordinate system as the first. + This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""") Expression right ) { this(source, left, right, false, false); } private SpatialDisjoint(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, true); + super(source, left, right, leftDocValues, rightDocValues); } private SpatialDisjoint(StreamInput in) throws IOException { @@ -147,11 +132,6 @@ protected NodeInfo info() { @Override public Object fold(FoldContext ctx) { try { - if (DataType.isGeoGrid(left().dataType())) { - return foldGeoGrid(ctx, right(), left(), left().dataType()); - } else if (DataType.isGeoGrid(right().dataType())) { - return foldGeoGrid(ctx, left(), right(), right().dataType()); - } GeometryDocValueReader docValueReader = asGeometryDocValueReader(ctx, crsType(), left()); Component2D component2D = asLuceneComponent2D(ctx, crsType(), right()); return (crsType() == SpatialCrsType.GEO) @@ -162,11 +142,6 @@ public Object fold(FoldContext ctx) { } } - private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gridExp, DataType gridType) throws IOException { - long gridId = (Long) valueOf(ctx, gridExp); - return GEO.compareGeometryAndGrid(makeGeometryFromLiteral(ctx, spatialExp), gridId, gridType); - } - @Override Map> evaluatorRules() { return evaluatorMap; @@ -236,78 +211,6 @@ private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gr } } } - - // Support geo_point and geo-grid types - for (DataType gridType : new DataType[] { GEOHASH, GEOTILE, GEOHEX }) { - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType), - new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( - (s, w, g) -> new SpatialDisjointGeoSourceAndConstantGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType).withLeftDocValues(), - new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( - (s, w, g) -> new SpatialDisjointGeoPointDocValuesAndConstantGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType), - new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( - (s, w, g) -> new SpatialDisjointGeoSourceAndSourceGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType).withLeftDocValues(), - new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( - (s, w, g) -> new SpatialDisjointGeoPointDocValuesAndSourceGridEvaluator.Factory(s, w, g, gridType) - ) - ); - } - } - - @Evaluator(extraName = "GeoSourceAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoSourceAndConstantGrid( - BooleanBlock.Builder results, - int p, - BytesRefBlock wkb, - @Fixed long gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processSourceAndConstantGrid(results, p, wkb, gridId, gridType); - } - - @Evaluator(extraName = "GeoPointDocValuesAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoPointDocValuesAndConstantGrid( - BooleanBlock.Builder results, - int p, - LongBlock encodedPoints, - @Fixed long gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processGeoPointDocValuesAndConstantGrid(results, p, encodedPoints, gridId, gridType); - } - - @Evaluator(extraName = "GeoSourceAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoSourceAndSourceGrid( - BooleanBlock.Builder results, - int p, - BytesRefBlock wkb, - LongBlock gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processSourceAndSourceGrid(results, p, wkb, gridId, gridType); - } - - @Evaluator(extraName = "GeoPointDocValuesAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoPointDocValuesAndSourceGrid( - BooleanBlock.Builder results, - int p, - LongBlock encodedPoints, - LongBlock gridIds, - @Fixed DataType gridType - ) throws IOException { - GEO.processGeoPointDocValuesAndSourceGrid(results, p, encodedPoints, gridIds, gridType); } @Evaluator(extraName = "GeoSourceAndConstant", warnExceptions = { IllegalArgumentException.class, IOException.class }) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java index 8cda0414474eb..dcd53075cf69c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialEvaluatorFactory.java @@ -17,7 +17,6 @@ import java.util.Map; -import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLong; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2Ds; @@ -180,26 +179,6 @@ public EvalOperator.ExpressionEvaluator.Factory get(SpatialSourceSupplier s, Eva } } - /** - * This evaluator factory is used when the right hand side is a geo-grid constant or literal, - * and the left is sourced from the index, or from previous evaluators. - */ - protected static class SpatialEvaluatorWithConstantGridFactory extends SpatialEvaluatorFactory< - EvalOperator.ExpressionEvaluator.Factory, - Long> { - - SpatialEvaluatorWithConstantGridFactory( - TriFunction factoryCreator - ) { - super(factoryCreator); - } - - @Override - public EvalOperator.ExpressionEvaluator.Factory get(SpatialSourceSupplier s, EvaluatorMapper.ToEvaluator toEvaluator) { - return factoryCreator.apply(s.source(), toEvaluator.apply(s.left()), asLong(toEvaluator.foldCtx(), s.right())); - } - } - /** * This evaluator factory is used when the right hand side is a constant or literal, * and the left is sourced from the index, or from previous evaluators. diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java index b3705b5ca9ea3..601550cd173bb 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersects.java @@ -38,15 +38,10 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.CARTESIAN_SHAPE; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE; -import static org.elasticsearch.xpack.esql.expression.Foldables.valueOf; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; -import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral; /** * This is the primary class for supporting the function ST_INTERSECTS. @@ -84,30 +79,20 @@ public class SpatialIntersects extends SpatialRelatesFunction { In mathematical terms: ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅""", examples = @Example(file = "spatial", tag = "st_intersects-airports")) public SpatialIntersects( Source source, - @Param( - name = "geomA", - type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, - description = """ - Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) - or a geo-grid value (`geohash`, `geotile`, `geohex`). - If `null`, the function returns `null`.""" - ) Expression left, - @Param( - name = "geomB", - type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape", "geohash", "geotile", "geohex" }, - description = """ - Expression that is either a geometry (`geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`) - or a geo-grid value (`geohash`, `geotile`, `geohex`). - If `null`, the function returns `null`. - The second parameter must also have the same coordinate system as the first. - This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""" - ) Expression right + @Param(name = "geomA", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ + Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. + If `null`, the function returns `null`.""") Expression left, + @Param(name = "geomB", type = { "geo_point", "cartesian_point", "geo_shape", "cartesian_shape" }, description = """ + Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. + If `null`, the function returns `null`. + The second parameter must also have the same coordinate system as the first. + This means it is not possible to combine `geo_*` and `cartesian_*` parameters.""") Expression right ) { this(source, left, right, false, false); } private SpatialIntersects(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, true); + super(source, left, right, leftDocValues, rightDocValues); } private SpatialIntersects(StreamInput in) throws IOException { @@ -145,11 +130,6 @@ protected NodeInfo info() { @Override public Object fold(FoldContext ctx) { try { - if (DataType.isGeoGrid(left().dataType())) { - return foldGeoGrid(ctx, right(), left(), left().dataType()); - } else if (DataType.isGeoGrid(right().dataType())) { - return foldGeoGrid(ctx, left(), right(), right().dataType()); - } GeometryDocValueReader docValueReader = asGeometryDocValueReader(ctx, crsType(), left()); Component2D component2D = asLuceneComponent2D(ctx, crsType(), right()); return (crsType() == SpatialCrsType.GEO) @@ -160,11 +140,6 @@ public Object fold(FoldContext ctx) { } } - private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gridExp, DataType gridType) throws IOException { - long gridId = (Long) valueOf(ctx, gridExp); - return GEO.compareGeometryAndGrid(makeGeometryFromLiteral(ctx, spatialExp), gridId, gridType); - } - @Override Map> evaluatorRules() { return evaluatorMap; @@ -234,78 +209,6 @@ private Object foldGeoGrid(FoldContext ctx, Expression spatialExp, Expression gr } } } - - // Support geo_point and geo-grid types - for (DataType gridType : new DataType[] { GEOHASH, GEOTILE, GEOHEX }) { - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType), - new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( - (s, w, g) -> new SpatialIntersectsGeoSourceAndConstantGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSourceAndConstant(GEO_POINT, gridType).withLeftDocValues(), - new SpatialEvaluatorFactory.SpatialEvaluatorWithConstantGridFactory( - (s, w, g) -> new SpatialIntersectsGeoPointDocValuesAndConstantGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType), - new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( - (s, w, g) -> new SpatialIntersectsGeoSourceAndSourceGridEvaluator.Factory(s, w, g, gridType) - ) - ); - evaluatorMap.put( - SpatialEvaluatorFactory.SpatialEvaluatorKey.fromSources(GEO_POINT, gridType).withLeftDocValues(), - new SpatialEvaluatorFactory.SpatialEvaluatorFactoryWithFields( - (s, w, g) -> new SpatialIntersectsGeoPointDocValuesAndSourceGridEvaluator.Factory(s, w, g, gridType) - ) - ); - } - } - - @Evaluator(extraName = "GeoSourceAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoSourceAndConstantGrid( - BooleanBlock.Builder results, - int p, - BytesRefBlock wkb, - @Fixed long gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processSourceAndConstantGrid(results, p, wkb, gridId, gridType); - } - - @Evaluator(extraName = "GeoPointDocValuesAndConstantGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoPointDocValuesAndConstantGrid( - BooleanBlock.Builder results, - int p, - LongBlock encodedPoints, - @Fixed long gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processGeoPointDocValuesAndConstantGrid(results, p, encodedPoints, gridId, gridType); - } - - @Evaluator(extraName = "GeoSourceAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoSourceAndSourceGrid( - BooleanBlock.Builder results, - int p, - BytesRefBlock wkb, - LongBlock gridId, - @Fixed DataType gridType - ) throws IOException { - GEO.processSourceAndSourceGrid(results, p, wkb, gridId, gridType); - } - - @Evaluator(extraName = "GeoPointDocValuesAndSourceGrid", warnExceptions = { IllegalArgumentException.class, IOException.class }) - static void processGeoPointDocValuesAndSourceGrid( - BooleanBlock.Builder results, - int p, - LongBlock encodedPoints, - LongBlock gridIds, - @Fixed DataType gridType - ) throws IOException { - GEO.processGeoPointDocValuesAndSourceGrid(results, p, encodedPoints, gridIds, gridType); } @Evaluator(extraName = "GeoSourceAndConstant", warnExceptions = { IllegalArgumentException.class, IOException.class }) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java index 1cfb68cdafc60..1aa6faea83860 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunction.java @@ -12,19 +12,16 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.geo.ShapeRelation; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Fixed; import org.elasticsearch.compute.data.BooleanBlock; import org.elasticsearch.compute.data.BytesRefBlock; import org.elasticsearch.compute.data.LongBlock; import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.geometry.Geometry; -import org.elasticsearch.geometry.Point; -import org.elasticsearch.geometry.utils.Geohash; -import org.elasticsearch.h3.H3; import org.elasticsearch.index.mapper.ShapeIndexer; import org.elasticsearch.lucene.spatial.Component2DVisitor; import org.elasticsearch.lucene.spatial.CoordinateEncoder; import org.elasticsearch.lucene.spatial.GeometryDocValueReader; -import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.xpack.esql.capabilities.TranslationAware; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -44,7 +41,6 @@ import java.io.IOException; import java.util.Map; -import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometry; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asGeometryDocValueReader; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.asLuceneComponent2D; @@ -56,22 +52,11 @@ public abstract class SpatialRelatesFunction extends BinarySpatialFunction SurrogateExpression { protected SpatialRelatesFunction(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, false, false); - } - - protected SpatialRelatesFunction( - Source source, - Expression left, - Expression right, - boolean leftDocValues, - boolean rightDocValues, - boolean supportsGrid - ) { - super(source, left, right, leftDocValues, rightDocValues, false, supportsGrid); + super(source, left, right, leftDocValues, rightDocValues, false); } protected SpatialRelatesFunction(StreamInput in, boolean leftDocValues, boolean rightDocValues) throws IOException { - super(in, leftDocValues, rightDocValues, false, false); + super(in, leftDocValues, rightDocValues, false); } public abstract ShapeRelation queryRelation(); @@ -131,94 +116,7 @@ protected boolean geometryRelatesGeometry(GeometryDocValueReader reader, Compone return visitor.matches(); } - protected void processSourceAndConstantGrid( - BooleanBlock.Builder builder, - int position, - BytesRefBlock wkb, - long gridId, - DataType gridType - ) { - if (wkb.getValueCount(position) < 1) { - builder.appendNull(); - } else { - builder.appendBoolean(compareGeometryAndGrid(asGeometry(wkb, position), gridId, gridType)); - } - } - - protected void processSourceAndSourceGrid( - BooleanBlock.Builder builder, - int position, - BytesRefBlock wkb, - LongBlock gridIds, - DataType gridType - ) { - if (wkb.getValueCount(position) < 1 || gridIds.getValueCount(position) < 1) { - builder.appendNull(); - } else { - builder.appendBoolean(compareGeometryAndGrid(asGeometry(wkb, position), gridIds.getLong(position), gridType)); - } - } - - protected boolean compareGeometryAndGrid(Geometry geometry, long gridId, DataType gridType) { - if (geometry instanceof Point point) { - long geoGridId = getGridId(point, gridId, gridType); - return gridId == geoGridId; - } else { - throw new IllegalArgumentException( - "Unsupported grid intersection geometry type: " + geometry.getClass().getSimpleName() + "; expected Point" - ); - } - } - - protected void processGeoPointDocValuesAndConstantGrid( - BooleanBlock.Builder builder, - int position, - LongBlock encodedPoint, - long gridId, - DataType gridType - ) { - if (encodedPoint.getValueCount(position) < 1) { - builder.appendNull(); - } else { - final Point point = spatialCoordinateType.longAsPoint(encodedPoint.getLong(position)); - long geoGridId = getGridId(point, gridId, gridType); - builder.appendBoolean(gridId == geoGridId); - } - } - - protected void processGeoPointDocValuesAndSourceGrid( - BooleanBlock.Builder builder, - int position, - LongBlock encodedPoint, - LongBlock gridIds, - DataType gridType - ) { - if (encodedPoint.getValueCount(position) < 1 || gridIds.getValueCount(position) < 1) { - builder.appendNull(); - } else { - final Point point = spatialCoordinateType.longAsPoint(encodedPoint.getLong(position)); - final long gridId = gridIds.getLong(position); - long geoGridId = getGridId(point, gridId, gridType); - builder.appendBoolean(gridId == geoGridId); - } - } - - private long getGridId(Point point, long gridId, DataType gridType) { - return switch (gridType) { - case GEOHASH -> Geohash.longEncode(point.getX(), point.getY(), Geohash.stringEncode(gridId).length()); - case GEOTILE -> GeoTileUtils.longEncode( - point.getX(), - point.getY(), - Integer.parseInt(GeoTileUtils.stringEncode(gridId).split("/")[0]) - ); - case GEOHEX -> H3.geoToH3(point.getY(), point.getX(), H3.getResolution(gridId)); - default -> throw new IllegalArgumentException( - "Unsupported grid type: " + gridType + "; expected GEOHASH, GEOTILE, or GEOHEX" - ); - }; - } - - protected void processSourceAndConstant(BooleanBlock.Builder builder, int position, BytesRefBlock left, Component2D right) + protected void processSourceAndConstant(BooleanBlock.Builder builder, int position, BytesRefBlock left, @Fixed Component2D right) throws IOException { if (left.getValueCount(position) < 1) { builder.appendNull(); @@ -243,7 +141,7 @@ protected void processPointDocValuesAndConstant( BooleanBlock.Builder builder, int position, LongBlock leftValue, - Component2D rightValue + @Fixed Component2D rightValue ) throws IOException { if (leftValue.getValueCount(position) < 1) { builder.appendNull(); @@ -314,7 +212,6 @@ private Query translate(TranslatorHandler handler, Expression spatialExpression, String name = handler.nameOf(attribute); try { - // TODO: Support geo-grid query pushdown Geometry shape = SpatialRelatesUtils.makeGeometryFromLiteral(constantExpression); return new SpatialRelatesQuery(source(), name, queryRelation(), shape, attribute.dataType()); } catch (IllegalArgumentException e) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java index 89fccfc34faa4..0d323ad8cb856 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesUtils.java @@ -43,20 +43,6 @@ public class SpatialRelatesUtils { - /** Converts a {@link Expression} into a {@link Long}. */ - static Long asLong(FoldContext ctx, Expression expression) { - Object value = valueOf(ctx, expression); - if (value instanceof Long longValue) { - return longValue; - } else if (value instanceof Integer intValue) { - return intValue.longValue(); - } else { - throw new IllegalArgumentException( - "Unsupported combination of literal [" + value.getClass().getSimpleName() + "] of type [" + expression.dataType() + "]" - ); - } - } - /** Converts a {@link Expression} into a {@link Component2D}. */ static Component2D asLuceneComponent2D(FoldContext ctx, BinarySpatialFunction.SpatialCrsType crsType, Expression expression) { return asLuceneComponent2D(crsType, makeGeometryFromLiteral(ctx, expression)); @@ -168,7 +154,7 @@ static GeometryDocValueReader asGeometryDocValueReader( return asGeometryDocValueReader(encoder, shapeIndexer, asGeometry(valueBlock, position)); } - static Geometry asGeometry(BytesRefBlock valueBlock, int position) { + private static Geometry asGeometry(BytesRefBlock valueBlock, int position) { final BytesRef scratch = new BytesRef(); final int firstValueIndex = valueBlock.getFirstValueIndex(position); final int valueCount = valueBlock.getValueCount(position); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java index e318d79848cc4..f0c25e3289cc1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistance.java @@ -241,15 +241,15 @@ public StDistance( The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_point` and `cartesian_point` parameters.""") Expression right ) { - super(source, left, right, false, false, true, false); + super(source, left, right, false, false, true); } protected StDistance(Source source, Expression left, Expression right, boolean leftDocValues, boolean rightDocValues) { - super(source, left, right, leftDocValues, rightDocValues, true, false); + super(source, left, right, leftDocValues, rightDocValues, true); } private StDistance(StreamInput in) throws IOException { - super(in, false, false, true, false); + super(in, false, false, true); } @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index ab0ef54599077..68dd600489393 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -10,7 +10,6 @@ import joptsimple.internal.Strings; import org.apache.lucene.util.BytesRef; -import org.elasticsearch.geometry.Geometry; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.TypeResolutions; import org.elasticsearch.xpack.esql.core.type.DataType; @@ -29,11 +28,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; -import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialOrGrid; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction.compatibleTypeNames; import static org.hamcrest.Matchers.equalTo; @@ -53,20 +49,17 @@ protected static Class getSpatialRelatesFunctionClass() throws ClassNotFoundE public static TestCaseSupplier.TypedDataSupplier testCaseSupplier(DataType dataType, boolean pointsOnly) { if (pointsOnly) { - return switch (dataType) { - case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + return switch (dataType.esType()) { + case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } else { - return switch (dataType) { - case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case GEO_SHAPE -> TestCaseSupplier.geoShapeCases(() -> false).get(0); - case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); - case CARTESIAN_SHAPE -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); - case GEOHASH -> TestCaseSupplier.geoGridCases(GEOHASH, () -> false).get(0); - case GEOTILE -> TestCaseSupplier.geoGridCases(GEOTILE, () -> false).get(0); - case GEOHEX -> TestCaseSupplier.geoGridCases(GEOHEX, () -> false).get(0); + return switch (dataType.esType()) { + case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case "geo_shape" -> TestCaseSupplier.geoShapeCases(() -> false).get(0); + case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + case "cartesian_shape" -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } @@ -101,39 +94,6 @@ protected static void addSpatialCombinations( } } - /** - * Binary spatial functions that take two spatial arguments, one of which is a gridId, - * should use this to generate combinations of test cases. - */ - protected static void addSpatialGridCombinations(List suppliers, DataType[] dataTypes, DataType returnType) { - for (DataType leftType : dataTypes) { - TestCaseSupplier.TypedDataSupplier leftDataSupplier = testCaseSupplier(leftType, true); - for (DataType rightType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { - if (typeCompatible(leftType, rightType)) { - TestCaseSupplier.TypedDataSupplier rightDataSupplier = testCaseSupplier(rightType, false); - suppliers.add( - TestCaseSupplier.testCaseSupplier( - leftDataSupplier, - rightDataSupplier, - BinarySpatialFunctionTestCase::spatialEvaluatorString, - returnType, - (l, r) -> expected(l, leftType, r, rightType) - ) - ); - suppliers.add( - TestCaseSupplier.testCaseSupplier( - rightDataSupplier, - leftDataSupplier, - BinarySpatialFunctionTestCase::spatialEvaluatorString, - returnType, - (l, r) -> expected(l, rightType, r, leftType) - ) - ); - } - } - } - } - /** * Build the expected error message for an invalid type signature. * For two args, this assumes they are both spatial. @@ -143,8 +103,7 @@ protected static String typeErrorMessage( boolean includeOrdinal, List> validPerPosition, List types, - boolean pointsOnly, - boolean supportsGrid + boolean pointsOnly ) { boolean argInvalid = false; List badArgPositions = new ArrayList<>(); @@ -168,22 +127,15 @@ protected static String typeErrorMessage( if (badArgPositions.size() == 1) { int badArgPosition = badArgPositions.get(0); int goodArgPosition = badArgPosition == 0 ? 1 : 0; - if (DataType.isGeoGrid(types.get(goodArgPosition))) { - // When the valid position is a grid, the other type can only be points - return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, true, supportsGrid); - } else if (isSpatialOrGrid(types.get(goodArgPosition)) == false) { - return oneInvalid(badArgPosition, -1, includeOrdinal, types, pointsOnly, supportsGrid); + if (isSpatial(types.get(goodArgPosition)) == false) { + return oneInvalid(badArgPosition, -1, includeOrdinal, types, pointsOnly); } else { - return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, pointsOnly, supportsGrid); + return oneInvalid(badArgPosition, goodArgPosition, includeOrdinal, types, pointsOnly); } } else if (argInvalid && badArgPositions.size() != 2) { return invalidArg(types.get(2)); - } else if (supportsGrid && DataType.isGeoGrid(types.get(0))) { - return invalidGrid(1, types, true); - } else if (supportsGrid && DataType.isGeoGrid(types.get(1))) { - return invalidGrid(0, types, true); } else { - return oneInvalid(0, -1, includeOrdinal, types, pointsOnly, supportsGrid); + return oneInvalid(0, -1, includeOrdinal, types, pointsOnly); } } @@ -199,26 +151,14 @@ private static String invalidArg(DataType invalidType) { ); } - private static String invalidGrid(int badArgPosition, List types, boolean pointsOnly) { - String expectedType = pointsOnly ? "geo_point" : "geo_point or geo_shape"; - String ordinal = TypeResolutions.ParamOrdinal.fromIndex(badArgPosition).name().toLowerCase(Locale.ROOT) + " "; - String name = types.get(badArgPosition).typeName(); - return ordinal + "argument of [source] must be [" + expectedType + "], found value [" + name + "] type [" + name + "]"; - } - private static String oneInvalid( int badArgPosition, int goodArgPosition, boolean includeOrdinal, List types, - boolean pointsOnly, - boolean supportsGrid + boolean pointsOnly ) { - String expected = pointsOnly - ? "geo_point or cartesian_point" - : (supportsGrid - ? "geo_point, cartesian_point, geo_shape, cartesian_shape, geohash, geotile or geohex" - : "geo_point, cartesian_point, geo_shape or cartesian_shape"); + String expected = pointsOnly ? "geo_point or cartesian_point" : "geo_point, cartesian_point, geo_shape or cartesian_shape"; String ordinal = includeOrdinal ? TypeResolutions.ParamOrdinal.fromIndex(badArgPosition).name().toLowerCase(Locale.ROOT) + " " : ""; String expectedType = goodArgPosition >= 0 ? compatibleTypes(types.get(goodArgPosition)) : expected; String name = types.get(badArgPosition).typeName(); @@ -233,33 +173,17 @@ protected static Object expected(Object left, DataType leftType, Object right, D if (typeCompatible(leftType, rightType) == false) { return null; } + // TODO cast objects to right type and check intersection + BytesRef leftWKB = asGeometryWKB(left, leftType); + BytesRef rightWKB = asGeometryWKB(right, rightType); BinarySpatialFunction.BinarySpatialComparator spatialRelations = spatialRelations(left, leftType, right, rightType); try { - if (DataType.isGeoGrid(leftType)) { - return expectedGrid(spatialRelations, asGeometryWKB(right, rightType), left, leftType); - } else if (DataType.isGeoGrid(rightType)) { - return expectedGrid(spatialRelations, asGeometryWKB(left, leftType), right, rightType); - } else { - BytesRef leftWKB = asGeometryWKB(left, leftType); - BytesRef rightWKB = asGeometryWKB(right, rightType); - return spatialRelations.compare(leftWKB, rightWKB); - } + return spatialRelations.compare(leftWKB, rightWKB); } catch (IOException e) { throw new RuntimeException(e); } } - private static boolean expectedGrid( - BinarySpatialFunction.BinarySpatialComparator spatialRelations, - BytesRef wkb, - Object grid, - DataType gridType - ) { - Geometry geometry = SpatialCoordinateTypes.UNSPECIFIED.wkbToGeometry(wkb); - long gridId = Long.parseLong(grid.toString()); - return ((SpatialRelatesFunction.SpatialRelations) spatialRelations).compareGeometryAndGrid(geometry, gridId, gridType); - } - /** * When two spatial arguments are processed and then compared with a third argument, * we need to process this argument too, before producing the final result. @@ -297,7 +221,7 @@ private static BinarySpatialFunction.BinarySpatialComparator spatialRelations ) { if (isSpatialGeo(leftType) || isSpatialGeo(rightType)) { return getRelationsField("GEO"); - } else if (isSpatialOrGrid(leftType) || isSpatialOrGrid(rightType)) { + } else if (isSpatial(leftType) || isSpatial(rightType)) { return getRelationsField("CARTESIAN"); } else { throw new IllegalArgumentException( @@ -325,7 +249,7 @@ protected static BytesRef asGeometryWKB(Object object, DataType dataType) { } protected static boolean typeCompatible(DataType leftType, DataType rightType) { - if (isSpatialOrGrid(leftType) && isSpatialOrGrid(rightType)) { + if (isSpatial(leftType) && isSpatial(rightType)) { // Both must be GEO_* or both must be CARTESIAN_* return countGeo(leftType, rightType) != 1; } @@ -333,9 +257,9 @@ protected static boolean typeCompatible(DataType leftType, DataType rightType) { } private static DataType pickSpatialType(DataType leftType, DataType rightType) { - if (isSpatialOrGrid(leftType)) { + if (isSpatial(leftType)) { return leftType; - } else if (isSpatialOrGrid(rightType)) { + } else if (isSpatial(rightType)) { return rightType; } else { throw new IllegalArgumentException("Invalid spatial types: " + leftType + " and " + rightType); @@ -344,12 +268,6 @@ private static DataType pickSpatialType(DataType leftType, DataType rightType) { private static Matcher spatialEvaluatorString(DataType leftType, DataType rightType) { String crsType = isSpatialGeo(pickSpatialType(leftType, rightType)) ? "Geo" : "Cartesian"; - if (DataType.isGeoGrid(leftType) || DataType.isGeoGrid(rightType)) { - int[] c = DataType.isGeoGrid(leftType) ? new int[] { 1, 0 } : new int[] { 0, 1 }; - DataType gridType = DataType.isGeoGrid(leftType) ? leftType : rightType; - String channelText = "wkb=Attribute[channel=" + c[0] + "], gridId=Attribute[channel=" + c[1] + "], gridType=" + gridType; - return equalTo(getFunctionClassName() + crsType + "SourceAndSourceGridEvaluator[" + channelText + "]"); - } String channels = channelsText("left", "right"); return equalTo(getFunctionClassName() + crsType + "SourceAndSourceEvaluator[" + channels + "]"); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java index 2c1ccb347d8bc..b3feac5619c16 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialDisjointTests.java @@ -18,11 +18,8 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.function.Supplier; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; - @FunctionName("st_disjoint") public class SpatialDisjointTests extends SpatialRelatesFunctionTestCase { public SpatialDisjointTests(@Name("TestCase") Supplier testCaseSupplier) { @@ -32,7 +29,6 @@ public SpatialDisjointTests(@Name("TestCase") Supplier parameters() { List suppliers = new ArrayList<>(); - SpatialRelatesFunctionTestCase.addSpatialGridCombinations(suppliers, GEO_POINT); DataType[] geoDataTypes = { DataType.GEO_POINT, DataType.GEO_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, geoDataTypes); DataType[] cartesianDataTypes = { DataType.CARTESIAN_POINT, DataType.CARTESIAN_SHAPE }; @@ -46,8 +42,4 @@ public static Iterable parameters() { protected Expression build(Source source, List args) { return new SpatialDisjoint(source, args.get(0), args.get(1)); } - - protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, false, true); - } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java index d651402214a10..ccf94bf6d2760 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialIntersectsTests.java @@ -18,11 +18,8 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.function.Supplier; -import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_POINT; - @FunctionName("st_intersects") public class SpatialIntersectsTests extends SpatialRelatesFunctionTestCase { public SpatialIntersectsTests(@Name("TestCase") Supplier testCaseSupplier) { @@ -32,8 +29,7 @@ public SpatialIntersectsTests(@Name("TestCase") Supplier parameters() { List suppliers = new ArrayList<>(); - SpatialRelatesFunctionTestCase.addSpatialGridCombinations(suppliers, GEO_POINT); - DataType[] geoDataTypes = { GEO_POINT, DataType.GEO_SHAPE }; + DataType[] geoDataTypes = { DataType.GEO_POINT, DataType.GEO_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, geoDataTypes); DataType[] cartesianDataTypes = { DataType.CARTESIAN_POINT, DataType.CARTESIAN_SHAPE }; SpatialRelatesFunctionTestCase.addSpatialCombinations(suppliers, cartesianDataTypes); @@ -46,8 +42,4 @@ public static Iterable parameters() { protected Expression build(Source source, List args) { return new SpatialIntersects(source, args.get(0), args.get(1)); } - - protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, false, true); - } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java index 756ebc08bab0a..53ed472a4d43f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialRelatesFunctionTestCase.java @@ -15,15 +15,11 @@ public abstract class SpatialRelatesFunctionTestCase extends BinarySpatialFunctionTestCase { - protected static void addSpatialCombinations(List suppliers, DataType... dataTypes) { + protected static void addSpatialCombinations(List suppliers, DataType[] dataTypes) { addSpatialCombinations(suppliers, dataTypes, DataType.BOOLEAN, false); } - protected static void addSpatialGridCombinations(List suppliers, DataType... dataTypes) { - addSpatialGridCombinations(suppliers, dataTypes, DataType.BOOLEAN); - } - protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, false, false); + return typeErrorMessage(includeOrdinal, validPerPosition, types, false); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java index 06958b94a492f..c78977918fc5e 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StDistanceTests.java @@ -49,6 +49,6 @@ protected static void addSpatialCombinations(List suppliers, D } protected static String typeErrorMessage(boolean includeOrdinal, List> validPerPosition, List types) { - return typeErrorMessage(includeOrdinal, validPerPosition, types, true, false); + return typeErrorMessage(includeOrdinal, validPerPosition, types, true); } } From 7f831c83a5e7f751e41d05125f9b1a2cb3770ab4 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Tue, 26 Aug 2025 14:20:01 +0200 Subject: [PATCH 38/47] Bring back function supporting grid types in other tests --- .../BinarySpatialFunctionTestCase.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java index 68dd600489393..1f53ea4d9a72c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/BinarySpatialFunctionTestCase.java @@ -28,6 +28,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHASH; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOHEX; +import static org.elasticsearch.xpack.esql.core.type.DataType.GEOTILE; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatial; import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; import static org.elasticsearch.xpack.esql.core.type.DataType.isString; @@ -49,17 +52,20 @@ protected static Class getSpatialRelatesFunctionClass() throws ClassNotFoundE public static TestCaseSupplier.TypedDataSupplier testCaseSupplier(DataType dataType, boolean pointsOnly) { if (pointsOnly) { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } else { - return switch (dataType.esType()) { - case "geo_point" -> TestCaseSupplier.geoPointCases(() -> false).get(0); - case "geo_shape" -> TestCaseSupplier.geoShapeCases(() -> false).get(0); - case "cartesian_point" -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); - case "cartesian_shape" -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); + return switch (dataType) { + case GEO_POINT -> TestCaseSupplier.geoPointCases(() -> false).get(0); + case GEO_SHAPE -> TestCaseSupplier.geoShapeCases(() -> false).get(0); + case CARTESIAN_POINT -> TestCaseSupplier.cartesianPointCases(() -> false).get(0); + case CARTESIAN_SHAPE -> TestCaseSupplier.cartesianShapeCases(() -> false).get(0); + case GEOHASH -> TestCaseSupplier.geoGridCases(GEOHASH, () -> false).get(0); + case GEOTILE -> TestCaseSupplier.geoGridCases(GEOTILE, () -> false).get(0); + case GEOHEX -> TestCaseSupplier.geoGridCases(GEOHEX, () -> false).get(0); default -> throw new IllegalArgumentException("Unsupported datatype for " + functionName() + ": " + dataType); }; } From 32db04036661a4a4e7b236e1d028bb4531f98aa6 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Wed, 27 Aug 2025 12:18:35 +0200 Subject: [PATCH 39/47] Fix evaluators after merging in main --- .../function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java | 2 +- .../function/scalar/convert/ToGeohashFromStringEvaluator.java | 2 +- .../function/scalar/convert/ToGeohexFromStringEvaluator.java | 2 +- .../function/scalar/convert/ToGeotileFromStringEvaluator.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java index eecabaa58ac8c..c87b99790f7f4 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeoShapeFromGeoGridEvaluator.java @@ -125,7 +125,7 @@ public void close() { @Override public long baseRamBytesUsed() { long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += gridId.baseRamBytesUsed(); + baseRamBytesUsed += in.baseRamBytesUsed(); return baseRamBytesUsed; } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java index ac97c6b7b7a38..5eeca08465d34 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashFromStringEvaluator.java @@ -123,7 +123,7 @@ public void close() { @Override public long baseRamBytesUsed() { long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += gridId.baseRamBytesUsed(); + baseRamBytesUsed += in.baseRamBytesUsed(); return baseRamBytesUsed; } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java index b26b580a6e244..f3bc3f3aec410 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexFromStringEvaluator.java @@ -123,7 +123,7 @@ public void close() { @Override public long baseRamBytesUsed() { long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += gridId.baseRamBytesUsed(); + baseRamBytesUsed += in.baseRamBytesUsed(); return baseRamBytesUsed; } diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java index 70322f1a72db2..a77c85d7415fe 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileFromStringEvaluator.java @@ -123,7 +123,7 @@ public void close() { @Override public long baseRamBytesUsed() { long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += gridId.baseRamBytesUsed(); + baseRamBytesUsed += in.baseRamBytesUsed(); return baseRamBytesUsed; } From 8ee289198276de42d70073a9b2c160b365a59b6c Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 12:22:44 +0200 Subject: [PATCH 40/47] Support self conversions for the three new types --- .../esql/_snippets/functions/types/to_geohash.md | 1 + .../esql/_snippets/functions/types/to_geohex.md | 1 + .../esql/_snippets/functions/types/to_geotile.md | 1 + .../esql/kibana/definition/functions/to_geohash.json | 12 ++++++++++++ .../esql/kibana/definition/functions/to_geohex.json | 12 ++++++++++++ .../esql/kibana/definition/functions/to_geotile.json | 12 ++++++++++++ .../function/scalar/convert/ToGeohash.java | 3 ++- .../expression/function/scalar/convert/ToGeohex.java | 3 ++- .../function/scalar/convert/ToGeotile.java | 3 ++- .../function/scalar/convert/ToGeohashErrorTests.java | 2 +- .../function/scalar/convert/ToGeohashTests.java | 1 + .../function/scalar/convert/ToGeohexTests.java | 1 + .../function/scalar/convert/ToGeohexhErrorTests.java | 2 +- .../function/scalar/convert/ToGeotileErrorTests.java | 2 +- .../function/scalar/convert/ToGeotileTests.java | 1 + 15 files changed, 51 insertions(+), 6 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md index dadea0b9fba6d..6d33be50ce1ad 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohash.md @@ -4,6 +4,7 @@ | field | result | | --- | --- | +| geohash | geohash | | keyword | geohash | | long | geohash | | text | geohash | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md index 350d8a9f19c3e..aafc34a5ef106 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geohex.md @@ -4,6 +4,7 @@ | field | result | | --- | --- | +| geohex | geohex | | keyword | geohex | | long | geohex | | text | geohex | diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md index 72636c88e1abf..832f77b5563f9 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/to_geotile.md @@ -4,6 +4,7 @@ | field | result | | --- | --- | +| geotile | geotile | | keyword | geotile | | long | geotile | | text | geotile | diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json index e49f0c22fba6a..9c6645f19f2eb 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohash.json @@ -4,6 +4,18 @@ "name" : "to_geohash", "description" : "Converts an input value to a `geohash` value.\nA string will only be successfully converted if it respects the\n`geohash` format.", "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "geohash", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohash" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json index 43bc359fc0f9e..9d75a0d5db755 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geohex.json @@ -4,6 +4,18 @@ "name" : "to_geohex", "description" : "Converts an input value to a `geohex` value.\nA string will only be successfully converted if it respects the\n`geohex` format.", "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "geohex", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geohex" + }, { "params" : [ { diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json index 34da9be3a9c65..85879c996dad7 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/to_geotile.json @@ -4,6 +4,18 @@ "name" : "to_geotile", "description" : "Converts an input value to a `geotile` value.\nA string will only be successfully converted if it respects the\n`geotile` format.", "signatures" : [ + { + "params" : [ + { + "name" : "field", + "type" : "geotile", + "optional" : false, + "description" : "Input value. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geotile" + }, { "params" : [ { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java index f289d7f878514..0ea490098ca6f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohash.java @@ -39,6 +39,7 @@ public class ToGeohash extends AbstractConvertFunction { ); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(GEOHASH, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeohashFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeohashFromStringEvaluator.Factory::new) @@ -58,7 +59,7 @@ public ToGeohash( Source source, @Param( name = "field", - type = { "long", "keyword", "text" }, + type = { "geohash", "long", "keyword", "text" }, description = "Input value. The input can be a single- or multi-valued column or an expression." ) Expression field ) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java index 1fbb14818a06a..4ccda5cea66f8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohex.java @@ -35,6 +35,7 @@ public class ToGeohex extends AbstractConvertFunction { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "ToGeohex", ToGeohex::new); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(GEOHEX, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeohexFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeohexFromStringEvaluator.Factory::new) @@ -54,7 +55,7 @@ public ToGeohex( Source source, @Param( name = "field", - type = { "long", "keyword", "text" }, + type = { "geohex", "long", "keyword", "text" }, description = "Input value. The input can be a single- or multi-valued column or an expression." ) Expression field ) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java index 05a83e30dcb1a..ea2c3075a9303 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotile.java @@ -39,6 +39,7 @@ public class ToGeotile extends AbstractConvertFunction { ); private static final Map EVALUATORS = Map.ofEntries( + Map.entry(GEOTILE, (source, fieldEval) -> fieldEval), Map.entry(LONG, (source, fieldEval) -> fieldEval), Map.entry(KEYWORD, ToGeotileFromStringEvaluator.Factory::new), Map.entry(TEXT, ToGeotileFromStringEvaluator.Factory::new) @@ -58,7 +59,7 @@ public ToGeotile( Source source, @Param( name = "field", - type = { "long", "keyword", "text" }, + type = { "geotile", "long", "keyword", "text" }, description = "Input value. The input can be a single- or multi-valued column or an expression." ) Expression field ) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java index 7c8a154ea1371..aefe38d0f8685 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashErrorTests.java @@ -32,6 +32,6 @@ protected Expression build(Source source, List args) { @Override protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { - return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "geohash or long or string")); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java index d6551404f9ed7..d9c0be69ac42a 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohashTests.java @@ -35,6 +35,7 @@ public static Iterable parameters() { final String evaluator = "ToGeohashFromStringEvaluator[in=Attribute[channel=0]]"; final List suppliers = new ArrayList<>(); + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.GEOHASH, DataType.GEOHASH, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOHASH, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOHASH, ToGeohashTests::valueOf, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOHASH, ToGeohashTests::valueOf, List.of()); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java index ca0b3b9c06bc5..75eefec4b3c96 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexTests.java @@ -35,6 +35,7 @@ public static Iterable parameters() { final String evaluator = "ToGeohexFromStringEvaluator[in=Attribute[channel=0]]"; final List suppliers = new ArrayList<>(); + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.GEOHEX, DataType.GEOHEX, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOHEX, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOHEX, ToGeohexTests::valueOf, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOHEX, ToGeohexTests::valueOf, List.of()); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java index 63f578c2c34a7..24e2521731bde 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeohexhErrorTests.java @@ -32,6 +32,6 @@ protected Expression build(Source source, List args) { @Override protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { - return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "geohex or long or string")); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java index 6e5e41c965a21..9696b7399e830 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileErrorTests.java @@ -32,6 +32,6 @@ protected Expression build(Source source, List args) { @Override protected Matcher expectedTypeErrorMatcher(List> validPerPosition, List signature) { - return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "long or string")); + return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "geotile or long or string")); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java index aa3e5c143f66e..49776099ada9f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToGeotileTests.java @@ -35,6 +35,7 @@ public static Iterable parameters() { final String evaluator = "ToGeotileFromStringEvaluator[in=Attribute[channel=0]]"; final List suppliers = new ArrayList<>(); + TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.GEOTILE, DataType.GEOTILE, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, attribute, DataType.LONG, DataType.GEOTILE, v -> v, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.KEYWORD, DataType.GEOTILE, ToGeotileTests::valueOf, List.of()); TestCaseSupplier.forUnaryGeoGrid(suppliers, evaluator, DataType.TEXT, DataType.GEOTILE, ToGeotileTests::valueOf, List.of()); From df81c7ced73e7a04e2c51bf0fce90e1562cfbebe Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 13:36:25 +0200 Subject: [PATCH 41/47] Add csv tests for count(grid) --- .../src/main/resources/spatial-grid.csv-spec | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index c8c14958e2811..116e1bd75dd5f 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -140,7 +140,7 @@ required_capability: spatial_grid_types FROM airports | EVAL geohash = ST_GEOHASH(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 @@ -179,7 +179,7 @@ FROM airports | WHERE ST_GEOHASH(location, 1) == TO_GEOHASH("7") | EVAL geohash = ST_GEOHASH(location, 2) | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | EVAL geohashString = TO_STRING(geohash) @@ -202,7 +202,7 @@ FROM airports | EVAL geohash = ST_GEOHASH(location, 2, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) | WHERE geohash IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | EVAL geohashString = TO_STRING(geohash) @@ -232,7 +232,7 @@ FROM airports | 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))"))) | WHERE geohash IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | EVAL geohashString = TO_STRING(geohash) @@ -476,7 +476,7 @@ required_capability: spatial_grid_types FROM airports | EVAL geotile = ST_GEOTILE(location, 2) | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile) @@ -508,7 +508,7 @@ FROM airports | WHERE ST_GEOTILE(location, 2) == TO_GEOTILE("2/0/2") | EVAL geotile = ST_GEOTILE(location, 3) | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile) @@ -528,7 +528,7 @@ FROM airports | EVAL geotile = ST_GEOTILE(location, 3, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) | WHERE geotile IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile) @@ -549,7 +549,7 @@ FROM airports | 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))"))) | WHERE geotile IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile) @@ -776,7 +776,7 @@ required_capability: spatial_grid_types FROM airports | EVAL geohex = ST_GEOHEX(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 @@ -809,7 +809,7 @@ FROM airports | WHERE ST_GEOHEX(location, 1) == TO_GEOHEX("812bbffffffffff") | EVAL geohex = ST_GEOHEX(location, 2) | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | EVAL geohexString = TO_STRING(geohex) @@ -833,7 +833,7 @@ FROM airports | EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("BBOX(0.0, 12.0, 60.0, 30.0)")) | WHERE geohex IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | EVAL geohexString = TO_STRING(geohex) @@ -863,7 +863,7 @@ FROM airports | 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))"))) | WHERE geohex IS NOT NULL | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | EVAL geohexString = TO_STRING(geohex) From 484d87e3d5c70f0096cb2efcb8d750478798f087 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 13:45:36 +0200 Subject: [PATCH 42/47] Added self-conversions to csv-spec tests --- .../src/main/resources/spatial-grid.csv-spec | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 116e1bd75dd5f..5fe20a57d5945 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -24,12 +24,13 @@ required_capability: spatial_grid_types ROW string = "u3bu" | EVAL geohash = TO_GEOHASH(string) | EVAL geohashLong = TO_LONG(geohash) +| EVAL geohash2 = TO_GEOHASH(geohash) // end::to_geohash_to_long[] ; // tag::to_geohash_to_long-result[] -string:keyword | geohash:geohash | geohashLong:long -u3bu | u3bu | 13686180 +string:keyword | geohash:geohash | geohashLong:long | geohash2:geohash +u3bu | u3bu | 13686180 | u3bu // end::to_geohash_to_long-result[] ; @@ -371,12 +372,13 @@ required_capability: spatial_grid_types ROW string = "4/8/5" | EVAL geotile = TO_GEOTILE(string) | EVAL geotileLong = TO_LONG(geotile) +| EVAL geotile2 = TO_GEOTILE(geotile) // end::to_geotile_to_long[] ; // tag::to_geotile_to_long-result[] -string:keyword | geotile:geotile | geotileLong:long -4/8/5 | 4/8/5 | 1152921508901814277 +string:keyword | geotile:geotile | geotileLong:long | geotile2:geotile +4/8/5 | 4/8/5 | 1152921508901814277 | 4/8/5 // end::to_geotile_to_long-result[] ; @@ -671,12 +673,13 @@ required_capability: spatial_grid_types ROW string = "841f059ffffffff" | EVAL geohex = TO_GEOHEX(string) | EVAL geohexLong = TO_LONG(geohex) +| EVAL geohex2 = TO_GEOHEX(geohex) // end::to_geohex_to_long[] ; // tag::to_geohex_to_long-result[] -string:keyword | geohex:geohex | geohexLong:long -841f059ffffffff | 841f059ffffffff | 595020895127339007 +string:keyword | geohex:geohex | geohexLong:long | geohex2:geohex +841f059ffffffff | 841f059ffffffff | 595020895127339007 | 841f059ffffffff // end::to_geohex_to_long-result[] ; From 46eca050d4727b54e07feb16bca05734db9bf88d Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 14:14:26 +0200 Subject: [PATCH 43/47] Added CASE example to csv-tests --- .../src/main/resources/spatial-grid.csv-spec | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 5fe20a57d5945..56d4b4ba299ae 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -173,6 +173,47 @@ count:long | centroid:geo_point | geohashString:keyw // end::st_geohash-grid-result[] ; +gridGeohashCase +required_capability: spatial_grid_types + +// tag::st_geohash-case[] +FROM airports +| EVAL geohash = ST_GEOHASH(location, 2) +| STATS + count = COUNT(geohash), + centroid = ST_CENTROID_AGG(location) + BY geohash +| WHERE count >= 10 +| EVAL parent = ST_GEOHASH(centroid, 1) +| EVAL level = CASE( + parent == "u"::geohash, "high", + parent == "d"::geohash, "medium", + parent == "9"::geohash, "low", + "other" + ) +| EVAL geohashString = TO_STRING(geohash) +| KEEP count, centroid, geohashString, parent, level +| SORT count DESC, geohashString ASC +// end::st_geohash-case[] +; + +// tag::st_geohash-case-result[] +count:long | centroid:geo_point | geohashString:keyword | parent:geohash | level:keyword +19 | POINT (6.360728044651057 47.94084087577894) | u0 | u | high +17 | POINT (-3.5034258844440473 53.25306422789307) | gc | g | other +16 | POINT (-84.3847085541347 41.85195600060979) | dp | d | medium +13 | POINT (-74.08679279498756 42.10354745746232) | dr | d | medium +12 | POINT (-83.732457049191 36.367889943066984) | dn | d | medium +12 | POINT (74.7963257250376 31.238017017021775) | tt | t | other +12 | POINT (84.32237566681579 24.78583392337896) | tu | t | other +11 | POINT (-94.80821384032342 31.166376347060908) | 9v | 9 | low +10 | POINT (-49.814146178774536 -24.70176063431427) | 6g | 6 | other +10 | POINT (-97.22507307864726 19.70557357929647) | 9g | 9 | low +10 | POINT (15.350638423115015 47.80751353036612) | u2 | u | high +10 | POINT (128.12597772292793 36.5161985848099) | wy | w | other +// end::st_geohash-case-result[] +; + gridGeohashQuery required_capability: spatial_grid_types @@ -503,6 +544,42 @@ count:long | centroid:geo_point | geotileString:key // end::st_geotile-grid-result[] ; +gridGeotileCase +required_capability: spatial_grid_types + +// tag::st_geotile-case[] +FROM airports +| EVAL geotile = ST_GEOTILE(location, 2) +| STATS + count = COUNT(geotile), + centroid = ST_CENTROID_AGG(location) + BY geotile +| WHERE count >= 10 +| EVAL parent = ST_GEOTILE(centroid, 1) +| EVAL level = CASE( + parent == "1/0/0"::geotile, "high", + parent == "1/1/0"::geotile, "medium", + parent == "1/1/1"::geotile, "low", + "other" + ) +| EVAL geotileString = TO_STRING(geotile) +| KEEP count, centroid, geotileString, parent, level +| SORT count DESC, geotileString ASC +// end::st_geotile-case[] +; + +// tag::st_geotile-case-result[] +count:long | centroid:geo_point | geotileString:keyword | parent:geotile | level:keyword +286 | POINT (39.31202001609169 35.149993664386415) | 2/2/1 | 1/1/0 | medium +197 | POINT (-55.387361375756825 31.952955322292855) | 2/1/1 | 1/0/0 | high +136 | POINT (-110.97162496141048 36.87185255084734) | 2/0/1 | 1/0/0 | high +106 | POINT (119.35907618669827 25.46263281488791) | 2/3/1 | 1/1/0 | medium +67 | POINT (-58.031108492373754 -22.624166105151065) | 2/1/2 | 1/0/1 | other +46 | POINT (142.95455511274707 -20.581492295427978) | 2/3/2 | 1/1/1 | low +34 | POINT (31.38476753634784 -14.64374022804858) | 2/2/2 | 1/1/1 | low +// end::st_geotile-case-result[] +; + gridGeotileQuery required_capability: spatial_grid_types @@ -805,6 +882,40 @@ count:long | centroid:geo_point | geohexString:keywo // end::st_geohex-grid-result[] ; +gridGeohexCase +required_capability: spatial_grid_types + +// tag::st_geohex-case[] +FROM airports +| EVAL geohex = ST_GEOHEX(location, 2) +| STATS + count = COUNT(geohex), + centroid = ST_CENTROID_AGG(location) + BY geohex +| WHERE count >= 5 +| EVAL parent = ST_GEOHEX(centroid, 1) +| EVAL level = CASE( + parent == "811fbffffffffff"::geohex, "high", + parent == "81197ffffffffff"::geohex, "medium", + parent == "8129bffffffffff"::geohex, "low", + "other" + ) +| EVAL geohexString = TO_STRING(geohex) +| KEEP count, centroid, geohexString, parent, level +| SORT count DESC, geohexString ASC +// end::st_geohex-case[] +; + +// tag::st_geohex-case-result[] +count:long | centroid:geo_point | geohexString:keyword | parent:geohex | level:keyword +6 | POINT (5.582276992499828 50.72238312335685) | 821fa7fffffffff | 811fbffffffffff | high +5 | POINT (-1.7227098606526852 51.717823022045195) | 82195ffffffffff | 81197ffffffffff | medium +5 | POINT (8.6918301936239 45.19817395694554) | 821f9ffffffffff | 811fbffffffffff | high +5 | POINT (-117.60585453920066 33.392433090135455) | 8229a7fffffffff | 8129bffffffffff | low +5 | POINT (-82.21536266617477 42.29504897072911) | 822ab7fffffffff | 812abffffffffff | other +// end::st_geohex-case-result[] +; + gridGeohexQuery required_capability: spatial_grid_types From 07b730df816f82ae9e396f5b788ea9402b166bf8 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 14:40:04 +0200 Subject: [PATCH 44/47] Added MV functions to csv-tests --- .../src/main/resources/spatial-grid.csv-spec | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 56d4b4ba299ae..42e886d6d7b38 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -121,6 +121,26 @@ location:geo_point | geohash4:long | geohash3:long | geoh POINT (12.6493508684508 55.6285017221528) | 13686180 | 427683 | 13362 | 417 ; +geohashLiteralMv +required_capability: spatial_grid_types + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geohash4 = ST_GEOHASH(location, 4), + geohash3 = ST_GEOHASH(location, 3), + geohash2 = ST_GEOHASH(location, 2), + geohash1 = ST_GEOHASH(location, 1) +| EVAL chain = MV_APPEND(geohash4, MV_APPEND(geohash3, MV_APPEND(geohash2, geohash1))) +| EVAL description = MV_CONCAT(chain::keyword, " --> ") +| EVAL top = MV_LAST(chain) +| EVAL bottom = MV_FIRST(chain) +//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| KEEP location, top, bottom, chain, description +; + +location:geo_point | top:geohash | bottom:geohash | chain:geohash | description:keyword +POINT(12.6493508684508 55.6285017221528) | u | u3bu | [u3bu, u3b, u3, u] | u3bu --> u3b --> u3 --> u +; + geohashField required_capability: spatial_grid_types @@ -499,6 +519,26 @@ location:geo_point | geotile4:long | geotile3:long POINT (12.6493508684508 55.6285017221528) | 1152921508901814277 | 864691130602618882 | 576460753377165313 | 288230376688582656 ; +geotileLiteralMv +required_capability: spatial_grid_types + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geotile4 = ST_GEOTILE(location, 4), + geotile3 = ST_GEOTILE(location, 3), + geotile2 = ST_GEOTILE(location, 2), + geotile1 = ST_GEOTILE(location, 1) +| EVAL chain = MV_APPEND(geotile4, MV_APPEND(geotile3, MV_APPEND(geotile2, geotile1))) +| EVAL description = MV_CONCAT(chain::keyword, " --> ") +| EVAL top = MV_LAST(chain) +| EVAL bottom = MV_FIRST(chain) +//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| KEEP location, top, bottom, chain, description +; + +location:geo_point | top:geotile | bottom:geotile | chain:geotile | description:keyword +POINT (12.6493508684508 55.6285017221528) | 1/1/0 | 4/8/5 | [4/8/5, 3/4/2, 2/2/1, 1/1/0] | 4/8/5 --> 3/4/2 --> 2/2/1 --> 1/1/0 +; + geotileField required_capability: spatial_grid_types @@ -836,6 +876,26 @@ location:geo_point | geohex4:long | geohex3:long POINT (12.6493508684508 55.6285017221528) | 595020895127339007 | 590517321269772287 | 586013859081355263 | 581514107744681983 ; +geohexLiteralMv +required_capability: spatial_grid_types + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") +| EVAL geohex4 = ST_GEOHEX(location, 4), + geohex3 = ST_GEOHEX(location, 3), + geohex2 = ST_GEOHEX(location, 2), + geohex1 = ST_GEOHEX(location, 1) +| EVAL chain = MV_APPEND(geohex4, MV_APPEND(geohex3, MV_APPEND(geohex2, geohex1))) +| EVAL description = MV_CONCAT(chain::keyword, " --> ") +| EVAL top = MV_LAST(chain) +| EVAL bottom = MV_FIRST(chain) +//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| KEEP location, top, bottom, chain, description +; + +location:geo_point | top:geohex | bottom:geohex | chain:geohex | description:keyword +POINT (12.6493508684508 55.6285017221528) | 811f3ffffffffff | 841f059ffffffff | [841f059ffffffff, 831f05fffffffff, 821f07fffffffff, 811f3ffffffffff] | 841f059ffffffff --> 831f05fffffffff --> 821f07fffffffff --> 811f3ffffffffff +; + geohexField required_capability: spatial_grid_types From e44c824a71c7596cdd0063bffe3e857ecfc423d9 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 15:29:15 +0200 Subject: [PATCH 45/47] Support MV_CONTAINS --- .../_snippets/functions/types/mv_contains.md | 3 + .../definition/functions/mv_contains.json | 54 ++++++++++++++++ .../src/main/resources/spatial-grid.csv-spec | 9 ++- .../scalar/multivalue/MvContains.java | 6 ++ .../scalar/multivalue/MvContainsTests.java | 63 +++++-------------- 5 files changed, 85 insertions(+), 50 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md b/docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md index fe4b46ac5b280..a965866eaae38 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md +++ b/docs/reference/query-languages/esql/_snippets/functions/types/mv_contains.md @@ -12,6 +12,9 @@ | double | double | boolean | | geo_point | geo_point | boolean | | geo_shape | geo_shape | boolean | +| geohash | geohash | boolean | +| geohex | geohex | boolean | +| geotile | geotile | boolean | | integer | integer | boolean | | ip | ip | boolean | | keyword | keyword | boolean | diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json b/docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json index 0116939ba4f59..da091144b0be8 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/mv_contains.json @@ -148,6 +148,60 @@ "variadic" : false, "returnType" : "boolean" }, + { + "params" : [ + { + "name" : "superset", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + }, + { + "name" : "subset", + "type" : "geohash", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "superset", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + }, + { + "name" : "subset", + "type" : "geohex", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, + { + "params" : [ + { + "name" : "superset", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + }, + { + "name" : "subset", + "type" : "geotile", + "optional" : false, + "description" : "Multivalue expression." + } + ], + "variadic" : false, + "returnType" : "boolean" + }, { "params" : [ { diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 42e886d6d7b38..6e9e357d9a14f 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -123,6 +123,7 @@ POINT (12.6493508684508 55.6285017221528) | 13686180 | 427683 | 1336 geohashLiteralMv required_capability: spatial_grid_types +required_capability: fn_mv_contains ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohash4 = ST_GEOHASH(location, 4), @@ -133,7 +134,7 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) -//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; @@ -521,6 +522,7 @@ POINT (12.6493508684508 55.6285017221528) | 1152921508901814277 | 86469113060261 geotileLiteralMv required_capability: spatial_grid_types +required_capability: fn_mv_contains ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geotile4 = ST_GEOTILE(location, 4), @@ -531,7 +533,7 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) -//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; @@ -878,6 +880,7 @@ POINT (12.6493508684508 55.6285017221528) | 595020895127339007 | 590517321269772 geohexLiteralMv required_capability: spatial_grid_types +required_capability: fn_mv_contains ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL geohex4 = ST_GEOHEX(location, 4), @@ -888,7 +891,7 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) -//| WHERE MV_CONTAINS(chain, first) AND MV_CONTAINS(chain, last) +| WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java index dfdec763e330a..052dac0d68b1c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java @@ -93,6 +93,9 @@ public MvContains( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", @@ -113,6 +116,9 @@ public MvContains( "double", "geo_point", "geo_shape", + "geohash", + "geotile", + "geohex", "integer", "ip", "keyword", diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java index 57da6d5c2fe9a..7b833ba86e00d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsTests.java @@ -35,6 +35,7 @@ import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.TypedData.MULTI_ROW_NULL; import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.TypedData.NULL; +import static org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvSliceTests.randomGrid; import static org.hamcrest.Matchers.equalTo; public class MvContainsTests extends AbstractScalarFunctionTestCase { @@ -100,56 +101,24 @@ private static void ints(List suppliers) { } private static void longs(List suppliers) { - suppliers.add(new TestCaseSupplier(List.of(DataType.LONG, DataType.LONG), () -> { - List field1 = randomList(1, 10, ESTestCase::randomLong); - List field2 = randomList(1, 10, ESTestCase::randomLong); - var result = field1.containsAll(field2); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field1, DataType.LONG, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.LONG, "field2") - ), - "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.BOOLEAN, - equalTo(result) - ); - })); - suppliers.add(new TestCaseSupplier(List.of(DataType.UNSIGNED_LONG, DataType.UNSIGNED_LONG), () -> { - List field1 = randomList(1, 10, ESTestCase::randomLong); - List field2 = randomList(1, 10, ESTestCase::randomLong); - var result = field1.containsAll(field2); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field1, DataType.UNSIGNED_LONG, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.UNSIGNED_LONG, "field2") - ), - "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.BOOLEAN, - equalTo(result) - ); - })); - suppliers.add(new TestCaseSupplier(List.of(DataType.DATETIME, DataType.DATETIME), () -> { - List field1 = randomList(1, 10, ESTestCase::randomLong); - List field2 = randomList(1, 10, ESTestCase::randomLong); - var result = field1.containsAll(field2); - return new TestCaseSupplier.TestCase( - List.of( - new TestCaseSupplier.TypedData(field1, DataType.DATETIME, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.DATETIME, "field2") - ), - "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", - DataType.BOOLEAN, - equalTo(result) - ); - })); - suppliers.add(new TestCaseSupplier(List.of(DataType.DATE_NANOS, DataType.DATE_NANOS), () -> { - List field1 = randomList(1, 10, ESTestCase::randomNonNegativeLong); - List field2 = randomList(1, 10, ESTestCase::randomNonNegativeLong); + addLongTestCase(suppliers, DataType.LONG, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.UNSIGNED_LONG, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATETIME, ESTestCase::randomLong); + addLongTestCase(suppliers, DataType.DATE_NANOS, ESTestCase::randomNonNegativeLong); + for (DataType gridType : new DataType[] { DataType.GEOHASH, DataType.GEOTILE, DataType.GEOHEX }) { + addLongTestCase(suppliers, gridType, () -> randomGrid(gridType)); + } + } + + private static void addLongTestCase(List suppliers, DataType dataType, Supplier longSupplier) { + suppliers.add(new TestCaseSupplier(List.of(dataType, dataType), () -> { + List field1 = randomList(1, 10, longSupplier); + List field2 = randomList(1, 10, longSupplier); var result = field1.containsAll(field2); return new TestCaseSupplier.TestCase( List.of( - new TestCaseSupplier.TypedData(field1, DataType.DATE_NANOS, "field1"), - new TestCaseSupplier.TypedData(field2, DataType.DATE_NANOS, "field2") + new TestCaseSupplier.TypedData(field1, dataType, "field1"), + new TestCaseSupplier.TypedData(field2, dataType, "field2") ), "MvContainsLongEvaluator[field1=Attribute[channel=0], field2=Attribute[channel=1]]", DataType.BOOLEAN, From 995724d2d92ab1564ec549076c6baa0504440538 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 15:36:35 +0200 Subject: [PATCH 46/47] Add csv-spec tests for COALESCE --- .../testFixtures/src/main/resources/spatial-grid.csv-spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec index 6e9e357d9a14f..f0dc76e4c8e87 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -134,6 +134,8 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) +| EVAL top = COALESCE(top, null, bottom) +| EVAL bottom = COALESCE(bottom, null, top) | WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; @@ -533,6 +535,8 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) +| EVAL top = COALESCE(top, null, bottom) +| EVAL bottom = COALESCE(bottom, null, top) | WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; @@ -891,6 +895,8 @@ ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)") | EVAL description = MV_CONCAT(chain::keyword, " --> ") | EVAL top = MV_LAST(chain) | EVAL bottom = MV_FIRST(chain) +| EVAL top = COALESCE(top, null, bottom) +| EVAL bottom = COALESCE(bottom, null, top) | WHERE MV_CONTAINS(chain, top) AND MV_CONTAINS(chain, bottom) | KEEP location, top, bottom, chain, description ; From dfabb96fe67a478ec2f696488a01cdb4678707f5 Mon Sep 17 00:00:00 2001 From: Craig Taverner Date: Sat, 30 Aug 2025 15:58:26 +0200 Subject: [PATCH 47/47] Updated docs after test updates --- .../esql/_snippets/functions/examples/st_geohash.md | 2 +- .../esql/_snippets/functions/examples/st_geohex.md | 2 +- .../esql/_snippets/functions/examples/st_geotile.md | 2 +- .../esql/kibana/definition/functions/st_geohash.json | 2 +- .../esql/kibana/definition/functions/st_geohex.json | 2 +- .../esql/kibana/definition/functions/st_geotile.json | 2 +- .../query-languages/esql/kibana/docs/functions/st_geohash.md | 2 +- .../query-languages/esql/kibana/docs/functions/st_geohex.md | 2 +- .../query-languages/esql/kibana/docs/functions/st_geotile.md | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md index 5790a09cbd606..144bf0ec09cef 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md @@ -6,7 +6,7 @@ FROM airports | EVAL geohash = ST_GEOHASH(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md index c670565771c24..3f194d065cb1a 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md @@ -6,7 +6,7 @@ FROM airports | EVAL geohex = ST_GEOHEX(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md index d01c092db4c9a..eb7aa2de95c96 100644 --- a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md @@ -6,7 +6,7 @@ FROM airports | EVAL geotile = ST_GEOTILE(location, 2) | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile) diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json index 725d1613aa8d2..fced160121589 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json @@ -48,7 +48,7 @@ } ], "examples" : [ - "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" + "FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(geohash),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC" ], "preview" : true, "snapshot_only" : true diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json index fa5d2c7662891..019fe27405f51 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json @@ -51,7 +51,7 @@ } ], "examples" : [ - "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" + "FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(geohex),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC" ], "preview" : true, "snapshot_only" : true diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json index 53cda0965e257..bd5fb4ede8cc4 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json @@ -48,7 +48,7 @@ } ], "examples" : [ - "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" + "FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(geotile),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString" ], "preview" : true, "snapshot_only" : true diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md index ecf2d4c310c34..17d0c71f274b2 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md @@ -13,7 +13,7 @@ and the [`geohash_grid` aggregation](https://www.elastic.co/docs/reference/aggre FROM airports | EVAL geohash = ST_GEOHASH(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohash), centroid = ST_CENTROID_AGG(location) BY geohash | WHERE count >= 10 diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md index 688540607e863..02143698b7b6c 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md @@ -13,7 +13,7 @@ and the [`geohex_grid` aggregation](https://www.elastic.co/docs/reference/aggreg FROM airports | EVAL geohex = ST_GEOHEX(location, 1) | STATS - count = COUNT(*), + count = COUNT(geohex), centroid = ST_CENTROID_AGG(location) BY geohex | WHERE count >= 10 diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md index d6f15430644c6..236a68e66d374 100644 --- a/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md @@ -13,7 +13,7 @@ and the [`geotile_grid` aggregation](https://www.elastic.co/docs/reference/aggre FROM airports | EVAL geotile = ST_GEOTILE(location, 2) | STATS - count = COUNT(*), + count = COUNT(geotile), centroid = ST_CENTROID_AGG(location) BY geotile | EVAL geotileString = TO_STRING(geotile)