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 new file mode 100644 index 0000000000000..2527a90db74e7 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**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. Or use [ST_GEOHASH_TO_GEOSHAPE](#esql-st_geohash_to_geoshape) to convert either the long or string `geohash` to a These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation). + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..98f834a5e8587 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_geoshape.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geo_shape` value. The input values are expected to be the grid-ids of geohash grids, in either long or string format. + 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 new file mode 100644 index 0000000000000..2abb0c416addb --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_long.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..5e1cc240c4731 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohash_to_string.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..2b31926bef047 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**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. Or use [ST_GEOHEX_TO_GEOSHAPE](#esql-st_geohex_to_geoshape) to convert either the long or string `geohex` to a POLYGON geo_shape. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation). + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..10547ae8c4bbc --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_geoshape.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geo_shape` value. The input values are expected to be the grid-ids of H3 grids, in either long or string format. + 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 new file mode 100644 index 0000000000000..b391ae1d685eb --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_long.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..7915ff0170e05 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geohex_to_string.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..c473312687c7a --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**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. Or use [ST_GEOTILE_TO_GEOSHAPE](#esql-st_geotile_to_geoshape) to convert either the long or string `geotile` to a POLYGON geo_shape. These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation). + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..f8cbfa8878d15 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_geoshape.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Description** + +Converts an input value to a `geo_shape` value. The input values are expected to be the grid-ids of geotile grids, in either long or string format. + 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 new file mode 100644 index 0000000000000..7ebe7a08d2a4d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_long.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..71fd355372975 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/st_geotile_to_string.md @@ -0,0 +1,6 @@ +% 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 new file mode 100644 index 0000000000000..f9fab4135d31f --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash.md @@ -0,0 +1,38 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +FROM airports +| EVAL geohash = ST_GEOHASH(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohash +| WHERE count >= 10 +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| KEEP count, centroid, geohashString +| SORT count DESC, geohashString ASC +``` + +| count:long | centroid:geo_point | geohashString:keyword | +| --- | --- | --- | +| 118 | POINT (-77.41857436454018 26.96522968734409) | d | +| 96 | POINT (23.181679135886952 27.295384635654045) | s | +| 94 | POINT (70.94076107503807 25.691916451026547) | t | +| 90 | POINT (-104.3941700803116 30.811849871650338) | 9 | +| 89 | POINT (18.71573683606942 53.165169130707305) | u | +| 85 | POINT (114.3722876966657 24.908398092505248) | w | +| 51 | POINT (-61.44522591713159 -22.87209844956284) | 6 | +| 38 | POINT (-9.429514887252529 25.497624435045413) | e | +| 34 | POINT (-111.8071846965262 52.464381378993174) | c | +| 30 | POINT (28.7045472683385 -14.706001980230212) | k | +| 28 | POINT (159.52750137208827 -25.555616633001982) | r | +| 22 | POINT (-4.410395708612421 54.90304926367985) | g | +| 21 | POINT (-69.40534970590046 50.93379438189523) | f | +| 17 | POINT (114.05526293222519 -10.898114638950895) | q | +| 16 | POINT (147.40052131412085 21.054660080408212) | x | +| 13 | POINT (63.64716878519035 54.37333276101317) | v | +| 12 | POINT (-39.53510569408536 -11.72166372067295) | 7 | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..4990583a2f8c6 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_geoshape.md @@ -0,0 +1,14 @@ +% 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 boundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +``` + +| geohash: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)) | + + 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 new file mode 100644 index 0000000000000..a5dd10b329f6f --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_long.md @@ -0,0 +1,14 @@ +% 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 new file mode 100644 index 0000000000000..dd6327499254f --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohash_to_string.md @@ -0,0 +1,14 @@ +% 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 new file mode 100644 index 0000000000000..875add22968d6 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex.md @@ -0,0 +1,32 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +FROM airports +| EVAL geohex = ST_GEOHEX(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohex +| WHERE count >= 10 +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| KEEP count, centroid, geohexString +| SORT count DESC, geohexString ASC +``` + +| count:long | centroid:geo_point | geohexString:keyword | +| --- | --- | --- | +| 22 | POINT (7.250850197689777 48.21363834643059) | 811fbffffffffff | +| 18 | POINT (-80.64959161449224 40.04119813675061) | 812abffffffffff | +| 17 | POINT (-0.7606179875266903 52.86413913565304) | 81197ffffffffff | +| 13 | POINT (22.53157936179867 41.98255742864254) | 811efffffffffff | +| 13 | POINT (78.30096947387435 26.073904778951636) | 813dbffffffffff | +| 12 | POINT (-76.39781514415517 45.16300531569868) | 812bbffffffffff | +| 12 | POINT (-100.30120467301458 20.114154297625646) | 8149bffffffffff | +| 11 | POINT (18.037187419831753 48.66540593306788) | 811e3ffffffffff | +| 11 | POINT (-83.42379064553164 33.18388901439241) | 8144fffffffffff | +| 11 | POINT (-99.4237939513881 27.100012352774765) | 8148bffffffffff | +| 10 | POINT (128.01009018346667 35.8699960866943) | 8130fffffffffff | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..544e9d4dfa39d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_geoshape.md @@ -0,0 +1,14 @@ +% 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 boundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +``` + +| geohex: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)) | + + 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 new file mode 100644 index 0000000000000..be94b611917aa --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_long.md @@ -0,0 +1,14 @@ +% 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 new file mode 100644 index 0000000000000..b3eabacd5ec14 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geohex_to_string.md @@ -0,0 +1,14 @@ +% 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 new file mode 100644 index 0000000000000..0653f55c969c7 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile.md @@ -0,0 +1,31 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +FROM airports +| EVAL geotile = ST_GEOTILE(location, 2) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| SORT count DESC, geotileString ASC +| KEEP count, centroid, geotileString +``` + +| count:long | centroid:geo_point | geotileString:keyword | +| --- | --- | --- | +| 286 | POINT (39.31202001609169 35.149993664386415) | 2/2/1 | +| 197 | POINT (-55.387361375756825 31.952955322292855) | 2/1/1 | +| 136 | POINT (-110.97162496141048 36.87185255084734) | 2/0/1 | +| 106 | POINT (119.35907618669827 25.46263281488791) | 2/3/1 | +| 67 | POINT (-58.031108492373754 -22.624166105151065) | 2/1/2 | +| 46 | POINT (142.95455511274707 -20.581492295427978) | 2/3/2 | +| 34 | POINT (31.38476753634784 -14.64374022804858) | 2/2/2 | +| 8 | POINT (-160.0723083713092 -19.124013530672528) | 2/0/2 | +| 6 | POINT (23.95813101902604 70.17537698848173) | 2/2/0 | +| 3 | POINT (-133.4001641627401 72.06833167467266) | 2/0/0 | +| 2 | POINT (-68.47209956031293 66.77569948369637) | 2/1/0 | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..9f0331fe632b8 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_geoshape.md @@ -0,0 +1,14 @@ +% 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 boundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +``` + +| geotile: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)) | + + 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 new file mode 100644 index 0000000000000..995f04ee6f355 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_long.md @@ -0,0 +1,14 @@ +% 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 new file mode 100644 index 0000000000000..6e7a95b6ff342 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/st_geotile_to_string.md @@ -0,0 +1,14 @@ +% 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.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash.md new file mode 100644 index 0000000000000..f84175b382f21 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +## `ST_GEOHASH` [esql-st_geohash] + +**Syntax** + +:::{image} ../../../images/functions/st_geohash.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geohash.md +::: + +:::{include} ../description/st_geohash.md +::: + +:::{include} ../types/st_geohash.md +::: + +:::{include} ../examples/st_geohash.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..616208fab61ab --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_geoshape.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### `ST_GEOHASH_TO_GEOSHAPE` [esql-st_geohash_to_geoshape] + +**Syntax** + +:::{image} ../../../images/functions/st_geohash_to_geoshape.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geohash_to_geoshape.md +::: + +:::{include} ../description/st_geohash_to_geoshape.md +::: + +:::{include} ../types/st_geohash_to_geoshape.md +::: + +:::{include} ../examples/st_geohash_to_geoshape.md +::: 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 new file mode 100644 index 0000000000000..e9f37660cedf9 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_long.md @@ -0,0 +1,23 @@ +% 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 new file mode 100644 index 0000000000000..cfed286eeee68 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohash_to_string.md @@ -0,0 +1,23 @@ +% 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.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex.md new file mode 100644 index 0000000000000..95c7c49ed50bc --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +## `ST_GEOHEX` [esql-st_geohex] + +**Syntax** + +:::{image} ../../../images/functions/st_geohex.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geohex.md +::: + +:::{include} ../description/st_geohex.md +::: + +:::{include} ../types/st_geohex.md +::: + +:::{include} ../examples/st_geohex.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..debfd69bc1af2 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_geoshape.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### `ST_GEOHEX_TO_GEOSHAPE` [esql-st_geohex_to_geoshape] + +**Syntax** + +:::{image} ../../../images/functions/st_geohex_to_geoshape.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geohex_to_geoshape.md +::: + +:::{include} ../description/st_geohex_to_geoshape.md +::: + +:::{include} ../types/st_geohex_to_geoshape.md +::: + +:::{include} ../examples/st_geohex_to_geoshape.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 new file mode 100644 index 0000000000000..6fe48a030d188 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_long.md @@ -0,0 +1,23 @@ +% 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 new file mode 100644 index 0000000000000..be1b882a50676 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geohex_to_string.md @@ -0,0 +1,23 @@ +% 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.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile.md new file mode 100644 index 0000000000000..b6a8d1b70ffe8 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +## `ST_GEOTILE` [esql-st_geotile] + +**Syntax** + +:::{image} ../../../images/functions/st_geotile.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geotile.md +::: + +:::{include} ../description/st_geotile.md +::: + +:::{include} ../types/st_geotile.md +::: + +:::{include} ../examples/st_geotile.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..526c536c6c8b3 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_geoshape.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### `ST_GEOTILE_TO_GEOSHAPE` [esql-st_geotile_to_geoshape] + +**Syntax** + +:::{image} ../../../images/functions/st_geotile_to_geoshape.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/st_geotile_to_geoshape.md +::: + +:::{include} ../description/st_geotile_to_geoshape.md +::: + +:::{include} ../types/st_geotile_to_geoshape.md +::: + +:::{include} ../examples/st_geotile_to_geoshape.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 new file mode 100644 index 0000000000000..eb5828218376d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_long.md @@ -0,0 +1,23 @@ +% 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 new file mode 100644 index 0000000000000..b1481b33788a4 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/st_geotile_to_string.md @@ -0,0 +1,23 @@ +% 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_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash.md new file mode 100644 index 0000000000000..6980bf5442a1d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash.md @@ -0,0 +1,13 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`geometry` +: Expression of type `geo_point`. If `null`, the function returns `null`. + +`precision` +: Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [1 and 12](https://en.wikipedia.org/wiki/Geohash). + +`bounds` +: Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. The envelope of the `geo_shape` is used as bounds. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..5db5ddfdfcd2c --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_geoshape.md @@ -0,0 +1,7 @@ +% 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_long.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md new file mode 100644 index 0000000000000..5db5ddfdfcd2c --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_long.md @@ -0,0 +1,7 @@ +% 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 new file mode 100644 index 0000000000000..5db5ddfdfcd2c --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohash_to_string.md @@ -0,0 +1,7 @@ +% 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.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex.md new file mode 100644 index 0000000000000..a9fecf05bb84a --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex.md @@ -0,0 +1,13 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`geometry` +: Expression of type `geo_point`. If `null`, the function returns `null`. + +`precision` +: Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [0 and 15](https://h3geo.org/docs/core-library/restable/). + +`bounds` +: Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. The envelope of the `geo_shape` is used as bounds. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..c929ae395f5fc --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_geoshape.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`grid_id` +: Input H3 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 new file mode 100644 index 0000000000000..e86ac82e67003 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_long.md @@ -0,0 +1,7 @@ +% 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 new file mode 100644 index 0000000000000..cb78878f500bf --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geohex_to_string.md @@ -0,0 +1,7 @@ +% 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.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile.md new file mode 100644 index 0000000000000..7f5e4e6f7c80c --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile.md @@ -0,0 +1,13 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`geometry` +: Expression of type `geo_point`. If `null`, the function returns `null`. + +`precision` +: Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [0 and 29](https://wiki.openstreetmap.org/wiki/Zoom_levels). + +`bounds` +: Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. The envelope of the `geo_shape` is used as bounds. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..4a16a5a87faad --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_geoshape.md @@ -0,0 +1,7 @@ +% 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_long.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md new file mode 100644 index 0000000000000..4a16a5a87faad --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_long.md @@ -0,0 +1,7 @@ +% 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 new file mode 100644 index 0000000000000..4a16a5a87faad --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/st_geotile_to_string.md @@ -0,0 +1,7 @@ +% 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/types/st_geohash.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md new file mode 100644 index 0000000000000..c7f908dd18458 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash.md @@ -0,0 +1,8 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| geometry | precision | bounds | result | +| --- | --- | --- | --- | +| geo_point | integer | | long | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..5dec4762ba6ef --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_geoshape.md @@ -0,0 +1,9 @@ +% 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 | geo_shape | +| long | geo_shape | + 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 new file mode 100644 index 0000000000000..fb31bb5d9f657 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..5d10b76e7bd09 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohash_to_string.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..c7f908dd18458 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex.md @@ -0,0 +1,8 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| geometry | precision | bounds | result | +| --- | --- | --- | --- | +| geo_point | integer | | long | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..5dec4762ba6ef --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_geoshape.md @@ -0,0 +1,9 @@ +% 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 | geo_shape | +| long | geo_shape | + 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 new file mode 100644 index 0000000000000..fb31bb5d9f657 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..5d10b76e7bd09 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geohex_to_string.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..c7f908dd18458 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile.md @@ -0,0 +1,8 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| geometry | precision | bounds | result | +| --- | --- | --- | --- | +| geo_point | integer | | long | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_geoshape.md b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..5dec4762ba6ef --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_geoshape.md @@ -0,0 +1,9 @@ +% 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 | geo_shape | +| long | geo_shape | + 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 new file mode 100644 index 0000000000000..fb31bb5d9f657 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..5d10b76e7bd09 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/st_geotile_to_string.md @@ -0,0 +1,9 @@ +% 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/lists/spatial-functions.md b/docs/reference/query-languages/esql/_snippets/lists/spatial-functions.md index 83cfdd4c60867..3621e44ac4f53 100644 --- a/docs/reference/query-languages/esql/_snippets/lists/spatial-functions.md +++ b/docs/reference/query-languages/esql/_snippets/lists/spatial-functions.md @@ -10,3 +10,15 @@ * [preview] [`ST_XMIN`](../../functions-operators/spatial-functions.md#esql-st_xmin) * [preview] [`ST_YMAX`](../../functions-operators/spatial-functions.md#esql-st_ymax) * [preview] [`ST_YMIN`](../../functions-operators/spatial-functions.md#esql-st_ymin) +* [preview] [`ST_GEOTILE`](../../functions-operators/spatial-functions.md#esql-st_geotile) + * [preview] [`ST_GEOTILE_TO_STRING`](../../functions-operators/spatial-functions.md#esql-st_geotile_to_string) + * [preview] [`ST_GEOTILE_TO_LONG`](../../functions-operators/spatial-functions.md#esql-st_geotile_to_long) + * [preview] [`ST_GEOTILE_TO_GEOSHAPE`](../../functions-operators/spatial-functions.md#esql-st_geotile_to_geoshape) +* [preview] [`ST_GEOHEX`](../../functions-operators/spatial-functions.md#esql-st_geohex) + * [preview] [`ST_GEOHEX_TO_STRING`](../../functions-operators/spatial-functions.md#esql-st_geohex_to_string) + * [preview] [`ST_GEOHEX_TO_LONG`](../../functions-operators/spatial-functions.md#esql-st_geohex_to_long) + * [preview] [`ST_GEOHEX_TO_GEOSHAPE`](../../functions-operators/spatial-functions.md#esql-st_geohex_to_geoshape) +* [preview] [`ST_GEOHASH`](../../functions-operators/spatial-functions.md#esql-st_geohash) + * [preview] [`ST_GEOHASH_TO_STRING`](../../functions-operators/spatial-functions.md#esql-st_geohash_to_string) + * [preview] [`ST_GEOHASH_TO_LONG`](../../functions-operators/spatial-functions.md#esql-st_geohash_to_long) + * [preview] [`ST_GEOHASH_TO_GEOSHAPE`](../../functions-operators/spatial-functions.md#esql-st_geohash_to_geoshape) diff --git a/docs/reference/query-languages/esql/functions-operators/spatial-functions.md b/docs/reference/query-languages/esql/functions-operators/spatial-functions.md index 806e5e8157a63..c4441e12a14ae 100644 --- a/docs/reference/query-languages/esql/functions-operators/spatial-functions.md +++ b/docs/reference/query-languages/esql/functions-operators/spatial-functions.md @@ -48,3 +48,38 @@ mapped_pages: :::{include} ../_snippets/functions/layout/st_ymin.md ::: +:::{include} ../_snippets/functions/layout/st_geotile.md +::: + +:::{include} ../_snippets/functions/layout/st_geotile_to_string.md +::: + +:::{include} ../_snippets/functions/layout/st_geotile_to_long.md +::: + +:::{include} ../_snippets/functions/layout/st_geotile_to_geoshape.md +::: + +:::{include} ../_snippets/functions/layout/st_geohex.md +::: + +:::{include} ../_snippets/functions/layout/st_geohex_to_string.md +::: + +:::{include} ../_snippets/functions/layout/st_geohex_to_long.md +::: + +:::{include} ../_snippets/functions/layout/st_geohex_to_geoshape.md +::: + +:::{include} ../_snippets/functions/layout/st_geohash.md +::: + +:::{include} ../_snippets/functions/layout/st_geohash_to_string.md +::: + +:::{include} ../_snippets/functions/layout/st_geohash_to_long.md +::: + +:::{include} ../_snippets/functions/layout/st_geohash_to_geoshape.md +::: diff --git a/docs/reference/query-languages/esql/images/functions/st_geohash.svg b/docs/reference/query-languages/esql/images/functions/st_geohash.svg new file mode 100644 index 0000000000000..231866d25d521 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohash.svg @@ -0,0 +1 @@ +ST_GEOHASH(geometry,precision,bounds) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohash_to_geoshape.svg b/docs/reference/query-languages/esql/images/functions/st_geohash_to_geoshape.svg new file mode 100644 index 0000000000000..bac257c45dd0b --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohash_to_geoshape.svg @@ -0,0 +1 @@ +ST_GEOHASH_TO_GEOSHAPE(grid_id) \ 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 new file mode 100644 index 0000000000000..869af17d522de --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohash_to_long.svg @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000000..dcb7e909d81dd --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohash_to_string.svg @@ -0,0 +1 @@ +ST_GEOHASH_TO_STRING(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohex.svg b/docs/reference/query-languages/esql/images/functions/st_geohex.svg new file mode 100644 index 0000000000000..588cb5374a617 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohex.svg @@ -0,0 +1 @@ +ST_GEOHEX(geometry,precision,bounds) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geohex_to_geoshape.svg b/docs/reference/query-languages/esql/images/functions/st_geohex_to_geoshape.svg new file mode 100644 index 0000000000000..0d814904e233f --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohex_to_geoshape.svg @@ -0,0 +1 @@ +ST_GEOHEX_TO_GEOSHAPE(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 new file mode 100644 index 0000000000000..39181484ebe7a --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohex_to_long.svg @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000000..3d96677e1f87e --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geohex_to_string.svg @@ -0,0 +1 @@ +ST_GEOHEX_TO_STRING(grid_id) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geotile.svg b/docs/reference/query-languages/esql/images/functions/st_geotile.svg new file mode 100644 index 0000000000000..ee97511f568cc --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geotile.svg @@ -0,0 +1 @@ +ST_GEOTILE(geometry,precision,bounds) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/st_geotile_to_geoshape.svg b/docs/reference/query-languages/esql/images/functions/st_geotile_to_geoshape.svg new file mode 100644 index 0000000000000..26d8d6c7a0778 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geotile_to_geoshape.svg @@ -0,0 +1 @@ +ST_GEOTILE_TO_GEOSHAPE(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 new file mode 100644 index 0000000000000..8ac85e2baa2d4 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geotile_to_long.svg @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000000..cbe406dd19211 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/st_geotile_to_string.svg @@ -0,0 +1 @@ +ST_GEOTILE_TO_STRING(grid_id) \ No newline at end of file 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 new file mode 100644 index 0000000000000..7b6c4ae3d92d0 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash.json @@ -0,0 +1,31 @@ +{ + "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.\nOr use ST_GEOHASH_TO_GEOSHAPE to convert either the long or string `geohash` to a\n\nThese functions are related to the `geo_grid` query\nand the `geohash_grid` aggregation.", + "signatures" : [ + { + "params" : [ + { + "name" : "geometry", + "type" : "geo_point", + "optional" : false, + "description" : "Expression of type `geo_point`. If `null`, the function returns `null`." + }, + { + "name" : "precision", + "type" : "integer", + "optional" : false, + "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" + } + ], + "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" + ], + "preview" : false, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_geoshape.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_geoshape.json new file mode 100644 index 0000000000000..9997c0f166d95 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_geoshape.json @@ -0,0 +1,37 @@ +{ + "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_geoshape", + "description" : "Converts an input value to a `geo_shape` value.\nThe input values are expected to be the grid-ids of geohash grids, in either long or string format.", + "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" : "geo_shape" + }, + { + "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" : "geo_shape" + } + ], + "examples" : [ + "ROW geohash = \"u3bu\"\n| EVAL boundary = ST_GEOHASH_TO_GEOSHAPE(geohash)" + ], + "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 new file mode 100644 index 0000000000000..f6b14f780e955 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_long.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000000000..d6b55c483ced5 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohash_to_string.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000000000..0f2faadd1da28 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex.json @@ -0,0 +1,31 @@ +{ + "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", + "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.\nOr use ST_GEOHEX_TO_GEOSHAPE to convert either the long or string `geohex` to a\nPOLYGON geo_shape.\n\nThese functions are related to the `geo_grid` query\nand the `geohex_grid` aggregation.", + "signatures" : [ + { + "params" : [ + { + "name" : "geometry", + "type" : "geo_point", + "optional" : false, + "description" : "Expression of type `geo_point`. If `null`, the function returns `null`." + }, + { + "name" : "precision", + "type" : "integer", + "optional" : false, + "description" : "Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [0 and 15](https://h3geo.org/docs/core-library/restable/)." + } + ], + "variadic" : false, + "returnType" : "long" + } + ], + "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" + ], + "preview" : false, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_geoshape.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_geoshape.json new file mode 100644 index 0000000000000..dde729a91ed2a --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_geoshape.json @@ -0,0 +1,37 @@ +{ + "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_geoshape", + "description" : "Converts an input value to a `geo_shape` value.\nThe input values are expected to be the grid-ids of H3 grids, in either long or string format.", + "signatures" : [ + { + "params" : [ + { + "name" : "grid_id", + "type" : "keyword", + "optional" : false, + "description" : "Input H3 grid-id. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geo_shape" + }, + { + "params" : [ + { + "name" : "grid_id", + "type" : "long", + "optional" : false, + "description" : "Input H3 grid-id. The input can be a single- or multi-valued column or an expression." + } + ], + "variadic" : false, + "returnType" : "geo_shape" + } + ], + "examples" : [ + "ROW geohex = \"841f059ffffffff\"\n| EVAL boundary = ST_GEOHEX_TO_GEOSHAPE(geohex)" + ], + "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 new file mode 100644 index 0000000000000..474c4f63ea8a6 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_long.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000000000..0d83038db609e --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geohex_to_string.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000000000..e3e9dfcade0af --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile.json @@ -0,0 +1,31 @@ +{ + "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.\nOr use ST_GEOTILE_TO_GEOSHAPE to convert either the long or string `geotile` to a\nPOLYGON geo_shape.\n\nThese functions are related to the `geo_grid` query\nand the `geotile_grid` aggregation.", + "signatures" : [ + { + "params" : [ + { + "name" : "geometry", + "type" : "geo_point", + "optional" : false, + "description" : "Expression of type `geo_point`. If `null`, the function returns `null`." + }, + { + "name" : "precision", + "type" : "integer", + "optional" : false, + "description" : "Expression of type `integer`. If `null`, the function returns `null`. Valid values are between [0 and 29](https://wiki.openstreetmap.org/wiki/Zoom_levels)." + } + ], + "variadic" : false, + "returnType" : "long" + } + ], + "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" + ], + "preview" : false, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_geoshape.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_geoshape.json new file mode 100644 index 0000000000000..1801f8d9735a3 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_geoshape.json @@ -0,0 +1,37 @@ +{ + "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_geoshape", + "description" : "Converts an input value to a `geo_shape` value.\nThe input values are expected to be the grid-ids of geotile grids, in either long or string format.", + "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" : "geo_shape" + }, + { + "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" : "geo_shape" + } + ], + "examples" : [ + "ROW geotile = \"4/8/5\"\n| EVAL boundary = ST_GEOTILE_TO_GEOSHAPE(geotile)" + ], + "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 new file mode 100644 index 0000000000000..e2aefafa33fdc --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_long.json @@ -0,0 +1,37 @@ +{ + "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 new file mode 100644 index 0000000000000..effe374bab93c --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_geotile_to_string.json @@ -0,0 +1,37 @@ +{ + "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/docs/functions/st_geohash.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md new file mode 100644 index 0000000000000..08b10e27a6d75 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash.md @@ -0,0 +1,22 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### 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. +Or use [ST_GEOHASH_TO_GEOSHAPE](#esql-st_geohash_to_geoshape) to convert either the long or string `geohash` to a + +These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) +and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation). + +```esql +FROM airports +| EVAL geohash = ST_GEOHASH(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohash +| WHERE count >= 10 +| EVAL geohashString = ST_GEOHASH_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_geoshape.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_geoshape.md new file mode 100644 index 0000000000000..debf86f9d1340 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_geoshape.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### ST GEOHASH TO GEOSHAPE +Converts an input value to a `geo_shape` value. +The input values are expected to be the grid-ids of geohash grids, in either long or string format. + +```esql +ROW geohash = "u3bu" +| EVAL boundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +``` 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 new file mode 100644 index 0000000000000..f949358288160 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..fbd7dbd3d4d0a --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohash_to_string.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..604319938b6b1 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### 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. +Or use [ST_GEOHEX_TO_GEOSHAPE](#esql-st_geohex_to_geoshape) to convert either the long or string `geohex` to a +POLYGON geo_shape. + +These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) +and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation). + +```esql +FROM airports +| EVAL geohex = ST_GEOHEX(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohex +| WHERE count >= 10 +| EVAL geohexString = ST_GEOHEX_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_geoshape.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_geoshape.md new file mode 100644 index 0000000000000..85a2339792739 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_geoshape.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### ST GEOHEX TO GEOSHAPE +Converts an input value to a `geo_shape` value. +The input values are expected to be the grid-ids of H3 grids, in either long or string format. + +```esql +ROW geohex = "841f059ffffffff" +| EVAL boundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +``` 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 new file mode 100644 index 0000000000000..393cde5be1e99 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..ba06c681d5af3 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geohex_to_string.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..aebc43fc14c4d --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile.md @@ -0,0 +1,22 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### 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. +Or use [ST_GEOTILE_TO_GEOSHAPE](#esql-st_geotile_to_geoshape) to convert either the long or string `geotile` to a +POLYGON geo_shape. + +These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) +and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation). + +```esql +FROM airports +| EVAL geotile = ST_GEOTILE(location, 2) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_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_geoshape.md b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_geoshape.md new file mode 100644 index 0000000000000..e03fbdd662c96 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_geoshape.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +### ST GEOTILE TO GEOSHAPE +Converts an input value to a `geo_shape` value. +The input values are expected to be the grid-ids of geotile grids, in either long or string format. + +```esql +ROW geotile = "4/8/5" +| EVAL boundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +``` 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 new file mode 100644 index 0000000000000..75f42b84ae03e --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_long.md @@ -0,0 +1,9 @@ +% 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 new file mode 100644 index 0000000000000..620047aa7ccc2 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/st_geotile_to_string.md @@ -0,0 +1,9 @@ +% 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/build.gradle b/x-pack/plugin/esql/build.gradle index 28c3e4d2b20cb..ad301c7595955 100644 --- a/x-pack/plugin/esql/build.gradle +++ b/x-pack/plugin/esql/build.gradle @@ -40,6 +40,8 @@ dependencies { implementation project('compute:ann') implementation project(':libs:dissect') implementation project(':libs:grok') + api "org.apache.lucene:lucene-spatial3d:${versions.lucene}" + api project(":libs:h3") implementation project('arrow') // Also contains a dummy processor to allow compilation with unused annotations. @@ -69,6 +71,10 @@ dependencies { internalClusterTestImplementation project(":modules:mapper-extras") } +tasks.named("dependencyLicenses").configure { + mapping from: /lucene-.*/, to: 'lucene' +} + def generatedPath = "src/main/generated" def projectDirectory = project.layout.projectDirectory def generatedSourceDir = projectDirectory.dir(generatedPath) diff --git a/x-pack/plugin/esql/licenses/lucene-LICENSE.txt b/x-pack/plugin/esql/licenses/lucene-LICENSE.txt new file mode 100644 index 0000000000000..28b134f5f8e4d --- /dev/null +++ b/x-pack/plugin/esql/licenses/lucene-LICENSE.txt @@ -0,0 +1,475 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was +derived from unicode conversion examples available at +http://www.unicode.org/Public/PROGRAMS/CVTUTF. Here is the copyright +from those sources: + +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + + +Some code in core/src/java/org/apache/lucene/util/ArrayUtil.java was +derived from Python 2.4.2 sources available at +http://www.python.org. Full license is here: + + http://www.python.org/download/releases/2.4.2/license/ + +Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was +derived from Python 3.1.2 sources available at +http://www.python.org. Full license is here: + + http://www.python.org/download/releases/3.1.2/license/ + +Some code in core/src/java/org/apache/lucene/util/automaton was +derived from Brics automaton sources available at +www.brics.dk/automaton/. Here is the copyright from those sources: + +/* + * Copyright (c) 2001-2009 Anders Moeller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +The levenshtein automata tables in core/src/java/org/apache/lucene/util/automaton +were automatically generated with the moman/finenight FSA package. +Here is the copyright for those sources: + +# Copyright (c) 2010, Jean-Philippe Barrette-LaPierre, +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was +derived from ICU (http://www.icu-project.org) +The full license is available here: + http://source.icu-project.org/repos/icu/icu/trunk/license.html + +/* + * Copyright (C) 1999-2010, International Business Machines + * Corporation and others. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * provided that the above copyright notice(s) and this permission notice appear + * in all copies of the Software and that both the above copyright notice(s) and + * this permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE + * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall not + * be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +The following license applies to the Snowball stemmers: + +Copyright (c) 2001, Dr Martin Porter +Copyright (c) 2002, Richard Boulton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The following license applies to the KStemmer: + +Copyright © 2003, +Center for Intelligent Information Retrieval, +University of Massachusetts, Amherst. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The names "Center for Intelligent Information Retrieval" and +"University of Massachusetts" must not be used to endorse or promote products +derived from this software without prior written permission. To obtain +permission, contact info@ciir.cs.umass.edu. + +THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF MASSACHUSETTS AND OTHER CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The following license applies to the Morfologik project: + +Copyright (c) 2006 Dawid Weiss +Copyright (c) 2007-2011 Dawid Weiss, Marcin Miłkowski +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Morfologik nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +The dictionary comes from Morfologik project. Morfologik uses data from +Polish ispell/myspell dictionary hosted at http://www.sjp.pl/slownik/en/ and +is licenced on the terms of (inter alia) LGPL and Creative Commons +ShareAlike. The part-of-speech tags were added in Morfologik project and +are not found in the data from sjp.pl. The tagset is similar to IPI PAN +tagset. + +--- + +The following license applies to the Morfeusz project, +used by org.apache.lucene.analysis.morfologik. + +BSD-licensed dictionary of Polish (SGJP) +http://sgjp.pl/morfeusz/ + +Copyright © 2011 Zygmunt Saloni, Włodzimierz Gruszczyński, + Marcin Woliński, Robert Wołosz + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS “AS IS” AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/x-pack/plugin/esql/licenses/lucene-NOTICE.txt b/x-pack/plugin/esql/licenses/lucene-NOTICE.txt new file mode 100644 index 0000000000000..1a1d51572432a --- /dev/null +++ b/x-pack/plugin/esql/licenses/lucene-NOTICE.txt @@ -0,0 +1,192 @@ +Apache Lucene +Copyright 2014 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Includes software from other Apache Software Foundation projects, +including, but not limited to: + - Apache Ant + - Apache Jakarta Regexp + - Apache Commons + - Apache Xerces + +ICU4J, (under analysis/icu) is licensed under an MIT styles license +and Copyright (c) 1995-2008 International Business Machines Corporation and others + +Some data files (under analysis/icu/src/data) are derived from Unicode data such +as the Unicode Character Database. See http://unicode.org/copyright.html for more +details. + +Brics Automaton (under core/src/java/org/apache/lucene/util/automaton) is +BSD-licensed, created by Anders Møller. See http://www.brics.dk/automaton/ + +The levenshtein automata tables (under core/src/java/org/apache/lucene/util/automaton) were +automatically generated with the moman/finenight FSA library, created by +Jean-Philippe Barrette-LaPierre. This library is available under an MIT license, +see http://sites.google.com/site/rrettesite/moman and +http://bitbucket.org/jpbarrette/moman/overview/ + +The class org.apache.lucene.util.WeakIdentityMap was derived from +the Apache CXF project and is Apache License 2.0. + +The Google Code Prettify is Apache License 2.0. +See http://code.google.com/p/google-code-prettify/ + +JUnit (junit-4.10) is licensed under the Common Public License v. 1.0 +See http://junit.sourceforge.net/cpl-v10.html + +This product includes code (JaspellTernarySearchTrie) from Java Spelling Checkin +g Package (jaspell): http://jaspell.sourceforge.net/ +License: The BSD License (http://www.opensource.org/licenses/bsd-license.php) + +The snowball stemmers in + analysis/common/src/java/net/sf/snowball +were developed by Martin Porter and Richard Boulton. +The snowball stopword lists in + analysis/common/src/resources/org/apache/lucene/analysis/snowball +were developed by Martin Porter and Richard Boulton. +The full snowball package is available from + http://snowball.tartarus.org/ + +The KStem stemmer in + analysis/common/src/org/apache/lucene/analysis/en +was developed by Bob Krovetz and Sergio Guzman-Lara (CIIR-UMass Amherst) +under the BSD-license. + +The Arabic,Persian,Romanian,Bulgarian, Hindi and Bengali analyzers (common) come with a default +stopword list that is BSD-licensed created by Jacques Savoy. These files reside in: +analysis/common/src/resources/org/apache/lucene/analysis/ar/stopwords.txt, +analysis/common/src/resources/org/apache/lucene/analysis/fa/stopwords.txt, +analysis/common/src/resources/org/apache/lucene/analysis/ro/stopwords.txt, +analysis/common/src/resources/org/apache/lucene/analysis/bg/stopwords.txt, +analysis/common/src/resources/org/apache/lucene/analysis/hi/stopwords.txt, +analysis/common/src/resources/org/apache/lucene/analysis/bn/stopwords.txt +See http://members.unine.ch/jacques.savoy/clef/index.html. + +The German,Spanish,Finnish,French,Hungarian,Italian,Portuguese,Russian and Swedish light stemmers +(common) are based on BSD-licensed reference implementations created by Jacques Savoy and +Ljiljana Dolamic. These files reside in: +analysis/common/src/java/org/apache/lucene/analysis/de/GermanLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/de/GermanMinimalStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/es/SpanishLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/fi/FinnishLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchMinimalStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/hu/HungarianLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/it/ItalianLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemmer.java +analysis/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemmer.java + +The Stempel analyzer (stempel) includes BSD-licensed software developed +by the Egothor project http://egothor.sf.net/, created by Leo Galambos, Martin Kvapil, +and Edmond Nolan. + +The Polish analyzer (stempel) comes with a default +stopword list that is BSD-licensed created by the Carrot2 project. The file resides +in stempel/src/resources/org/apache/lucene/analysis/pl/stopwords.txt. +See http://project.carrot2.org/license.html. + +The SmartChineseAnalyzer source code (smartcn) was +provided by Xiaoping Gao and copyright 2009 by www.imdict.net. + +WordBreakTestUnicode_*.java (under modules/analysis/common/src/test/) +is derived from Unicode data such as the Unicode Character Database. +See http://unicode.org/copyright.html for more details. + +The Morfologik analyzer (morfologik) includes BSD-licensed software +developed by Dawid Weiss and Marcin Miłkowski (http://morfologik.blogspot.com/). + +Morfologik uses data from Polish ispell/myspell dictionary +(http://www.sjp.pl/slownik/en/) licenced on the terms of (inter alia) +LGPL and Creative Commons ShareAlike. + +Morfologic includes data from BSD-licensed dictionary of Polish (SGJP) +(http://sgjp.pl/morfeusz/) + +Servlet-api.jar and javax.servlet-*.jar are under the CDDL license, the original +source code for this can be found at http://www.eclipse.org/jetty/downloads.php + +=========================================================================== +Kuromoji Japanese Morphological Analyzer - Apache Lucene Integration +=========================================================================== + +This software includes a binary and/or source version of data from + + mecab-ipadic-2.7.0-20070801 + +which can be obtained from + + http://atilika.com/releases/mecab-ipadic/mecab-ipadic-2.7.0-20070801.tar.gz + +or + + http://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz + +=========================================================================== +mecab-ipadic-2.7.0-20070801 Notice +=========================================================================== + +Nara Institute of Science and Technology (NAIST), +the copyright holders, disclaims all warranties with regard to this +software, including all implied warranties of merchantability and +fitness, in no event shall NAIST be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether in an +action of contract, negligence or other tortuous action, arising out +of or in connection with the use or performance of this software. + +A large portion of the dictionary entries +originate from ICOT Free Software. The following conditions for ICOT +Free Software applies to the current dictionary as well. + +Each User may also freely distribute the Program, whether in its +original form or modified, to any third party or parties, PROVIDED +that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear +on, or be attached to, the Program, which is distributed substantially +in the same form as set out herein and that such intended +distribution, if actually made, will neither violate or otherwise +contravene any of the laws and regulations of the countries having +jurisdiction over the User or the intended distribution itself. + +NO WARRANTY + +The program was produced on an experimental basis in the course of the +research and development conducted during the project and is provided +to users as so produced on an experimental basis. Accordingly, the +program is provided without any warranty whatsoever, whether express, +implied, statutory or otherwise. The term "warranty" used herein +includes, but is not limited to, any warranty of the quality, +performance, merchantability and fitness for a particular purpose of +the program and the nonexistence of any infringement or violation of +any right of any third party. + +Each user of the program will agree and understand, and be deemed to +have agreed and understood, that there is no warranty whatsoever for +the program and, accordingly, the entire risk arising from or +otherwise connected with the program is assumed by the user. + +Therefore, neither ICOT, the copyright holder, or any other +organization that participated in or was otherwise related to the +development of the program and their respective officials, directors, +officers and other employees shall be held liable for any and all +damages, including, without limitation, general, special, incidental +and consequential damages, arising out of or otherwise in connection +with the use or inability to use the program or any product, material +or result produced or otherwise obtained by using the program, +regardless of whether they have been advised of, or otherwise had +knowledge of, the possibility of such damages at any time during the +project or thereafter. Each user will be deemed to have agreed to the +foregoing by his or her commencement of use of the program. The term +"use" as used herein includes, but is not limited to, the use, +modification, copying and distribution of the program and the +production of secondary products from the program. + +In the case where the program, whether in its original form or +modified, was distributed or delivered to or received by a user from +any person, organization or entity other than ICOT, unless it makes or +grants independently of ICOT any specific warranty to the user in +writing, such person, organization or entity, will also be exempted +from and not be held liable to the user for any such damages as noted +above as far as the program is concerned. 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 3f8478fe713a3..83276d006273a 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 @@ -323,7 +323,7 @@ private static String pipeTable( if (values.size() > rows) { result.append("...").append(System.lineSeparator()); } - return result.toString(); + return result.toString().replaceAll("\\s+" + System.lineSeparator(), System.lineSeparator()); } private static String header(String name, Type type) { 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 new file mode 100644 index 0000000000000..743a226ce6413 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial-grid.csv-spec @@ -0,0 +1,977 @@ +############################################### +# Tests for geo_grid function: ST_GEOHASH +############################################### + +geohashStringToLong +required_capability: spatial_grid + +// tag::geohash_to_long[] +ROW geohash = "u3bu" +| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash) +// end::geohash_to_long[] +; + +// tag::geohash_to_long-result[] +geohash:keyword | geohashLong:long +u3bu | 13686180 +// end::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) +// end::geohash_to_string[] +; + +// tag::geohash_to_string-result[] +geohash:long | geohashString:keyword +13686180 | u3bu +// end::geohash_to_string-result[] +; + +geohashStringToGeoShape +required_capability: spatial_grid + +// tag::geohash_to_geoshape[] +ROW geohash = "u3bu" +| EVAL boundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +// end::geohash_to_geoshape[] +; + +// tag::geohash_to_geoshape-result[] +geohash: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 geohash = TO_LONG(13686180) +| EVAL boundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +; + +geohash: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[] +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[] +; + +// 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[] +; + +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)) +; + +location:geo_point | geohash4:keyword | geohash3:keyword | geohash2:keyword | geohash1:keyword +POINT(12.6493508684508 55.6285017221528) | u3bu | u3b | u3 | u +; + +geohashLiteralMv +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geohash = ST_GEOHASH(location, precision) +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +; + +location:geo_point | precision:integer | geohash:long | geohashString:keyword +POINT (12.6493508684508 55.6285017221528) | 1 | 417 | u +POINT (12.6493508684508 55.6285017221528) | 2 | 13362 | u3 +POINT (12.6493508684508 55.6285017221528) | 3 | 427683 | u3b +POINT (12.6493508684508 55.6285017221528) | 4 | 13686180 | u3bu +POINT (12.6493508684508 55.6285017221528) | 5 | 437958005 | u3bur +; + +geohashLiteralMvBoundary +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geohash = ST_GEOHASH_TO_STRING(ST_GEOHASH(location, precision)) +| EVAL cellBoundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +; + +location:geo_point | precision:integer | geohash:keyword | cellBoundary:geo_shape +POINT (12.6493508684508 55.6285017221528) | 1 | u | POLYGON((0.0 45.0, 45.0 45.0, 45.0 90.0, 0.0 90.0, 0.0 45.0)) +POINT (12.6493508684508 55.6285017221528) | 2 | u3 | POLYGON((11.25 50.625, 22.5 50.625, 22.5 56.25, 11.25 56.25, 11.25 50.625)) +POINT (12.6493508684508 55.6285017221528) | 3 | u3b | POLYGON((11.25 54.84375, 12.65625 54.84375, 12.65625 56.25, 11.25 56.25, 11.25 54.84375)) +POINT (12.6493508684508 55.6285017221528) | 4 | u3bu | POLYGON((12.3046875 55.546875, 12.65625 55.546875, 12.65625 55.72265625, 12.3046875 55.72265625, 12.3046875 55.546875)) +POINT (12.6493508684508 55.6285017221528) | 5 | u3bur | POLYGON((12.6123046875 55.5908203125, 12.65625 55.5908203125, 12.65625 55.634765625, 12.6123046875 55.634765625, 12.6123046875 55.5908203125)) +; + +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 +; + +geohash:long | geohashString:keyword | abbrev:keyword | name:text | location:geo_point +448469007591 | u3buryf | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +; + +gridGeohashStatsBy +required_capability: spatial_grid + +// tag::st_geohash-grid[] +FROM airports +| EVAL geohash = ST_GEOHASH(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohash +| WHERE count >= 10 +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| KEEP count, centroid, geohashString +| SORT count DESC, geohashString ASC +// end::st_geohash-grid[] +; + +// tag::st_geohash-grid-result[] +count:long | centroid:geo_point | geohashString:keyword +118 | POINT (-77.41857436454018 26.96522968734409) | d +96 | POINT (23.181679135886952 27.295384635654045) | s +94 | POINT (70.94076107503807 25.691916451026547) | t +90 | POINT (-104.3941700803116 30.811849871650338) | 9 +89 | POINT (18.71573683606942 53.165169130707305) | u +85 | POINT (114.3722876966657 24.908398092505248) | w +51 | POINT (-61.44522591713159 -22.87209844956284) | 6 +38 | POINT (-9.429514887252529 25.497624435045413) | e +34 | POINT (-111.8071846965262 52.464381378993174) | c +30 | POINT (28.7045472683385 -14.706001980230212) | k +28 | POINT (159.52750137208827 -25.555616633001982) | r +22 | POINT (-4.410395708612421 54.90304926367985) | g +21 | POINT (-69.40534970590046 50.93379438189523) | f +17 | POINT (114.05526293222519 -10.898114638950895) | q +16 | POINT (147.40052131412085 21.054660080408212) | x +13 | POINT (63.64716878519035 54.37333276101317) | v +12 | POINT (-39.53510569408536 -11.72166372067295) | 7 +// end::st_geohash-grid-result[] +; + +gridGeohashStatsByBounds +required_capability: spatial_grid + +FROM airports +| EVAL geohash = ST_GEOHASH(location, 2, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")) +| WHERE geohash IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohash +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL cellBoundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary +| SORT count DESC, geohashString ASC +; + +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)) +; + +gridGeohashStatsByPointsBounds +required_capability: spatial_grid + +FROM airports +| EVAL points = ["POINT(0.0 30.0)", "POINT(12.0 60.0)"] +| EVAL geohash = ST_GEOHASH(location, 2, TO_GEOPOINT(points)) +| WHERE geohash IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohash +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL cellBoundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary +| SORT count DESC, geohashString ASC +; + +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, ST_GEOHASH_TO_GEOSHAPE("u1")) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) +; + +count:long | centroid:geo_point +8 | POINT (6.351574736181647 51.8981519783847) +; + +gridGeohashStatsByWhereUK +required_capability: spatial_grid + +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))")) +| EVAL geohash = ST_GEOHASH(location, 2) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geohash +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL cellBoundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary +| SORT count DESC +; + +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 +required_capability: spatial_grid + +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))")) +| EVAL geohash = ST_GEOHASH(location, 2, bounds) +| WHERE geohash IS NOT NULL +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geohash +| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash) +| EVAL cellBoundary = ST_GEOHASH_TO_GEOSHAPE(geohash) +| KEEP count, centroid, geohashString, cellBoundary +| SORT count DESC, geohashString ASC +; + +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 +required_capability: spatial_grid + +FROM airports +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOHASH(location, 1) +| SORT count DESC +| KEEP count, centroid +| LIMIT 10 +; + +count:long | centroid:geo_point + 118 | POINT (-77.41857436454018 26.96522968734409) + 96 | POINT (23.181679135886952 27.295384635654045) + 94 | POINT (70.94076107503807 25.691916451026547) + 90 | POINT (-104.3941700803116 30.811849871650338) + 89 | POINT (18.71573683606942 53.165169130707305) + 85 | POINT (114.3722876966657 24.908398092505248) + 51 | POINT (-61.44522591713159 -22.87209844956284) + 38 | POINT (-9.429514887252529 25.497624435045413) + 34 | POINT (-111.8071846965262 52.464381378993174) + 30 | POINT (28.7045472683385 -14.706001980230212) +; + +gridGeohashInStatsByWhereUK +required_capability: spatial_grid + +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))")) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOHASH(location, 2) +| KEEP count, centroid +| SORT count DESC +; + +count:long | centroid:geo_point +14 | POINT (-2.5644131543646966 53.38093495994274) +3 | POINT (-2.7510103583335876 58.79020635969937) +; + +############################################### +# Tests for geo_grid function: ST_GEOTILE +############################################### + +geotileStringToLong +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::geotile_to_long-result[] +geotile:keyword | geotileLong:long +4/8/5 | 1152921508901814277 +// end::geotile_to_long-result[] +; + +geotileLongToString +required_capability: spatial_grid + +// tag::geotile_to_string[] +ROW geotile = 1152921508901814277 +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +// end::geotile_to_string[] +; + +// tag::geotile_to_string-result[] +geotile:long | geotileString:keyword +1152921508901814277 | 4/8/5 +// end::geotile_to_string-result[] +; + +geotileStringToGeoshape +required_capability: spatial_grid + +// tag::geotile_to_geoshape[] +ROW geotile = "4/8/5" +| EVAL boundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +// end::geotile_to_geoshape[] +; + +// tag::geotile_to_geoshape-result[] +geotile: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[] +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[] +; + +// 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[] +; + +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)) +; + +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 +; + +geotileLiteralMv +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geotile = ST_GEOTILE(location, precision) +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +; + +location:geo_point | precision:integer | geotile:long | geotileString:keyword +POINT (12.6493508684508 55.6285017221528) | 1 | 288230376688582656 | 1/1/0 +POINT (12.6493508684508 55.6285017221528) | 2 | 576460753377165313 | 2/2/1 +POINT (12.6493508684508 55.6285017221528) | 3 | 864691130602618882 | 3/4/2 +POINT (12.6493508684508 55.6285017221528) | 4 | 1152921508901814277 | 4/8/5 +POINT (12.6493508684508 55.6285017221528) | 5 | 1441151889885364234 | 5/17/10 +; + +geotileLiteralMvBoundary +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geotile = ST_GEOTILE_TO_STRING(ST_GEOTILE(location, precision)) +| EVAL cellBoundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +; + +location:geo_point | precision:integer | geotile:keyword | cellBoundary:geo_shape +POINT (12.6493508684508 55.6285017221528) | 1 | 1/1/0 | POLYGON((0.0 0.0, 180.0 0.0, 180.0 85.0511287798066, 0.0 85.0511287798066, 0.0 0.0)) +POINT (12.6493508684508 55.6285017221528) | 2 | 2/2/1 | POLYGON((0.0 0.0, 90.0 0.0, 90.0 66.51326044311186, 0.0 66.51326044311186, 0.0 0.0)) +POINT (12.6493508684508 55.6285017221528) | 3 | 3/4/2 | POLYGON((0.0 40.979898069620134, 45.0 40.979898069620134, 45.0 66.51326044311186, 0.0 66.51326044311186, 0.0 40.979898069620134)) +POINT (12.6493508684508 55.6285017221528) | 4 | 4/8/5 | POLYGON((0.0 40.979898069620134, 22.5 40.979898069620134, 22.5 55.77657301866769, 0.0 55.77657301866769, 0.0 40.979898069620134)) +POINT (12.6493508684508 55.6285017221528) | 5 | 5/17/10 | POLYGON((11.25 48.922499263758255, 22.5 48.922499263758255, 22.5 55.77657301866769, 11.25 55.77657301866769, 11.25 48.922499263758255)) +; + +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 +; + +geotile:long | geotileString:keyword | abbrev:keyword | name:text | location:geo_point +2017612669569204264 | 7/68/40 | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +; + +gridGeotileStatsBy +required_capability: spatial_grid + +// tag::st_geotile-grid[] +FROM airports +| EVAL geotile = ST_GEOTILE(location, 2) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| SORT count DESC, geotileString ASC +| KEEP count, centroid, geotileString +// end::st_geotile-grid[] +; + +// tag::st_geotile-grid-result[] +count:long | centroid:geo_point | geotileString:keyword +286 | POINT (39.31202001609169 35.149993664386415) | 2/2/1 +197 | POINT (-55.387361375756825 31.952955322292855) | 2/1/1 +136 | POINT (-110.97162496141048 36.87185255084734) | 2/0/1 +106 | POINT (119.35907618669827 25.46263281488791) | 2/3/1 +67 | POINT (-58.031108492373754 -22.624166105151065) | 2/1/2 +46 | POINT (142.95455511274707 -20.581492295427978) | 2/3/2 +34 | POINT (31.38476753634784 -14.64374022804858) | 2/2/2 +8 | POINT (-160.0723083713092 -19.124013530672528) | 2/0/2 +6 | POINT (23.95813101902604 70.17537698848173) | 2/2/0 +3 | POINT (-133.4001641627401 72.06833167467266) | 2/0/0 +2 | POINT (-68.47209956031293 66.77569948369637) | 2/1/0 +// end::st_geotile-grid-result[] +; + +gridGeotileStatsByBounds +required_capability: spatial_grid + +FROM airports +| EVAL geotile = ST_GEOTILE(location, 3, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")) +| WHERE geotile IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL cellBoundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +| SORT count DESC, geotileString ASC +| KEEP count, centroid, geotileString, cellBoundary +; + +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)) +; + +gridGeotileStatsByPointsBounds +required_capability: spatial_grid + +FROM airports +| EVAL points = ["POINT(0.0 30.0)", "POINT(12.0 60.0)"] +| EVAL geotile = ST_GEOTILE(location, 3, TO_GEOPOINT(points)) +| WHERE geotile IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL cellBoundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary +| SORT count DESC, geotileString ASC +; + +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, ST_GEOTILE_TO_GEOSHAPE("3/4/3")) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) +; + +count:long | centroid:geo_point +79 | POINT (24.516750878736943 23.93036561181085) +; + +gridGeotileStatsByWhereUK +required_capability: spatial_grid + +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))")) +| EVAL geotile = ST_GEOTILE(location, 4) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL cellBoundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary +| SORT count DESC +; + +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 +required_capability: spatial_grid + +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))")) +| EVAL geotile = ST_GEOTILE(location, 4, bounds) +| WHERE geotile IS NOT NULL +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geotile +| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile) +| EVAL cellBoundary = ST_GEOTILE_TO_GEOSHAPE(geotile) +| KEEP count, centroid, geotileString, cellBoundary +| SORT count DESC +; + +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 +required_capability: spatial_grid + +FROM airports +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOTILE(location, 1) +| SORT count DESC +| KEEP count, centroid +| LIMIT 10 +; + +count:long | centroid:geo_point +398 | POINT (60.39961956408642 33.09796363900383) +338 | POINT (-78.52247301001411 34.49426195088267) +80 | POINT (95.5373953927774 -18.057947666791733) +75 | POINT (-68.91550314612687 -22.25081649720669) +; + +gridGeotileInStatsByWhereUK +required_capability: spatial_grid + +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))")) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOTILE(location, 3) +| KEEP count, centroid +| SORT count DESC +; + +count:long | centroid:geo_point +17 | POINT (-2.597342072712148 54.33551226578214) +; + +############################################### +# Tests for geo_grid function: ST_GEOHEX +############################################### + +geohexStringToLong +required_capability: spatial_grid + +// tag::geohex_to_long[] +ROW geohex = "841f059ffffffff" +| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex) +// end::geohex_to_long[] +; + +// tag::geohex_to_long-result[] +geohex:keyword | geohexLong:long +841f059ffffffff | 595020895127339007 +// end::geohex_to_long-result[] +; + +geohexLongToString +required_capability: spatial_grid + +// tag::geohex_to_string[] +ROW geohex = 595020895127339007 +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +// end::geohex_to_string[] +; + +// tag::geohex_to_string-result[] +geohex:long | geohexString:keyword +595020895127339007 | 841f059ffffffff +// end::geohex_to_string-result[] +; + +geohexStringToGeoshape +required_capability: spatial_grid + +// tag::geohex_to_geoshape[] +ROW geohex = "841f059ffffffff" +| EVAL boundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +// end::geohex_to_geoshape[] +; + +// tag::geohex_to_geoshape-result[] +geohex: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[] +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[] +; + +// 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[] +; + +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)) +; + +location:geo_point | geohex4:keyword | geohex3:keyword | geohex2:keyword | geohex1:keyword +POINT (12.6493508684508 55.6285017221528) | 841f059ffffffff | 831f05fffffffff | 821f07fffffffff | 811f3ffffffffff +; + +geohexLiteralMv +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geohex = ST_GEOHEX(location, precision) +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +; + +location:geo_point | precision:integer | geohex:long | geohexString:keyword +POINT (12.6493508684508 55.6285017221528) | 1 | 581514107744681983 | 811f3ffffffffff +POINT (12.6493508684508 55.6285017221528) | 2 | 586013859081355263 | 821f07fffffffff +POINT (12.6493508684508 55.6285017221528) | 3 | 590517321269772287 | 831f05fffffffff +POINT (12.6493508684508 55.6285017221528) | 4 | 595020895127339007 | 841f059ffffffff +POINT (12.6493508684508 55.6285017221528) | 5 | 599524487238516735 | 851f0583fffffff +; + +geohexLiteralMvBoundary +required_capability: spatial_grid + +ROW location = TO_GEOPOINT("POINT(12.6493508684508 55.6285017221528)"), precision = [1,2,3,4,5] +| MV_EXPAND precision +| EVAL geohex = ST_GEOHEX_TO_STRING(ST_GEOHEX(location, precision)) +| EVAL cellBoundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +; + +location:geo_point | precision:integer | geohex:keyword | cellBoundary:geo_shape +POINT (12.6493508684508 55.6285017221528) | 1 | 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)) +POINT (12.6493508684508 55.6285017221528) | 2 | 821f07fffffffff | POLYGON ((10.06569233741819 55.3948787035456, 9.374530816292083 53.97551370235174, 11.245170492278875 53.03203973205439, 13.839528609232428 53.48724516123688, 14.640206584543728 54.90218190493179, 12.739822958959062 55.8673267391136, 10.06569233741819 55.3948787035456)) +POINT (12.6493508684508 55.6285017221528) | 3 | 831f05fffffffff | POLYGON ((11.860105203878488 55.53944935104936, 11.917786510985744 55.0057489060893, 12.839846498886947 54.79854371636354, 13.717124800902113 55.12308086302377, 13.674892957473272 55.65810153974231, 12.739822958959069 55.8673267391136, 11.860105203878488 55.53944935104936)) +POINT (12.6493508684508 55.6285017221528) | 4 | 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)) +POINT (12.6493508684508 55.6285017221528) | 5 | 851f0583fffffff | POLYGON ((12.494766876566144 55.69864155255122, 12.502309582573728 55.6227995792834, 12.635566668537882 55.59351730049433, 12.761550811198047 55.640035539252175, 12.754326292782508 55.71590456460875, 12.62079911077343 55.745228479933665, 12.494766876566144 55.69864155255122)) +; + +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 +; + +geohex:long | geohexString:keyword | abbrev:keyword | name:text | location:geo_point +608531685838946303 | 871f05818ffffff | CPH | Copenhagen | POINT (12.6493508684508 55.6285017221528) +; + +gridGeohexStatsBy +required_capability: spatial_grid + +// tag::st_geohex-grid[] +FROM airports +| EVAL geohex = ST_GEOHEX(location, 1) +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohex +| WHERE count >= 10 +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| KEEP count, centroid, geohexString +| SORT count DESC, geohexString ASC +// end::st_geohex-grid[] +; + +// tag::st_geohex-grid-result[] +count:long | centroid:geo_point | geohexString:keyword +22 | POINT (7.250850197689777 48.21363834643059) | 811fbffffffffff +18 | POINT (-80.64959161449224 40.04119813675061) | 812abffffffffff +17 | POINT (-0.7606179875266903 52.86413913565304) | 81197ffffffffff +13 | POINT (22.53157936179867 41.98255742864254) | 811efffffffffff +13 | POINT (78.30096947387435 26.073904778951636) | 813dbffffffffff +12 | POINT (-76.39781514415517 45.16300531569868) | 812bbffffffffff +12 | POINT (-100.30120467301458 20.114154297625646) | 8149bffffffffff +11 | POINT (18.037187419831753 48.66540593306788) | 811e3ffffffffff +11 | POINT (-83.42379064553164 33.18388901439241) | 8144fffffffffff +11 | POINT (-99.4237939513881 27.100012352774765) | 8148bffffffffff +10 | POINT (128.01009018346667 35.8699960866943) | 8130fffffffffff +// end::st_geohex-grid-result[] +; + +gridGeohexStatsByBounds +required_capability: spatial_grid + +FROM airports +| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")) +| WHERE geohex IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohex +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL cellBoundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +| SORT count DESC, geohexString ASC +| KEEP count, centroid, geohexString, cellBoundary +; + +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)) +; + +gridGeohexStatsByPointsBounds +required_capability: spatial_grid + +FROM airports +| EVAL points = ["POINT(0.0 30.0)", "POINT(12.0 60.0)"] +| EVAL geohex = ST_GEOHEX(location, 1, TO_GEOPOINT(points)) +| WHERE geohex IS NOT NULL +| STATS + count = COUNT(*), + centroid = ST_CENTROID_AGG(location) + BY geohex +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL cellBoundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +| KEEP count, centroid, geohexString, cellBoundary +| SORT count DESC, geohexString ASC +; + +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)) +; + +// TODO: Fix this test +//gridGeohexDocsFromCell +//required_capability: spatial_grid +// +//FROM airports +//| WHERE ST_INTERSECTS(location, ST_GEOHEX_TO_GEOSHAPE("81397ffffffffff")) +//| STATS +// count = COUNT(*), +// centroid = ST_CENTROID_AGG(location) +//; +// +//count:long | centroid:geo_point +//7 | POINT (2.475211258445467 41.32352174592337) +//; + +gridGeohexStatsByWhereUK +required_capability: spatial_grid + +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))")) +| EVAL geohex = ST_GEOHEX(location, 1) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geohex +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL cellBoundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +| KEEP count, centroid, geohexString, cellBoundary +| SORT count DESC, geohexString ASC +; + +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 +required_capability: spatial_grid + +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))")) +| EVAL geohex = ST_GEOHEX(location, 2, bounds) +| WHERE geohex IS NOT NULL +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY geohex +| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex) +| EVAL cellBoundary = ST_GEOHEX_TO_GEOSHAPE(geohex) +| KEEP count, centroid, geohexString, cellBoundary +| SORT count DESC, geohexString ASC +; + +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 +required_capability: spatial_grid + +FROM airports +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOHEX(location, 2, TO_GEOSHAPE("POLYGON((0.0 30.0, 12.0 30.0, 12.0 60.0, 0.0 60.0, 0.0 30.0))")) +| WHERE count > 3 +| SORT count DESC +| KEEP count, centroid +| LIMIT 10 +; + +count:long | centroid:geo_point +827 | POINT (-0.5615898292227913 22.56591850424922) +6 | POINT (5.582276992499828 50.72238312335685) +5 | POINT (8.6918301936239 45.19817395694554) +; + +gridGeohexInStatsByWhereUK +required_capability: spatial_grid + +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))")) +| STATS + count = COUNT(location), + centroid = ST_CENTROID_AGG(location) + BY ST_GEOHEX(location, 1) +| WHERE count > 1 +| KEEP count, centroid +| SORT count DESC +; + +count:long | centroid:geo_point +13 | POINT (-2.283508819169723 53.28242553254733) +2 | POINT (-3.482485176064074 58.24696456314996) +; diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..dafbf8836e46f --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldAndLiteralEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldAndFieldAndLiteral(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohashFromFieldAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldAndFieldAndLiteralEvaluator(source, in.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldEvaluator.java new file mode 100644 index 0000000000000..e97975b26aa44 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldAndFieldEvaluator(Source source, EvalOperator.ExpressionEvaluator in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldAndField(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeohashFromFieldAndFieldEvaluator get(DriverContext context) { + return new StGeohashFromFieldAndFieldEvaluator(source, in.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohashFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..2e4b8e7d538d8 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,119 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final StGeohash.GeoHashBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, StGeohash.GeoHashBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + return eval(page.getPositionCount(), inBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldAndLiteralAndLiteral(result, p, inBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in); + } + + 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 in; + + private final StGeohash.GeoHashBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + StGeohash.GeoHashBoundedGrid bounds) { + this.source = source; + this.in = in; + this.bounds = bounds; + } + + @Override + public StGeohashFromFieldAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldAndLiteralAndLiteralEvaluator(source, in.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..c67d7e4855299 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkbBlock; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkbBlock, int precision, DriverContext driverContext) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlockBlock = (BytesRefBlock) wkbBlock.eval(page)) { + return eval(page.getPositionCount(), wkbBlockBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock wkbBlockBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlockBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldAndLiteral(result, p, wkbBlockBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkbBlock); + } + + 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 wkbBlock; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkbBlock, + int precision) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + } + + @Override + public StGeohashFromFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldAndLiteralEvaluator(source, wkbBlock.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..c5e2f6a651825 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator.java @@ -0,0 +1,139 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldDocValuesAndFieldAndLiteral(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator(source, encoded.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldEvaluator.java new file mode 100644 index 0000000000000..ad24270bba186 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldDocValuesAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldDocValuesAndFieldEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldDocValuesAndField(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeohashFromFieldDocValuesAndFieldEvaluator get(DriverContext context) { + return new StGeohashFromFieldDocValuesAndFieldEvaluator(source, encoded.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..862b2b90c9b2d --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final StGeohash.GeoHashBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, StGeohash.GeoHashBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldDocValuesAndLiteralAndLiteral(result, p, encodedBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final StGeohash.GeoHashBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + StGeohash.GeoHashBoundedGrid bounds) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + } + + @Override + public StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator(source, encoded.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralEvaluator.java new file mode 100644 index 0000000000000..a57c2559093bf --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromFieldDocValuesAndLiteralEvaluator.java @@ -0,0 +1,116 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromFieldDocValuesAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromFieldDocValuesAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, int precision, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohash.fromFieldDocValuesAndLiteral(result, p, encodedBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, int precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeohashFromFieldDocValuesAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromFieldDocValuesAndLiteralEvaluator(source, encoded.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeohashFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..11b7e9d8e220c --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldAndLiteralEvaluator.java @@ -0,0 +1,149 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromLiteralAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromLiteralAndFieldAndLiteralEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, GeoBoundingBox bbox, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeohash.fromLiteralAndFieldAndLiteral(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeohash.fromLiteralAndFieldAndLiteral(this.in, precisionVector.getInt(p), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision, + GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohashFromLiteralAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohashFromLiteralAndFieldAndLiteralEvaluator(source, in, precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohashFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldEvaluator.java new file mode 100644 index 0000000000000..8a60d2211ae4a --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashFromLiteralAndFieldEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +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.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohash}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohashFromLiteralAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohashFromLiteralAndFieldEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeohash.fromLiteralAndField(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeohash.fromLiteralAndField(this.in, precisionVector.getInt(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohashFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeohashFromLiteralAndFieldEvaluator get(DriverContext context) { + return new StGeohashFromLiteralAndFieldEvaluator(source, in, precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohashFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromLongEvaluator.java new file mode 100644 index 0000000000000..3e95b8a55d7e9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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 StGeohashToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohashToGeoShapeFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohashToGeoShapeFromLongEvaluator(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 StGeohashToGeoShape.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 StGeohashToGeoShape.fromLong(value); + } + + @Override + public String toString() { + return "StGeohashToGeoShapeFromLongEvaluator[" + "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 StGeohashToGeoShapeFromLongEvaluator get(DriverContext context) { + return new StGeohashToGeoShapeFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohashToGeoShapeFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromStringEvaluator.java new file mode 100644 index 0000000000000..0e50257a50bed --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeFromStringEvaluator.java @@ -0,0 +1,144 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.OrdinalBytesRefVector; +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 StGeohashToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohashToGeoShapeFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohashToGeoShapeFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + OrdinalBytesRefVector ordinals = vector.asOrdinals(); + if (ordinals != null) { + return evalOrdinals(ordinals); + } + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private BytesRef evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohashToGeoShape.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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, scratchPad); + 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(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohashToGeoShape.fromString(value); + } + + private Block evalOrdinals(OrdinalBytesRefVector v) { + int positionCount = v.getDictionaryVector().getPositionCount(); + BytesRef scratchPad = new BytesRef(); + try (BytesRefVector.Builder builder = driverContext.blockFactory().newBytesRefVectorBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(v.getDictionaryVector(), p, scratchPad)); + } + IntVector ordinals = v.getOrdinalsVector(); + ordinals.incRef(); + return new OrdinalBytesRefVector(ordinals, builder.build()).asBlock(); + } + } + + @Override + public String toString() { + return "StGeohashToGeoShapeFromStringEvaluator[" + "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 StGeohashToGeoShapeFromStringEvaluator get(DriverContext context) { + return new StGeohashToGeoShapeFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohashToGeoShapeFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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/spatial/StGeohashToLongFromStringEvaluator.java new file mode 100644 index 0000000000000..640a77fe05fb9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongFromStringEvaluator.java @@ -0,0 +1,126 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.LongBlock; +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 StGeohashToLong}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohashToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohashToLongFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendLong(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohashToLong.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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++) { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } + if (valuesAppended == false) { + builder.appendNull(); + } else if (positionOpened) { + builder.endPositionEntry(); + } + } + return builder.build(); + } + } + + private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohashToLong.fromString(value); + } + + @Override + public String toString() { + return "StGeohashToLongFromStringEvaluator[" + "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 StGeohashToLongFromStringEvaluator get(DriverContext context) { + return new StGeohashToLongFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohashToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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/spatial/StGeohashToStringFromLongEvaluator.java new file mode 100644 index 0000000000000..3e33f376e4e7e --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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 StGeohashToString}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohashToStringFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohashToStringFromLongEvaluator(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 StGeohashToString.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 StGeohashToString.fromLong(value); + } + + @Override + public String toString() { + return "StGeohashToStringFromLongEvaluator[" + "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 StGeohashToStringFromLongEvaluator get(DriverContext context) { + return new StGeohashToStringFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohashToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..eb956fa8b37b1 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldAndLiteralEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldAndFieldAndLiteral(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohexFromFieldAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldAndFieldAndLiteralEvaluator(source, in.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldEvaluator.java new file mode 100644 index 0000000000000..36d121396a086 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldAndFieldEvaluator(Source source, EvalOperator.ExpressionEvaluator in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldAndField(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeohexFromFieldAndFieldEvaluator get(DriverContext context) { + return new StGeohexFromFieldAndFieldEvaluator(source, in.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohexFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..24e070c46adda --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,119 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final StGeohex.GeoHexBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, StGeohex.GeoHexBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + return eval(page.getPositionCount(), inBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldAndLiteralAndLiteral(result, p, inBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in); + } + + 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 in; + + private final StGeohex.GeoHexBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + StGeohex.GeoHexBoundedGrid bounds) { + this.source = source; + this.in = in; + this.bounds = bounds; + } + + @Override + public StGeohexFromFieldAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldAndLiteralAndLiteralEvaluator(source, in.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..5209d32caf308 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkbBlock; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkbBlock, int precision, DriverContext driverContext) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlockBlock = (BytesRefBlock) wkbBlock.eval(page)) { + return eval(page.getPositionCount(), wkbBlockBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock wkbBlockBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlockBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldAndLiteral(result, p, wkbBlockBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkbBlock); + } + + 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 wkbBlock; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkbBlock, + int precision) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + } + + @Override + public StGeohexFromFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldAndLiteralEvaluator(source, wkbBlock.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..c8b750048d141 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator.java @@ -0,0 +1,139 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldDocValuesAndFieldAndLiteral(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator(source, encoded.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldEvaluator.java new file mode 100644 index 0000000000000..947bc22e41136 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldDocValuesAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldDocValuesAndFieldEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldDocValuesAndField(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeohexFromFieldDocValuesAndFieldEvaluator get(DriverContext context) { + return new StGeohexFromFieldDocValuesAndFieldEvaluator(source, encoded.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..0ac32cbdbedad --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final StGeohex.GeoHexBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, StGeohex.GeoHexBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldDocValuesAndLiteralAndLiteral(result, p, encodedBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final StGeohex.GeoHexBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + StGeohex.GeoHexBoundedGrid bounds) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + } + + @Override + public StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator(source, encoded.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralEvaluator.java new file mode 100644 index 0000000000000..2b7d48d5f159d --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromFieldDocValuesAndLiteralEvaluator.java @@ -0,0 +1,116 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromFieldDocValuesAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromFieldDocValuesAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, int precision, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeohex.fromFieldDocValuesAndLiteral(result, p, encodedBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, int precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeohexFromFieldDocValuesAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromFieldDocValuesAndLiteralEvaluator(source, encoded.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeohexFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..ff03bbf920760 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldAndLiteralEvaluator.java @@ -0,0 +1,149 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromLiteralAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromLiteralAndFieldAndLiteralEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, GeoBoundingBox bbox, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeohex.fromLiteralAndFieldAndLiteral(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeohex.fromLiteralAndFieldAndLiteral(this.in, precisionVector.getInt(p), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision, + GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeohexFromLiteralAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeohexFromLiteralAndFieldAndLiteralEvaluator(source, in, precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeohexFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldEvaluator.java new file mode 100644 index 0000000000000..d3daf1b6178da --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexFromLiteralAndFieldEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +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.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeohex}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeohexFromLiteralAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeohexFromLiteralAndFieldEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeohex.fromLiteralAndField(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeohex.fromLiteralAndField(this.in, precisionVector.getInt(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeohexFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeohexFromLiteralAndFieldEvaluator get(DriverContext context) { + return new StGeohexFromLiteralAndFieldEvaluator(source, in, precision.get(context), context); + } + + @Override + public String toString() { + return "StGeohexFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromLongEvaluator.java new file mode 100644 index 0000000000000..250c2159e380b --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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 StGeohexToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohexToGeoShapeFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohexToGeoShapeFromLongEvaluator(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 StGeohexToGeoShape.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 StGeohexToGeoShape.fromLong(value); + } + + @Override + public String toString() { + return "StGeohexToGeoShapeFromLongEvaluator[" + "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 StGeohexToGeoShapeFromLongEvaluator get(DriverContext context) { + return new StGeohexToGeoShapeFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohexToGeoShapeFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromStringEvaluator.java new file mode 100644 index 0000000000000..94887bda9c960 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeFromStringEvaluator.java @@ -0,0 +1,144 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.OrdinalBytesRefVector; +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 StGeohexToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohexToGeoShapeFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohexToGeoShapeFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + OrdinalBytesRefVector ordinals = vector.asOrdinals(); + if (ordinals != null) { + return evalOrdinals(ordinals); + } + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private BytesRef evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohexToGeoShape.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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, scratchPad); + 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(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohexToGeoShape.fromString(value); + } + + private Block evalOrdinals(OrdinalBytesRefVector v) { + int positionCount = v.getDictionaryVector().getPositionCount(); + BytesRef scratchPad = new BytesRef(); + try (BytesRefVector.Builder builder = driverContext.blockFactory().newBytesRefVectorBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(v.getDictionaryVector(), p, scratchPad)); + } + IntVector ordinals = v.getOrdinalsVector(); + ordinals.incRef(); + return new OrdinalBytesRefVector(ordinals, builder.build()).asBlock(); + } + } + + @Override + public String toString() { + return "StGeohexToGeoShapeFromStringEvaluator[" + "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 StGeohexToGeoShapeFromStringEvaluator get(DriverContext context) { + return new StGeohexToGeoShapeFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohexToGeoShapeFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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/spatial/StGeohexToLongFromStringEvaluator.java new file mode 100644 index 0000000000000..815b5c9cb9015 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongFromStringEvaluator.java @@ -0,0 +1,126 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.LongBlock; +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 StGeohexToLong}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeohexToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeohexToLongFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendLong(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohexToLong.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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++) { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } + if (valuesAppended == false) { + builder.appendNull(); + } else if (positionOpened) { + builder.endPositionEntry(); + } + } + return builder.build(); + } + } + + private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeohexToLong.fromString(value); + } + + @Override + public String toString() { + return "StGeohexToLongFromStringEvaluator[" + "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 StGeohexToLongFromStringEvaluator get(DriverContext context) { + return new StGeohexToLongFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeohexToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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 new file mode 100644 index 0000000000000..9806e85ef6a48 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..3644945c6600c --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldAndLiteralEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldAndFieldAndLiteral(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeotileFromFieldAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldAndFieldAndLiteralEvaluator(source, in.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldEvaluator.java new file mode 100644 index 0000000000000..c0e9075742d58 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldAndFieldEvaluator(Source source, EvalOperator.ExpressionEvaluator in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), inBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldAndField(result, p, inBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in, precision); + } + + 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 in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeotileFromFieldAndFieldEvaluator get(DriverContext context) { + return new StGeotileFromFieldAndFieldEvaluator(source, in.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeotileFromFieldAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..13a8da4ad0c9c --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,119 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator in; + + private final StGeotile.GeoTileBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator in, StGeotile.GeoTileBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inBlock = (BytesRefBlock) in.eval(page)) { + return eval(page.getPositionCount(), inBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock inBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!inBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldAndLiteralAndLiteral(result, p, inBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(in); + } + + 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 in; + + private final StGeotile.GeoTileBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory in, + StGeotile.GeoTileBoundedGrid bounds) { + this.source = source; + this.in = in; + this.bounds = bounds; + } + + @Override + public StGeotileFromFieldAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldAndLiteralAndLiteralEvaluator(source, in.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldAndLiteralAndLiteralEvaluator[" + "in=" + in + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..f5b6f4b503373 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator wkbBlock; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator wkbBlock, int precision, DriverContext driverContext) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock wkbBlockBlock = (BytesRefBlock) wkbBlock.eval(page)) { + return eval(page.getPositionCount(), wkbBlockBlock); + } + } + + public LongBlock eval(int positionCount, BytesRefBlock wkbBlockBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!wkbBlockBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldAndLiteral(result, p, wkbBlockBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(wkbBlock); + } + + 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 wkbBlock; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory wkbBlock, + int precision) { + this.source = source; + this.wkbBlock = wkbBlock; + this.precision = precision; + } + + @Override + public StGeotileFromFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldAndLiteralEvaluator(source, wkbBlock.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldAndLiteralEvaluator[" + "wkbBlock=" + wkbBlock + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..9c621960577ec --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator.java @@ -0,0 +1,139 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + GeoBoundingBox bbox, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldDocValuesAndFieldAndLiteral(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision, GeoBoundingBox bbox) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator(source, encoded.get(context), precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldEvaluator.java new file mode 100644 index 0000000000000..0db8ced570f03 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndFieldEvaluator.java @@ -0,0 +1,132 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldDocValuesAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldDocValuesAndFieldEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, EvalOperator.ExpressionEvaluator precision, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + return eval(page.getPositionCount(), encodedBlock, precisionBlock); + } + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldDocValuesAndField(result, p, encodedBlock, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded, precision); + } + + 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 encoded; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeotileFromFieldDocValuesAndFieldEvaluator get(DriverContext context) { + return new StGeotileFromFieldDocValuesAndFieldEvaluator(source, encoded.get(context), precision.get(context), context); + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndFieldEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator.java new file mode 100644 index 0000000000000..c6dc1d23b9f3d --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator.java @@ -0,0 +1,118 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final StGeotile.GeoTileBoundedGrid bounds; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, StGeotile.GeoTileBoundedGrid bounds, + DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldDocValuesAndLiteralAndLiteral(result, p, encodedBlock, this.bounds); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final StGeotile.GeoTileBoundedGrid bounds; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, + StGeotile.GeoTileBoundedGrid bounds) { + this.source = source; + this.encoded = encoded; + this.bounds = bounds; + } + + @Override + public StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator(source, encoded.get(context), bounds, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator[" + "encoded=" + encoded + ", bounds=" + bounds + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralEvaluator.java new file mode 100644 index 0000000000000..93acf7bd2badc --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromFieldDocValuesAndLiteralEvaluator.java @@ -0,0 +1,116 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.elasticsearch.compute.data.Block; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromFieldDocValuesAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final EvalOperator.ExpressionEvaluator encoded; + + private final int precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromFieldDocValuesAndLiteralEvaluator(Source source, + EvalOperator.ExpressionEvaluator encoded, int precision, DriverContext driverContext) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock encodedBlock = (LongBlock) encoded.eval(page)) { + return eval(page.getPositionCount(), encodedBlock); + } + } + + public LongBlock eval(int positionCount, LongBlock encodedBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + boolean allBlocksAreNulls = true; + if (!encodedBlock.isNull(p)) { + allBlocksAreNulls = false; + } + if (allBlocksAreNulls) { + result.appendNull(); + continue position; + } + try { + StGeotile.fromFieldDocValuesAndLiteral(result, p, encodedBlock, this.precision); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(encoded); + } + + 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 encoded; + + private final int precision; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory encoded, int precision) { + this.source = source; + this.encoded = encoded; + this.precision = precision; + } + + @Override + public StGeotileFromFieldDocValuesAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromFieldDocValuesAndLiteralEvaluator(source, encoded.get(context), precision, context); + } + + @Override + public String toString() { + return "StGeotileFromFieldDocValuesAndLiteralEvaluator[" + "encoded=" + encoded + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldAndLiteralEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldAndLiteralEvaluator.java new file mode 100644 index 0000000000000..f626323fdc4f9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldAndLiteralEvaluator.java @@ -0,0 +1,149 @@ +// 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.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromLiteralAndFieldAndLiteralEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final GeoBoundingBox bbox; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromLiteralAndFieldAndLiteralEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, GeoBoundingBox bbox, + DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeotile.fromLiteralAndFieldAndLiteral(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeotile.fromLiteralAndFieldAndLiteral(this.in, precisionVector.getInt(p), this.bbox)); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + private final GeoBoundingBox bbox; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision, + GeoBoundingBox bbox) { + this.source = source; + this.in = in; + this.precision = precision; + this.bbox = bbox; + } + + @Override + public StGeotileFromLiteralAndFieldAndLiteralEvaluator get(DriverContext context) { + return new StGeotileFromLiteralAndFieldAndLiteralEvaluator(source, in, precision.get(context), bbox, context); + } + + @Override + public String toString() { + return "StGeotileFromLiteralAndFieldAndLiteralEvaluator[" + "in=" + in + ", precision=" + precision + ", bbox=" + bbox + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldEvaluator.java new file mode 100644 index 0000000000000..8a9534e8095d6 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileFromLiteralAndFieldEvaluator.java @@ -0,0 +1,140 @@ +// 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.IllegalArgumentException; +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.IntBlock; +import org.elasticsearch.compute.data.IntVector; +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; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link StGeotile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class StGeotileFromLiteralAndFieldEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BytesRef in; + + private final EvalOperator.ExpressionEvaluator precision; + + private final DriverContext driverContext; + + private Warnings warnings; + + public StGeotileFromLiteralAndFieldEvaluator(Source source, BytesRef in, + EvalOperator.ExpressionEvaluator precision, DriverContext driverContext) { + this.source = source; + this.in = in; + this.precision = precision; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock precisionBlock = (IntBlock) precision.eval(page)) { + IntVector precisionVector = precisionBlock.asVector(); + if (precisionVector == null) { + return eval(page.getPositionCount(), precisionBlock); + } + return eval(page.getPositionCount(), precisionVector); + } + } + + public LongBlock eval(int positionCount, IntBlock precisionBlock) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + if (precisionBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (precisionBlock.getValueCount(p) != 1) { + if (precisionBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendLong(StGeotile.fromLiteralAndField(this.in, precisionBlock.getInt(precisionBlock.getFirstValueIndex(p)))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public LongBlock eval(int positionCount, IntVector precisionVector) { + try(LongBlock.Builder result = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendLong(StGeotile.fromLiteralAndField(this.in, precisionVector.getInt(p))); + } catch (IllegalArgumentException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "StGeotileFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(precision); + } + + 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 BytesRef in; + + private final EvalOperator.ExpressionEvaluator.Factory precision; + + public Factory(Source source, BytesRef in, EvalOperator.ExpressionEvaluator.Factory precision) { + this.source = source; + this.in = in; + this.precision = precision; + } + + @Override + public StGeotileFromLiteralAndFieldEvaluator get(DriverContext context) { + return new StGeotileFromLiteralAndFieldEvaluator(source, in, precision.get(context), context); + } + + @Override + public String toString() { + return "StGeotileFromLiteralAndFieldEvaluator[" + "in=" + in + ", precision=" + precision + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromLongEvaluator.java new file mode 100644 index 0000000000000..e625fb7443aab --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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 StGeotileToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeotileToGeoShapeFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeotileToGeoShapeFromLongEvaluator(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 StGeotileToGeoShape.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 StGeotileToGeoShape.fromLong(value); + } + + @Override + public String toString() { + return "StGeotileToGeoShapeFromLongEvaluator[" + "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 StGeotileToGeoShapeFromLongEvaluator get(DriverContext context) { + return new StGeotileToGeoShapeFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeotileToGeoShapeFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromStringEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromStringEvaluator.java new file mode 100644 index 0000000000000..801bf228e6adf --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeFromStringEvaluator.java @@ -0,0 +1,144 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.OrdinalBytesRefVector; +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 StGeotileToGeoShape}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeotileToGeoShapeFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeotileToGeoShapeFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + OrdinalBytesRefVector ordinals = vector.asOrdinals(); + if (ordinals != null) { + return evalOrdinals(ordinals); + } + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantBytesRefBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private BytesRef evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToGeoShape.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (BytesRefBlock.Builder builder = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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, scratchPad); + 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(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToGeoShape.fromString(value); + } + + private Block evalOrdinals(OrdinalBytesRefVector v) { + int positionCount = v.getDictionaryVector().getPositionCount(); + BytesRef scratchPad = new BytesRef(); + try (BytesRefVector.Builder builder = driverContext.blockFactory().newBytesRefVectorBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendBytesRef(evalValue(v.getDictionaryVector(), p, scratchPad)); + } + IntVector ordinals = v.getOrdinalsVector(); + ordinals.incRef(); + return new OrdinalBytesRefVector(ordinals, builder.build()).asBlock(); + } + } + + @Override + public String toString() { + return "StGeotileToGeoShapeFromStringEvaluator[" + "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 StGeotileToGeoShapeFromStringEvaluator get(DriverContext context) { + return new StGeotileToGeoShapeFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeotileToGeoShapeFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromLongEvaluator.java new file mode 100644 index 0000000000000..7fdf4159a9513 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromLongEvaluator.java @@ -0,0 +1,126 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.LongBlock; +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 StGeotileToLong}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeotileToLongFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeotileToLongFromLongEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendLong(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToLong.fromLong(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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++) { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } + if (valuesAppended == false) { + builder.appendNull(); + } else if (positionOpened) { + builder.endPositionEntry(); + } + } + return builder.build(); + } + } + + private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToLong.fromLong(value); + } + + @Override + public String toString() { + return "StGeotileToLongFromLongEvaluator[" + "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 StGeotileToLongFromLongEvaluator get(DriverContext context) { + return new StGeotileToLongFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeotileToLongFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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/spatial/StGeotileToLongFromStringEvaluator.java new file mode 100644 index 0000000000000..b99abc16e62f8 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongFromStringEvaluator.java @@ -0,0 +1,126 @@ +// 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.BytesRefVector; +import org.elasticsearch.compute.data.LongBlock; +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 StGeotileToLong}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeotileToLongFromStringEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeotileToLongFromStringEvaluator(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) { + BytesRefVector vector = (BytesRefVector) v; + int positionCount = v.getPositionCount(); + BytesRef scratchPad = new BytesRef(); + if (vector.isConstant()) { + return driverContext.blockFactory().newConstantLongBlockWith(evalValue(vector, 0, scratchPad), positionCount); + } + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + for (int p = 0; p < positionCount; p++) { + builder.appendLong(evalValue(vector, p, scratchPad)); + } + return builder.build(); + } + } + + private long evalValue(BytesRefVector container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToLong.fromString(value); + } + + @Override + public Block evalBlock(Block b) { + BytesRefBlock block = (BytesRefBlock) b; + int positionCount = block.getPositionCount(); + try (LongBlock.Builder builder = driverContext.blockFactory().newLongBlockBuilder(positionCount)) { + BytesRef scratchPad = new BytesRef(); + 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++) { + long value = evalValue(block, i, scratchPad); + if (positionOpened == false && valueCount > 1) { + builder.beginPositionEntry(); + positionOpened = true; + } + builder.appendLong(value); + valuesAppended = true; + } + if (valuesAppended == false) { + builder.appendNull(); + } else if (positionOpened) { + builder.endPositionEntry(); + } + } + return builder.build(); + } + } + + private long evalValue(BytesRefBlock container, int index, BytesRef scratchPad) { + BytesRef value = container.getBytesRef(index, scratchPad); + return StGeotileToLong.fromString(value); + } + + @Override + public String toString() { + return "StGeotileToLongFromStringEvaluator[" + "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 StGeotileToLongFromStringEvaluator get(DriverContext context) { + return new StGeotileToLongFromStringEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeotileToLongFromStringEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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/spatial/StGeotileToStringFromLongEvaluator.java new file mode 100644 index 0000000000000..aece0da62cd23 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringFromLongEvaluator.java @@ -0,0 +1,124 @@ +// 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 StGeotileToString}. + * This class is generated. Edit {@code ConvertEvaluatorImplementer} instead. + */ +public final class StGeotileToStringFromLongEvaluator extends AbstractConvertFunction.AbstractEvaluator { + private final EvalOperator.ExpressionEvaluator gridId; + + public StGeotileToStringFromLongEvaluator(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 StGeotileToString.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 StGeotileToString.fromLong(value); + } + + @Override + public String toString() { + return "StGeotileToStringFromLongEvaluator[" + "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 StGeotileToStringFromLongEvaluator get(DriverContext context) { + return new StGeotileToStringFromLongEvaluator(source, gridId.get(context), context); + } + + @Override + public String toString() { + return "StGeotileToStringFromLongEvaluator[" + "gridId=" + gridId + "]"; + } + } +} 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 07990a72e99cc..9866c1fcf899e 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 @@ -363,6 +363,11 @@ public enum Cap { */ ST_ENVELOPE, + /** + * Support ST_GEOHASH, ST_GEOTILE and ST_GEOHEX functions + */ + SPATIAL_GRID, + /** * Fix to GROK and DISSECT that allows extracting attributes with the same name as the input * https://github.com/elastic/elasticsearch/issues/110184 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometry.java new file mode 100644 index 0000000000000..be43f576c7fdd --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometry.java @@ -0,0 +1,227 @@ +/* + * 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.common.spatial; + +import org.apache.lucene.geo.Component2D; +import org.apache.lucene.geo.GeoUtils; +import org.apache.lucene.geo.LatLonGeometry; +import org.apache.lucene.index.PointValues; +import org.apache.lucene.spatial3d.geom.GeoArea; +import org.apache.lucene.spatial3d.geom.GeoAreaFactory; +import org.apache.lucene.spatial3d.geom.GeoPolygon; +import org.apache.lucene.spatial3d.geom.LatLonBounds; +import org.apache.lucene.spatial3d.geom.PlanetModel; +import org.elasticsearch.h3.H3; + +/** + * Implementation of a lucene {@link LatLonGeometry} that covers the extent of a provided H3 bin. + * Note that H3 bin are polygons on the sphere. + * TODO: This class is a copy of the same class in org.elasticsearch.xpack.spatial.common, we should find a common location for it. + */ +class H3SphericalGeometry extends LatLonGeometry { + + private final long h3; + + H3SphericalGeometry(long h3) { + this.h3 = h3; + } + + @Override + protected Component2D toComponent2D() { + return new H3Polygon2D(h3); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof H3SphericalGeometry geom) { + return h3 == geom.h3; + } + return false; + } + + @Override + public int hashCode() { + return Long.hashCode(h3); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("H3 : "); + sb.append("\""); + sb.append(h3); + sb.append("\""); + return sb.toString(); + } + + private static class H3Polygon2D implements Component2D { + + // We want to make are edges a bit bigger because spatial3d and h3 edges do not fully agree in + // membership of points around he edges. + private static final double BBOX_EDGE_DELTA = 1e-4; + private final long h3; + private final int res; + private final GeoPolygon hexagon; + private final double minX, maxX, minY, maxY; + + private H3Polygon2D(long h3) { + this.h3 = h3; + this.res = H3.getResolution(h3); + this.hexagon = H3SphericalUtil.toGeoPolygon(h3); + final LatLonBounds bounds = new LatLonBounds(); + this.hexagon.getBounds(bounds); + final double minY = bounds.checkNoBottomLatitudeBound() ? GeoUtils.MIN_LAT_INCL : Math.toDegrees(bounds.getMinLatitude()); + final double maxY = bounds.checkNoTopLatitudeBound() ? GeoUtils.MAX_LAT_INCL : Math.toDegrees(bounds.getMaxLatitude()); + final double minX; + final double maxX; + if (bounds.checkNoLongitudeBound() || bounds.getLeftLongitude() > bounds.getRightLongitude()) { + minX = GeoUtils.MIN_LON_INCL; + maxX = GeoUtils.MAX_LON_INCL; + } else { + minX = Math.toDegrees(bounds.getLeftLongitude()); + maxX = Math.toDegrees(bounds.getRightLongitude()); + } + // Unfortunately, h3 bin edges are fuzzy and cannot be represented easily. We need to buffer + // the bounding boxes to make sure we don't reject valid points + this.minX = Math.max(GeoUtils.MIN_LON_INCL, minX - BBOX_EDGE_DELTA); + this.maxX = Math.min(GeoUtils.MAX_LON_INCL, maxX + BBOX_EDGE_DELTA); + this.minY = Math.max(GeoUtils.MIN_LAT_INCL, minY - BBOX_EDGE_DELTA); + this.maxY = Math.min(GeoUtils.MAX_LAT_INCL, maxY + BBOX_EDGE_DELTA); + + } + + @Override + public double getMinX() { + return minX; + } + + @Override + public double getMaxX() { + return maxX; + } + + @Override + public double getMinY() { + return minY; + } + + @Override + public double getMaxY() { + return maxY; + } + + @Override + public boolean contains(double x, double y) { + return h3 == H3.geoToH3(y, x, res); + } + + @Override + public PointValues.Relation relate(double minX, double maxX, double minY, double maxY) { + if (minX > this.maxX || maxX < this.minX || maxY < this.minY || minY > this.maxY) { + return PointValues.Relation.CELL_OUTSIDE_QUERY; + } + // h3 edges are fuzzy, therefore to avoid issues when bounding box are around the edges, + // we just buffer slightly the bounding box to check if it is inside the h3 bin, otherwise + // return crosses. + final GeoArea box = GeoAreaFactory.makeGeoArea( + PlanetModel.SPHERE, + Math.toRadians(Math.min(GeoUtils.MAX_LAT_INCL, maxY + BBOX_EDGE_DELTA)), + Math.toRadians(Math.max(GeoUtils.MIN_LAT_INCL, minY - BBOX_EDGE_DELTA)), + Math.toRadians(Math.max(GeoUtils.MIN_LON_INCL, minX - BBOX_EDGE_DELTA)), + Math.toRadians(Math.min(GeoUtils.MAX_LON_INCL, maxX + BBOX_EDGE_DELTA)) + ); + return switch (box.getRelationship(hexagon)) { + case GeoArea.CONTAINS -> PointValues.Relation.CELL_INSIDE_QUERY; + case GeoArea.DISJOINT -> PointValues.Relation.CELL_OUTSIDE_QUERY; + default -> PointValues.Relation.CELL_CROSSES_QUERY; + }; + } + + @Override + public boolean intersectsLine(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY) { + throw new UnsupportedOperationException("intersectsLine not implemented in H3Polygon2D"); + } + + @Override + public boolean intersectsTriangle( + double minX, + double maxX, + double minY, + double maxY, + double aX, + double aY, + double bX, + double bY, + double cX, + double cY + ) { + throw new UnsupportedOperationException("intersectsTriangle not implemented in H3Polygon2D"); + } + + @Override + public boolean containsLine(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY) { + throw new UnsupportedOperationException("containsLine not implemented in H3Polygon2D"); + } + + @Override + public boolean containsTriangle( + double minX, + double maxX, + double minY, + double maxY, + double aX, + double aY, + double bX, + double bY, + double cX, + double cY + ) { + throw new IllegalArgumentException(); + } + + @Override + public WithinRelation withinPoint(double x, double y) { + return contains(x, y) ? WithinRelation.NOTWITHIN : WithinRelation.DISJOINT; + } + + @Override + public WithinRelation withinLine( + double minX, + double maxX, + double minY, + double maxY, + double aX, + double aY, + boolean ab, + double bX, + double bY + ) { + throw new UnsupportedOperationException("withinLine not implemented in H3Polygon2D"); + } + + @Override + public WithinRelation withinTriangle( + double minX, + double maxX, + double minY, + double maxY, + double aX, + double aY, + boolean ab, + double bX, + double bY, + boolean bc, + double cX, + double cY, + boolean ca + ) { + throw new UnsupportedOperationException("withinTriangle not implemented in H3Polygon2D"); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtil.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtil.java new file mode 100644 index 0000000000000..ee63b8cfb18d6 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtil.java @@ -0,0 +1,136 @@ +/* + * 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.common.spatial; + +import org.apache.lucene.geo.LatLonGeometry; +import org.apache.lucene.spatial3d.geom.GeoPoint; +import org.apache.lucene.spatial3d.geom.GeoPolygon; +import org.apache.lucene.spatial3d.geom.GeoPolygonFactory; +import org.apache.lucene.spatial3d.geom.PlanetModel; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.h3.CellBoundary; +import org.elasticsearch.h3.H3; +import org.elasticsearch.h3.LatLng; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiPredicate; + +/** + * Utility class for generating H3 spherical objects. + * TODO: This class is a copy of the same class in org.elasticsearch.xpack.spatial.common, we should find a common location for it. + */ +public final class H3SphericalUtil { + + private static final BiPredicate MIN_COMPARATOR = (e1, e2) -> e1.getLatRad() < e2.getLatRad(); + + private static final BiPredicate MAX_COMPARATOR = (e1, e2) -> e1.getLatRad() > e2.getLatRad(); + + /** + * Computes the bounding box of the provided h3 cell considering edges to be great circles and + * stores then in the provided {@link GeoBoundingBox}. + */ + public static void computeGeoBounds(long h3, GeoBoundingBox boundingBox) { + final CellBoundary boundary = H3.h3ToGeoBoundary(h3); + final int res = H3.getResolution(h3); + if (h3 == H3.northPolarH3(res)) { + // specialize north pole + computeNorthPoleBounds(boundary, boundingBox); + } else if (h3 == H3.southPolarH3(res)) { + // specialize south pole + computeSouthPoleBounds(boundary, boundingBox); + } else { + // generic case + computeBounds(boundary, boundingBox); + } + } + + private static void computeNorthPoleBounds(CellBoundary boundary, GeoBoundingBox boundingBox) { + double minLat = Double.POSITIVE_INFINITY; + for (int i = 0; i < boundary.numPoints(); i++) { + minLat = Math.min(minLat, boundary.getLatLon(i).getLatRad()); + } + boundingBox.topLeft().reset(90, -180d); + boundingBox.bottomRight().reset(Math.toDegrees(minLat), 180d); + } + + private static void computeSouthPoleBounds(CellBoundary boundary, GeoBoundingBox boundingBox) { + double maxLat = Double.NEGATIVE_INFINITY; + for (int i = 0; i < boundary.numPoints(); i++) { + maxLat = Math.max(maxLat, boundary.getLatLon(i).getLatRad()); + } + boundingBox.topLeft().reset(Math.toDegrees(maxLat), -180d); + boundingBox.bottomRight().reset(-90, 180d); + } + + private static void computeBounds(CellBoundary boundary, GeoBoundingBox boundingBox) { + // This algorithm is based on the bounding box for great circle edges in + // https://trs.jpl.nasa.gov/bitstream/handle/2014/41271/07-0286.pdf + double minLat = Double.POSITIVE_INFINITY; + int minLatPos = -1; + double minLon = Double.POSITIVE_INFINITY; + double maxLat = Double.NEGATIVE_INFINITY; + int maxLatPos = -1; + double maxLon = Double.NEGATIVE_INFINITY; + double maxNegLon = Double.NEGATIVE_INFINITY; + double minPosLon = Double.POSITIVE_INFINITY; + for (int i = 0; i < boundary.numPoints(); i++) { + final double lon = boundary.getLatLon(i).getLonRad(); + final double lat = boundary.getLatLon(i).getLatRad(); + if (lat < minLat) { + minLat = lat; + minLatPos = i; + } + if (lat > maxLat) { + maxLat = lat; + maxLatPos = i; + } + minLon = Math.min(minLon, lon); + maxLon = Math.max(maxLon, lon); + if (lon < 0) { + maxNegLon = Math.max(maxNegLon, lon); + } else { + minPosLon = Math.min(minPosLon, lon); + } + } + if (minLat < 0) { + // we only correct the min latitude if negative + minLat = boundary.getLatLon(minLatPos).greatCircleMinLatitude(computeEdge(boundary, minLatPos, MIN_COMPARATOR)); + } + if (maxLat > 0) { + // we only correct the max latitude if positive + maxLat = boundary.getLatLon(maxLatPos).greatCircleMaxLatitude(computeEdge(boundary, maxLatPos, MAX_COMPARATOR)); + } + // the min / max longitude is computed the same way as in cartesian, being careful with polygons crossing the dateline + final boolean crossesDateline = maxLon - minLon > Math.PI; + boundingBox.topLeft().reset(Math.toDegrees(maxLat), crossesDateline ? Math.toDegrees(minPosLon) : Math.toDegrees(minLon)); + boundingBox.bottomRight().reset(Math.toDegrees(minLat), crossesDateline ? Math.toDegrees(maxNegLon) : Math.toDegrees(maxLon)); + } + + private static LatLng computeEdge(CellBoundary boundary, int pos, BiPredicate comparator) { + final LatLng end1 = boundary.getLatLon((pos + 1) % boundary.numPoints()); + final LatLng end2 = boundary.getLatLon(pos == 0 ? boundary.numPoints() - 1 : pos - 1); + return comparator.test(end1, end2) ? end1 : end2; + } + + /** Return the {@link GeoPolygon} representing the provided H3 bin */ + public static GeoPolygon toGeoPolygon(long h3) { + final CellBoundary boundary = H3.h3ToGeoBoundary(h3); + List points = new ArrayList<>(boundary.numPoints()); + for (int i = 0; i < boundary.numPoints(); i++) { + LatLng latLng = boundary.getLatLon(i); + points.add(new GeoPoint(PlanetModel.SPHERE, latLng.getLatRad(), latLng.getLonRad())); + } + return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points); + } + + /** Return the {@link LatLonGeometry} representing the provided H3 bin */ + public static LatLonGeometry getLatLonGeometry(long h3) { + return new H3SphericalGeometry(h3); + } +} 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 4ffa778b8287a..6b520ee4c034d 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 @@ -58,6 +58,18 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialWithin; 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.StGeohashToGeoShape; +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.StGeohexToGeoShape; +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.StGeotileToGeoShape; +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; @@ -212,7 +224,25 @@ public static List unaryScalars() { } private static List spatials() { - return List.of(SpatialContains.ENTRY, SpatialDisjoint.ENTRY, SpatialIntersects.ENTRY, SpatialWithin.ENTRY, StDistance.ENTRY); + return List.of( + SpatialContains.ENTRY, + SpatialDisjoint.ENTRY, + SpatialIntersects.ENTRY, + SpatialWithin.ENTRY, + StDistance.ENTRY, + StGeohash.ENTRY, + StGeohashToString.ENTRY, + StGeohashToLong.ENTRY, + StGeohashToGeoShape.ENTRY, + StGeotile.ENTRY, + StGeotileToString.ENTRY, + StGeotileToLong.ENTRY, + StGeotileToGeoShape.ENTRY, + StGeohex.ENTRY, + StGeohexToString.ENTRY, + StGeohexToLong.ENTRY, + StGeohexToGeoShape.ENTRY + ); } private static List arithmetics() { 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 b2d85d809c058..95d2b284152df 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 @@ -131,6 +131,18 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialWithin; 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.StGeohashToGeoShape; +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.StGeohexToGeoShape; +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.StGeotileToGeoShape; +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; @@ -380,7 +392,19 @@ 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(StY.class, StY::new, "st_y"), + def(StGeohash.class, StGeohash::new, "st_geohash"), + def(StGeohashToGeoShape.class, StGeohashToGeoShape::new, "st_geohash_to_geoshape"), + 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(StGeotileToGeoShape.class, StGeotileToGeoShape::new, "st_geotile_to_geoshape"), + 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(StGeohexToGeoShape.class, StGeohexToGeoShape::new, "st_geohex_to_geoshape"), + def(StGeohexToLong.class, StGeohexToLong::new, "st_geohex_to_long"), + def(StGeohexToString.class, StGeohexToString::new, "st_geohex_to_string") }, // conditional new FunctionDefinition[] { def(Case.class, Case::new, "case") }, // null diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java index 3b869c0200cb9..cdd55ca24d86f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java @@ -100,7 +100,7 @@ static String supportedTypesNames(Set types) { } @FunctionalInterface - interface BuildFactory { + public interface BuildFactory { ExpressionEvaluator.Factory build(Source source, ExpressionEvaluator.Factory field); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/GeoHexBoundedPredicate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/GeoHexBoundedPredicate.java new file mode 100644 index 0000000000000..500a218e956f9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/GeoHexBoundedPredicate.java @@ -0,0 +1,47 @@ +/* + * 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.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.xpack.esql.common.spatial.H3SphericalUtil; + +/** + * A class that checks if a hexagon intersects with a bounding box. + * TODO: This class is a copy of the inner class GeoHexPredicate inside GeoHexCellIdSource, we should find a common location for it. + */ +public class GeoHexBoundedPredicate { + + private final boolean crossesDateline; + private final GeoBoundingBox bbox, scratch; + + GeoHexBoundedPredicate(GeoBoundingBox bbox) { + this.crossesDateline = bbox.right() < bbox.left(); + this.bbox = bbox; + scratch = new GeoBoundingBox(new org.elasticsearch.common.geo.GeoPoint(), new org.elasticsearch.common.geo.GeoPoint()); + } + + public boolean validHex(long hex) { + H3SphericalUtil.computeGeoBounds(hex, scratch); + if (bbox.top() > scratch.bottom() && bbox.bottom() < scratch.top()) { + if (scratch.left() > scratch.right()) { + return intersects(-180, scratch.right()) || intersects(scratch.left(), 180); + } else { + return intersects(scratch.left(), scratch.right()); + } + } + return false; + } + + private boolean intersects(double minLon, double maxLon) { + if (crossesDateline) { + return bbox.left() < maxLon || bbox.right() > minLon; + } else { + return bbox.left() < maxLon && bbox.right() > minLon; + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunction.java new file mode 100644 index 0000000000000..a6b91599fcb99 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunction.java @@ -0,0 +1,353 @@ +/* + * 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.geo.GeoBoundingBox; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.Rectangle; +import org.elasticsearch.geometry.utils.SpatialEnvelopeVisitor; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.function.scalar.ScalarFunction; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.util.PlanStreamInput; +import org.elasticsearch.xpack.esql.expression.function.OptionalArgument; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.THIRD; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isWholeNumber; +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.util.SpatialCoordinateTypes.GEO; + +/** + * Spatial functions that take one spatial argument, one parameter and one optional bounds can inherit from this class. + * Obvious choices are: StGeohash, StGeotile and StGeohex. + */ +public abstract class SpatialGridFunction extends ScalarFunction implements OptionalArgument { + protected final Expression spatialField; + protected final Expression parameter; + protected final Expression bounds; + protected final boolean spatialDocsValues; + + protected SpatialGridFunction( + Source source, + Expression spatialField, + Expression parameter, + Expression bounds, + boolean spatialDocsValues + ) { + super(source, bounds == null ? Arrays.asList(spatialField, parameter) : Arrays.asList(spatialField, parameter, bounds)); + this.spatialField = spatialField; + this.parameter = parameter; + this.bounds = bounds; + this.spatialDocsValues = spatialDocsValues; + } + + protected SpatialGridFunction(StreamInput in, boolean spatialDocsValues) throws IOException { + this( + Source.readFrom((StreamInput & PlanStreamInput) in), + in.readNamedWriteable(Expression.class), + in.readNamedWriteable(Expression.class), + in.readOptionalNamedWriteable(Expression.class), + spatialDocsValues + ); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + source().writeTo(out); + out.writeNamedWriteable(spatialField); + out.writeNamedWriteable(parameter); + out.writeOptionalNamedWriteable(bounds); + } + + /** + * Mark the function as expecting the specified field to arrive as doc-values. + * This only applies to geo_point and cartesian_point types. + */ + public abstract SpatialGridFunction withDocValues(boolean useDocValues); + + @Override + protected TypeResolution resolveType() { + if (childrenResolved() == false) { + return new TypeResolution("Unresolved children"); + } + + TypeResolution resolution = isGeoPoint(spatialField(), sourceText()); + if (resolution.unresolved()) { + return resolution; + } + + resolution = isWholeNumber(parameter(), sourceText(), SECOND); + if (resolution.unresolved()) { + return resolution; + } + + if (bounds() != null) { + resolution = isGeo(bounds(), sourceText()); + if (resolution.unresolved()) { + return resolution; + } + } + + return TypeResolution.TYPE_RESOLVED; + } + + protected static Expression.TypeResolution isGeoPoint(Expression e, String operationName) { + return isType(e, t -> t.equals(GEO_POINT), operationName, FIRST, GEO_POINT.typeName()); + } + + protected static Expression.TypeResolution isGeo(Expression e, String operationName) { + return isType(e, t -> t.equals(GEO_SHAPE) || t.equals(GEO_POINT), operationName, THIRD, GEO_SHAPE.typeName(), GEO_POINT.typeName()); + } + + protected static Rectangle asRectangle(BytesRef boundsBytesRef) { + var geometry = GEO.wkbToGeometry(boundsBytesRef); + if (geometry instanceof Rectangle rectangle) { + return rectangle; + } + var envelope = SpatialEnvelopeVisitor.visitGeo(geometry, SpatialEnvelopeVisitor.WrapLongitude.WRAP); + if (envelope.isPresent()) { + return envelope.get(); + } + throw new IllegalArgumentException("Cannot determine envelope of bounds geometry"); + } + + protected static Rectangle asRectangle(List list) { + var visitor = new SpatialEnvelopeVisitor(new SpatialEnvelopeVisitor.GeoPointVisitor(SpatialEnvelopeVisitor.WrapLongitude.WRAP)); + for (Object o : list) { + if (o instanceof BytesRef bytesRef) { + var geometry = GEO.wkbToGeometry(bytesRef); + geometry.visit(visitor); + } else { + throw new IllegalArgumentException("Cannot determine envelope of bounds geometry of type " + o.getClass().getSimpleName()); + } + } + return visitor.getResult(); + } + + protected static GeoBoundingBox asGeoBoundingBox(Object bounds) { + if (bounds instanceof BytesRef boundsBytesRef) { + return asGeoBoundingBox(asRectangle(boundsBytesRef)); + } else if (bounds instanceof List list) { + return asGeoBoundingBox(asRectangle(list)); + } + throw new IllegalArgumentException("Cannot determine envelope of bounds geometry of type " + bounds.getClass().getSimpleName()); + } + + protected static GeoBoundingBox asGeoBoundingBox(Rectangle rectangle) { + return new GeoBoundingBox( + new GeoPoint(rectangle.getMaxLat(), rectangle.getMinLon()), + new GeoPoint(rectangle.getMinLat(), rectangle.getMaxLon()) + ); + } + + protected static boolean inBounds(Point point, Rectangle bounds) { + // TODO: consider bounds across the dateline + return point.getX() >= bounds.getMinX() + && point.getY() >= bounds.getMinY() + && point.getX() <= bounds.getMaxX() + && point.getY() <= bounds.getMaxY(); + } + + @Override + public int hashCode() { + // NB: the hashcode is currently used for key generation so + // to avoid clashes between aggs with the same arguments, add the class name as variation + return Objects.hash(getClass(), children(), spatialDocsValues); + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + SpatialGridFunction other = (SpatialGridFunction) obj; + return Objects.equals(other.children(), children()) && Objects.equals(other.spatialDocsValues, spatialDocsValues); + } + return false; + } + + public boolean spatialDocsValues() { + return spatialDocsValues; + } + + @Override + public final SpatialGridFunction replaceChildren(List newChildren) { + Expression newSpatialField = newChildren.get(0); + Expression newParameter = newChildren.get(1); + Expression newBounds = newChildren.size() > 2 ? newChildren.get(2) : null; + + return spatialField.equals(newSpatialField) + && parameter.equals(newParameter) + && (bounds == null && newBounds == null || bounds != null && bounds.equals(newBounds)) + ? this + : replaceChildren(newSpatialField, newParameter, newBounds); + } + + protected abstract SpatialGridFunction replaceChildren(Expression newSpatialField, Expression newParameter, Expression newBounds); + + public Expression spatialField() { + return spatialField; + } + + public Expression parameter() { + return parameter; + } + + public Expression bounds() { + return bounds; + } + + @Override + public boolean foldable() { + return spatialField.foldable() && parameter.foldable() && (bounds == null || bounds.foldable()); + } + + protected static void addGrids(LongBlock.Builder results, List gridIds) { + if (gridIds.isEmpty()) { + results.appendNull(); + } else if (gridIds.size() == 1) { + results.appendLong(gridIds.getFirst()); + } else { + results.beginPositionEntry(); + for (long gridId : gridIds) { + results.appendLong(gridId); + } + results.endPositionEntry(); + } + } + + protected interface UnboundedGrid { + long calculateGridId(Point point, int precision); + } + + protected interface BoundedGrid { + long calculateGridId(Point point); + + int precision(); + } + + protected static void fromWKB( + LongBlock.Builder results, + int position, + BytesRefBlock wkbBlock, + int precision, + UnboundedGrid unboundedGrid + ) { + int valueCount = wkbBlock.getValueCount(position); + if (valueCount < 1) { + results.appendNull(); + } else { + final BytesRef scratch = new BytesRef(); + final int firstValueIndex = wkbBlock.getFirstValueIndex(position); + if (valueCount == 1) { + results.appendLong( + unboundedGrid.calculateGridId(GEO.wkbAsPoint(wkbBlock.getBytesRef(firstValueIndex, scratch)), precision) + ); + } else { + results.beginPositionEntry(); + for (int i = 0; i < valueCount; i++) { + results.appendLong( + unboundedGrid.calculateGridId(GEO.wkbAsPoint(wkbBlock.getBytesRef(firstValueIndex + i, scratch)), precision) + ); + } + results.endPositionEntry(); + } + } + } + + protected static void fromEncodedLong( + LongBlock.Builder results, + int position, + LongBlock encoded, + int precision, + UnboundedGrid unboundedGrid + ) { + int valueCount = encoded.getValueCount(position); + if (valueCount < 1) { + results.appendNull(); + } else { + final int firstValueIndex = encoded.getFirstValueIndex(position); + if (valueCount == 1) { + results.appendLong(unboundedGrid.calculateGridId(GEO.longAsPoint(encoded.getLong(firstValueIndex)), precision)); + } else { + results.beginPositionEntry(); + for (int i = 0; i < valueCount; i++) { + results.appendLong(unboundedGrid.calculateGridId(GEO.longAsPoint(encoded.getLong(firstValueIndex + i)), precision)); + } + results.endPositionEntry(); + } + } + } + + protected static void fromWKB(LongBlock.Builder results, int position, BytesRefBlock wkbBlock, BoundedGrid bounds) { + int valueCount = wkbBlock.getValueCount(position); + if (valueCount < 1) { + results.appendNull(); + } else { + final BytesRef scratch = new BytesRef(); + final int firstValueIndex = wkbBlock.getFirstValueIndex(position); + if (valueCount == 1) { + long grid = bounds.calculateGridId(GEO.wkbAsPoint(wkbBlock.getBytesRef(firstValueIndex, scratch))); + if (grid < 0) { + results.appendNull(); + } else { + results.appendLong(grid); + } + } else { + var gridIds = new ArrayList(valueCount); + for (int i = 0; i < valueCount; i++) { + var grid = bounds.calculateGridId(GEO.wkbAsPoint(wkbBlock.getBytesRef(firstValueIndex + i, scratch))); + if (grid >= 0) { + gridIds.add(grid); + } + } + addGrids(results, gridIds); + } + } + } + + protected static void fromEncodedLong(LongBlock.Builder results, int position, LongBlock encoded, BoundedGrid bounds) { + int valueCount = encoded.getValueCount(position); + if (valueCount < 1) { + results.appendNull(); + } else { + final int firstValueIndex = encoded.getFirstValueIndex(position); + if (valueCount == 1) { + long grid = bounds.calculateGridId(GEO.longAsPoint(encoded.getLong(firstValueIndex))); + if (grid < 0) { + results.appendNull(); + } else { + results.appendLong(grid); + } + } else { + var gridIds = new ArrayList(valueCount); + for (int i = 0; i < valueCount; i++) { + var grid = bounds.calculateGridId(GEO.longAsPoint(encoded.getLong(firstValueIndex + i))); + if (grid >= 0) { + gridIds.add(grid); + } + } + addGrids(results, gridIds); + } + } + } +} 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 new file mode 100644 index 0000000000000..174f5f9b25207 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohash.java @@ -0,0 +1,297 @@ +/* + * 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.geo.GeoBoundingBox; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.ann.Fixed; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.geometry.utils.Geohash; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoHashBoundedPredicate; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +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 java.io.IOException; + +import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; + +/** + * Calculates the geohash of geo_point geometries. + */ +public class StGeohash extends SpatialGridFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeohash", + StGeohash::new + ); + + /** + * When checking grid cells with bounds, we need to check if the cell is valid (intersects with the bounds). + * This uses GeoHashBoundedPredicate to check if the grid cell is valid. + */ + protected static class GeoHashBoundedGrid implements BoundedGrid { + private final int precision; + private final GeoHashBoundedPredicate bounds; + + public GeoHashBoundedGrid(int precision, GeoBoundingBox bbox) { + this.precision = checkPrecisionRange(precision); + this.bounds = new GeoHashBoundedPredicate(precision, bbox); + } + + public long calculateGridId(Point point) { + String geohash = Geohash.stringEncode(point.getX(), point.getY(), precision); + if (bounds.validHash(geohash)) { + return Geohash.longEncode(geohash); + } + // TODO: Are negative values allowed in geohash long encoding? + return -1; + } + + @Override + public int precision() { + return precision; + } + } + + /** + * For unbounded grids, we don't need to check if the grid cell is valid, + * just calculate the encoded long intersecting the point at that precision. + */ + protected static final UnboundedGrid unboundedGrid = (point, precision) -> Geohash.longEncode( + point.getX(), + point.getY(), + checkPrecisionRange(precision) + ); + + private static int checkPrecisionRange(int precision) { + if (precision < 1 || precision > Geohash.PRECISION) { + throw new IllegalArgumentException( + "Invalid geohash precision of " + precision + ". Must be between 1 and " + Geohash.PRECISION + "." + ); + } + return precision; + } + + @FunctionInfo( + returnType = "long", + 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. + Or use [ST_GEOHASH_TO_GEOSHAPE](#esql-st_geohash_to_geoshape) to convert either the long or string `geohash` to a + + These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) + and the [`geohash_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohashgrid-aggregation).""", + examples = @Example(file = "spatial-grid", tag = "st_geohash-grid") + ) + public StGeohash( + Source source, + @Param( + name = "geometry", + type = { "geo_point" }, + description = "Expression of type `geo_point`. If `null`, the function returns `null`." + ) 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, + @Param(name = "bounds", type = { "geo_shape", "geo_point" }, description = """ + Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. + The envelope of the `geo_shape` is used as bounds.""", optional = true) Expression bounds + ) { + this(source, field, precision, bounds, false); + } + + private StGeohash(Source source, Expression field, Expression precision, Expression bounds, boolean spatialDocValues) { + super(source, field, precision, bounds, spatialDocValues); + } + + private StGeohash(StreamInput in) throws IOException { + super(in, false); + } + + @Override + public SpatialGridFunction withDocValues(boolean useDocValues) { + // Only update the docValues flags if the field is found in the attributes + boolean docValues = this.spatialDocsValues || useDocValues; + return new StGeohash(source(), spatialField, parameter, bounds, docValues); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + protected SpatialGridFunction replaceChildren(Expression newSpatialField, Expression newParameter, Expression newBounds) { + return new StGeohash(source(), newSpatialField, newParameter, newBounds); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohash::new, spatialField, parameter, bounds); + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + if (bounds != null) { + if (bounds.foldable() == false) { + throw new IllegalArgumentException("bounds must be foldable"); + } + GeoBoundingBox bbox = asGeoBoundingBox(bounds.fold(toEvaluator.foldCtx())); + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeohashFromLiteralAndFieldAndLiteralEvaluator.Factory(source(), point, toEvaluator.apply(parameter()), bbox); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = (int) parameter.fold(toEvaluator.foldCtx()); + GeoHashBoundedGrid bounds = new GeoHashBoundedGrid(precision, bbox); + return spatialDocsValues + ? new StGeohashFromFieldDocValuesAndLiteralAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField()), + bounds + ) + : new StGeohashFromFieldAndLiteralAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), bounds); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeohashFromFieldDocValuesAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ) + : new StGeohashFromFieldAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ); + } + } else { + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeohashFromLiteralAndFieldEvaluator.Factory(source(), point, toEvaluator.apply(parameter())); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = checkPrecisionRange((int) parameter.fold(toEvaluator.foldCtx())); + return spatialDocsValues + ? new StGeohashFromFieldDocValuesAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField()), precision) + : new StGeohashFromFieldAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), precision); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeohashFromFieldDocValuesAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ) + : new StGeohashFromFieldAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ); + } + } + } + + @Override + public Object fold(FoldContext ctx) { + var point = (BytesRef) spatialField().fold(ctx); + int precision = (int) parameter().fold(ctx); + if (bounds() == null) { + return fromLiteralAndField(point, precision); + } else { + return fromLiteralAndFieldAndLiteral(point, precision, asGeoBoundingBox((BytesRef) bounds().fold(ctx))); + } + } + + @Evaluator(extraName = "FromFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock wkbBlock, @Fixed int precision) { + fromWKB(results, p, wkbBlock, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteral(LongBlock.Builder results, int p, LongBlock encoded, @Fixed int precision) { + fromEncodedLong(results, p, encoded, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndField(LongBlock.Builder results, int p, BytesRefBlock in, int precision) { + fromWKB(results, p, in, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndField(LongBlock.Builder results, int p, LongBlock encoded, int precision) { + fromEncodedLong(results, p, encoded, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromLiteralAndField", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndField(@Fixed BytesRef in, int precision) { + return unboundedGrid.calculateGridId(GEO.wkbAsPoint(in), precision); + } + + @Evaluator(extraName = "FromFieldAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteralAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, @Fixed GeoHashBoundedGrid bounds) { + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteralAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + @Fixed GeoHashBoundedGrid bounds + ) { + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromFieldAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, int precision, @Fixed GeoBoundingBox bbox) { + GeoHashBoundedGrid bounds = new GeoHashBoundedGrid(precision, bbox); + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndFieldAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + int precision, + @Fixed GeoBoundingBox bbox + ) { + GeoHashBoundedGrid bounds = new GeoHashBoundedGrid(precision, bbox); + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromLiteralAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndFieldAndLiteral(@Fixed BytesRef in, int precision, @Fixed GeoBoundingBox bbox) { + GeoHashBoundedGrid bounds = new GeoHashBoundedGrid(precision, bbox); + return bounds.calculateGridId(GEO.wkbAsPoint(in)); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShape.java new file mode 100644 index 0000000000000..b205ca194dbc9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShape.java @@ -0,0 +1,103 @@ +/* + * 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.GEO_SHAPE; +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.expression.function.scalar.spatial.StGeotileToGeoShape.fromRectangle; + +public class StGeohashToGeoShape extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeohashToGeoShape", + StGeohashToGeoShape::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(KEYWORD, StGeohashToGeoShapeFromStringEvaluator.Factory::new), + Map.entry(LONG, StGeohashToGeoShapeFromLongEvaluator.Factory::new) + ); + + @FunctionInfo( + returnType = "geo_shape", + description = """ + Converts an input value to a `geo_shape` value. + The input values are expected to be the grid-ids of geohash grids, in either long or string format.""", + examples = @Example(file = "spatial-grid", tag = "geohash_to_geoshape"), + depthOffset = 1 // make it appear as a subsection of ST_GEOHASH + ) + public StGeohashToGeoShape( + 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 StGeohashToGeoShape(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return GEO_SHAPE; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeohashToGeoShape(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohashToGeoShape::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static BytesRef fromString(BytesRef gridId) { + return fromRectangle(Geohash.toBoundingBox(gridId.utf8ToString())); + } + + @ConvertEvaluator(extraName = "FromLong") + static BytesRef fromLong(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/StGeohashToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLong.java new file mode 100644 index 0000000000000..717dfea9724ec --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLong.java @@ -0,0 +1,94 @@ +/* + * 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 StGeohashToLong extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeohashToLong", + StGeohashToLong::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(LONG, (source, fieldEval) -> fieldEval), + Map.entry(KEYWORD, StGeohashToLongFromStringEvaluator.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( + 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 StGeohashToLong(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeohashToLong(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohashToLong::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static long fromString(BytesRef gridId) { + return Geohash.longEncode(gridId.utf8ToString()); + } +} 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 new file mode 100644 index 0000000000000..d3c6f7697e0c9 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToString.java @@ -0,0 +1,94 @@ +/* + * 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 new file mode 100644 index 0000000000000..cbd16c4c461aa --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohex.java @@ -0,0 +1,294 @@ +/* + * 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.geo.GeoBoundingBox; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.ann.Fixed; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.h3.H3; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +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 java.io.IOException; + +import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; + +/** + * Calculates the geohex of geo_point geometries. + */ +public class StGeohex extends SpatialGridFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "StGeohex", StGeohex::new); + + /** + * When checking grid cells with bounds, we need to check if the cell is valid (intersects with the bounds). + * This uses GeoHexBoundedPredicate to check if the cell is valid. + */ + protected static class GeoHexBoundedGrid implements BoundedGrid { + private final int precision; + private final GeoHexBoundedPredicate bounds; + + public GeoHexBoundedGrid(int precision, GeoBoundingBox bbox) { + this.precision = checkPrecisionRange(precision); + this.bounds = new GeoHexBoundedPredicate(bbox); + } + + public long calculateGridId(Point point) { + // For points, filtering the point is as good as filtering the tile + long geohex = H3.geoToH3(point.getLat(), point.getLon(), precision); + if (bounds.validHex(geohex)) { + return geohex; + } + // TODO: Are we sure negative numbers are not valid + return -1L; + } + + @Override + public int precision() { + return precision; + } + } + + /** + * For unbounded grids, we don't need to check if the tile is valid, + * just calculate the encoded long intersecting the point at that precision. + */ + protected static final UnboundedGrid unboundedGrid = (point, precision) -> H3.geoToH3( + point.getLat(), + point.getLon(), + checkPrecisionRange(precision) + ); + + private static int checkPrecisionRange(int precision) { + if (precision < 1 || precision > H3.MAX_H3_RES) { + throw new IllegalArgumentException( + "Invalid geohex precision of " + precision + ". Must be between 0 and " + H3.MAX_H3_RES + "." + ); + } + return precision; + } + + @FunctionInfo( + returnType = "long", + 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. + Or use [ST_GEOHEX_TO_GEOSHAPE](#esql-st_geohex_to_geoshape) to convert either the long or string `geohex` to a + POLYGON geo_shape. + + These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) + and the [`geohex_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geohexgrid-aggregation).""", + examples = @Example(file = "spatial-grid", tag = "st_geohex-grid") + ) + public StGeohex( + Source source, + @Param( + name = "geometry", + type = { "geo_point" }, + description = "Expression of type `geo_point`. If `null`, the function returns `null`." + ) Expression field, + @Param(name = "precision", type = { "integer" }, description = """ + Expression of type `integer`. If `null`, the function returns `null`. + Valid values are between [0 and 15](https://h3geo.org/docs/core-library/restable/).""") Expression precision, + @Param(name = "bounds", type = { "geo_shape", "geo_point" }, description = """ + Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. + The envelope of the `geo_shape` is used as bounds.""", optional = true) Expression bounds + ) { + this(source, field, precision, bounds, false); + } + + private StGeohex(Source source, Expression field, Expression precision, Expression bounds, boolean spatialDocValues) { + super(source, field, precision, bounds, spatialDocValues); + } + + private StGeohex(StreamInput in) throws IOException { + super(in, false); + } + + @Override + public SpatialGridFunction withDocValues(boolean useDocValues) { + // Only update the docValues flags if the field is found in the attributes + boolean docValues = this.spatialDocsValues || useDocValues; + return new StGeohex(source(), spatialField, parameter, bounds, docValues); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + protected SpatialGridFunction replaceChildren(Expression newSpatialField, Expression newParameter, Expression newBounds) { + return new StGeohex(source(), newSpatialField, newParameter, newBounds); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohex::new, spatialField, parameter, bounds); + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + if (bounds != null) { + if (bounds.foldable() == false) { + throw new IllegalArgumentException("bounds must be foldable"); + } + GeoBoundingBox bbox = asGeoBoundingBox(bounds.fold(toEvaluator.foldCtx())); + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeohexFromLiteralAndFieldAndLiteralEvaluator.Factory(source(), point, toEvaluator.apply(parameter()), bbox); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = (int) parameter.fold(toEvaluator.foldCtx()); + GeoHexBoundedGrid bounds = new GeoHexBoundedGrid(precision, bbox); + return spatialDocsValues + ? new StGeohexFromFieldDocValuesAndLiteralAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField()), + bounds + ) + : new StGeohexFromFieldAndLiteralAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), bounds); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeohexFromFieldDocValuesAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ) + : new StGeohexFromFieldAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ); + } + } else { + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeohexFromLiteralAndFieldEvaluator.Factory(source(), point, toEvaluator.apply(parameter())); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = checkPrecisionRange((int) parameter.fold(toEvaluator.foldCtx())); + return spatialDocsValues + ? new StGeohexFromFieldDocValuesAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField()), precision) + : new StGeohexFromFieldAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), precision); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeohexFromFieldDocValuesAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ) + : new StGeohexFromFieldAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ); + } + } + } + + @Override + public Object fold(FoldContext ctx) { + var point = (BytesRef) spatialField().fold(ctx); + int precision = checkPrecisionRange((int) parameter().fold(ctx)); + if (bounds() == null) { + return fromLiteralAndField(point, precision); + } else { + return fromLiteralAndFieldAndLiteral(point, precision, asGeoBoundingBox((BytesRef) bounds().fold(ctx))); + } + } + + @Evaluator(extraName = "FromFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock wkbBlock, @Fixed int precision) { + fromWKB(results, p, wkbBlock, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteral(LongBlock.Builder results, int p, LongBlock encoded, @Fixed int precision) { + fromEncodedLong(results, p, encoded, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndField(LongBlock.Builder results, int p, BytesRefBlock in, int precision) { + fromWKB(results, p, in, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndField(LongBlock.Builder results, int p, LongBlock encoded, int precision) { + fromEncodedLong(results, p, encoded, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromLiteralAndField", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndField(@Fixed BytesRef in, int precision) { + return unboundedGrid.calculateGridId(GEO.wkbAsPoint(in), precision); + } + + @Evaluator(extraName = "FromFieldAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteralAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, @Fixed GeoHexBoundedGrid bounds) { + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteralAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + @Fixed GeoHexBoundedGrid bounds + ) { + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromFieldAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, int precision, @Fixed GeoBoundingBox bbox) { + GeoHexBoundedGrid bounds = new GeoHexBoundedGrid(precision, bbox); + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndFieldAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + int precision, + @Fixed GeoBoundingBox bbox + ) { + GeoHexBoundedGrid bounds = new GeoHexBoundedGrid(precision, bbox); + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromLiteralAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndFieldAndLiteral(@Fixed BytesRef in, int precision, @Fixed GeoBoundingBox bbox) { + GeoHexBoundedGrid bounds = new GeoHexBoundedGrid(precision, bbox); + return bounds.calculateGridId(GEO.wkbAsPoint(in)); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShape.java new file mode 100644 index 0000000000000..816fadb6061c2 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShape.java @@ -0,0 +1,122 @@ +/* + * 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.LinearRing; +import org.elasticsearch.geometry.Polygon; +import org.elasticsearch.h3.CellBoundary; +import org.elasticsearch.h3.H3; +import org.elasticsearch.h3.LatLng; +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.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; +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.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; +import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; + +public class StGeohexToGeoShape extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeohexToGeoShape", + StGeohexToGeoShape::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(KEYWORD, StGeohexToGeoShapeFromStringEvaluator.Factory::new), + Map.entry(LONG, StGeohexToGeoShapeFromLongEvaluator.Factory::new) + ); + + @FunctionInfo( + returnType = "geo_shape", + description = """ + Converts an input value to a `geo_shape` value. + The input values are expected to be the grid-ids of H3 grids, in either long or string format.""", + examples = @Example(file = "spatial-grid", tag = "geohex_to_geoshape"), + depthOffset = 1 // make it appear as a subsection of ST_GEOHEX + ) + public StGeohexToGeoShape( + Source source, + @Param( + name = "grid_id", + type = { "keyword", "long" }, + description = "Input H3 grid-id. The input can be a single- or multi-valued column or an expression." + ) Expression v + ) { + super(source, v); + } + + private StGeohexToGeoShape(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return GEO_SHAPE; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeohexToGeoShape(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohexToGeoShape::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static BytesRef fromString(BytesRef gridId) { + return fromCellBoundary(H3.h3ToGeoBoundary(gridId.utf8ToString())); + } + + @ConvertEvaluator(extraName = "FromLong") + static BytesRef fromLong(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/StGeohexToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLong.java new file mode 100644 index 0000000000000..abb357a683109 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLong.java @@ -0,0 +1,94 @@ +/* + * 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 StGeohexToLong extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeohexToLong", + StGeohexToLong::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(LONG, (source, fieldEval) -> fieldEval), + Map.entry(KEYWORD, StGeohexToLongFromStringEvaluator.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( + 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 StGeohexToLong(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeohexToLong(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeohexToLong::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static long fromString(BytesRef gridId) { + return H3.stringToH3(gridId.utf8ToString()); + } +} 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 new file mode 100644 index 0000000000000..9632fe983a66b --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToString.java @@ -0,0 +1,94 @@ +/* + * 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 new file mode 100644 index 0000000000000..231191d7485e2 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotile.java @@ -0,0 +1,292 @@ +/* + * 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.geo.GeoBoundingBox; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.ann.Fixed; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileBoundedPredicate; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +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 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.util.SpatialCoordinateTypes.GEO; + +/** + * Calculates the geotile of geo_point geometries. + */ +public class StGeotile extends SpatialGridFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeotile", + StGeotile::new + ); + + /** + * When checking tiles with bounds, we need to check if the tile is valid (intersects with the bounds). + * This uses GeoTileBoundedPredicate to check if the tile is valid. + */ + protected static class GeoTileBoundedGrid implements BoundedGrid { + private final int precision; + private final GeoTileBoundedPredicate bounds; + + public GeoTileBoundedGrid(int precision, GeoBoundingBox bbox) { + this.precision = checkPrecisionRange(precision); + this.bounds = new GeoTileBoundedPredicate(precision, bbox); + } + + public long calculateGridId(Point point) { + final int tiles = 1 << precision; + final int x = GeoTileUtils.getXTile(point.getX(), tiles); + final int y = GeoTileUtils.getYTile(point.getY(), tiles); + if (bounds.validTile(x, y, precision)) { + return GeoTileUtils.longEncodeTiles(precision, x, y); + } + // TODO: Are we sure negative numbers are not valid + return -1L; + } + + @Override + public int precision() { + return precision; + } + } + + /** + * For unbounded grids, we don't need to check if the tile is valid, + * just calculate the encoded long intersecting the point at that precision. + */ + protected static final UnboundedGrid unboundedGrid = (point, precision) -> GeoTileUtils.longEncode( + point.getX(), + point.getY(), + checkPrecisionRange(precision) + ); + + @FunctionInfo( + returnType = "long", + 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. + Or use [ST_GEOTILE_TO_GEOSHAPE](#esql-st_geotile_to_geoshape) to convert either the long or string `geotile` to a + POLYGON geo_shape. + + These functions are related to the [`geo_grid` query](/reference/query-languages/query-dsl/query-dsl-geo-grid-query) + and the [`geotile_grid` aggregation](/reference/aggregations/search-aggregations-bucket-geotilegrid-aggregation).""", + examples = @Example(file = "spatial-grid", tag = "st_geotile-grid") + ) + public StGeotile( + Source source, + @Param( + name = "geometry", + type = { "geo_point" }, + description = "Expression of type `geo_point`. If `null`, the function returns `null`." + ) Expression field, + @Param(name = "precision", type = { "integer" }, description = """ + Expression of type `integer`. If `null`, the function returns `null`. + Valid values are between [0 and 29](https://wiki.openstreetmap.org/wiki/Zoom_levels).""") Expression precision, + @Param(name = "bounds", type = { "geo_shape", "geo_point" }, description = """ + Optional bounds to filter the grid tiles, either a `geo_shape` or an array of at least two `geo_point`s. + The envelope of the `geo_shape` is used as bounds.""", optional = true) Expression bounds + ) { + this(source, field, precision, bounds, false); + } + + private StGeotile(Source source, Expression field, Expression precision, Expression bounds, boolean spatialDocValues) { + super(source, field, precision, bounds, spatialDocValues); + } + + private StGeotile(StreamInput in) throws IOException { + super(in, false); + } + + @Override + public SpatialGridFunction withDocValues(boolean useDocValues) { + // Only update the docValues flags if the field is found in the attributes + boolean docValues = this.spatialDocsValues || useDocValues; + return new StGeotile(source(), spatialField, parameter, bounds, docValues); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + protected SpatialGridFunction replaceChildren(Expression newSpatialField, Expression newParameter, Expression newBounds) { + return new StGeotile(source(), newSpatialField, newParameter, newBounds); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeotile::new, spatialField, parameter, bounds); + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + if (bounds != null) { + if (bounds.foldable() == false) { + throw new IllegalArgumentException("bounds must be foldable"); + } + GeoBoundingBox bbox = asGeoBoundingBox(bounds.fold(toEvaluator.foldCtx())); + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeotileFromLiteralAndFieldAndLiteralEvaluator.Factory(source(), point, toEvaluator.apply(parameter()), bbox); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = (int) parameter.fold(toEvaluator.foldCtx()); + GeoTileBoundedGrid bounds = new GeoTileBoundedGrid(precision, bbox); + return spatialDocsValues + ? new StGeotileFromFieldDocValuesAndLiteralAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField()), + bounds + ) + : new StGeotileFromFieldAndLiteralAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), bounds); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeotileFromFieldDocValuesAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ) + : new StGeotileFromFieldAndFieldAndLiteralEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter), + bbox + ); + } + } else { + if (spatialField().foldable()) { + // Assume right is not foldable, since that would be dealt with in isFoldable() and fold() + var point = (BytesRef) spatialField.fold(toEvaluator.foldCtx()); + return new StGeotileFromLiteralAndFieldEvaluator.Factory(source(), point, toEvaluator.apply(parameter())); + } else if (parameter().foldable()) { + // Assume left is not foldable, since that would be dealt with in isFoldable() and fold() + int precision = checkPrecisionRange((int) parameter.fold(toEvaluator.foldCtx())); + return spatialDocsValues + ? new StGeotileFromFieldDocValuesAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField()), precision) + : new StGeotileFromFieldAndLiteralEvaluator.Factory(source(), toEvaluator.apply(spatialField), precision); + } else { + // Both arguments come from index fields + return spatialDocsValues + ? new StGeotileFromFieldDocValuesAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ) + : new StGeotileFromFieldAndFieldEvaluator.Factory( + source(), + toEvaluator.apply(spatialField), + toEvaluator.apply(parameter) + ); + } + } + } + + @Override + public Object fold(FoldContext ctx) { + var point = (BytesRef) spatialField().fold(ctx); + int precision = checkPrecisionRange((int) parameter().fold(ctx)); + if (bounds() == null) { + return fromLiteralAndField(point, precision); + } else { + return fromLiteralAndFieldAndLiteral(point, precision, asGeoBoundingBox((BytesRef) bounds().fold(ctx))); + } + } + + @Evaluator(extraName = "FromFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock wkbBlock, @Fixed int precision) { + fromWKB(results, p, wkbBlock, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteral(LongBlock.Builder results, int p, LongBlock encoded, @Fixed int precision) { + fromEncodedLong(results, p, encoded, precision, unboundedGrid); + } + + @Evaluator(extraName = "FromFieldAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndField(LongBlock.Builder results, int p, BytesRefBlock in, int precision) { + fromWKB(results, p, in, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromFieldDocValuesAndField", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndField(LongBlock.Builder results, int p, LongBlock encoded, int precision) { + fromEncodedLong(results, p, encoded, checkPrecisionRange(precision), unboundedGrid); + } + + @Evaluator(extraName = "FromLiteralAndField", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndField(@Fixed BytesRef in, int precision) { + return unboundedGrid.calculateGridId(GEO.wkbAsPoint(in), precision); + } + + @Evaluator(extraName = "FromFieldAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndLiteralAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, @Fixed GeoTileBoundedGrid bounds) { + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndLiteralAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndLiteralAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + @Fixed GeoTileBoundedGrid bounds + ) { + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromFieldAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldAndFieldAndLiteral(LongBlock.Builder results, int p, BytesRefBlock in, int precision, @Fixed GeoBoundingBox bbox) { + GeoTileBoundedGrid bounds = new GeoTileBoundedGrid(precision, bbox); + fromWKB(results, p, in, bounds); + } + + @Evaluator(extraName = "FromFieldDocValuesAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static void fromFieldDocValuesAndFieldAndLiteral( + LongBlock.Builder results, + int p, + LongBlock encoded, + int precision, + @Fixed GeoBoundingBox bbox + ) { + GeoTileBoundedGrid bounds = new GeoTileBoundedGrid(precision, bbox); + fromEncodedLong(results, p, encoded, bounds); + } + + @Evaluator(extraName = "FromLiteralAndFieldAndLiteral", warnExceptions = { IllegalArgumentException.class }) + static long fromLiteralAndFieldAndLiteral(@Fixed BytesRef in, int precision, @Fixed GeoBoundingBox bbox) { + GeoTileBoundedGrid bounds = new GeoTileBoundedGrid(precision, bbox); + return bounds.calculateGridId(GEO.wkbAsPoint(in)); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShape.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShape.java new file mode 100644 index 0000000000000..862a33d82ad79 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShape.java @@ -0,0 +1,114 @@ +/* + * 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.LinearRing; +import org.elasticsearch.geometry.Polygon; +import org.elasticsearch.geometry.Rectangle; +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.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; +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.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; +import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; + +public class StGeotileToGeoShape extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeotileToGeoShape", + StGeotileToGeoShape::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(KEYWORD, StGeotileToGeoShapeFromStringEvaluator.Factory::new), + Map.entry(LONG, StGeotileToGeoShapeFromLongEvaluator.Factory::new) + ); + + @FunctionInfo( + returnType = "geo_shape", + description = """ + Converts an input value to a `geo_shape` value. + The input values are expected to be the grid-ids of geotile grids, in either long or string format.""", + examples = @Example(file = "spatial-grid", tag = "geotile_to_geoshape"), + depthOffset = 1 // make it appear as a subsection of ST_GEOTILE + ) + public StGeotileToGeoShape( + 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 StGeotileToGeoShape(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return GEO_SHAPE; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeotileToGeoShape(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeotileToGeoShape::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static BytesRef fromString(BytesRef gridId) { + return fromRectangle(GeoTileUtils.toBoundingBox(gridId.utf8ToString())); + } + + @ConvertEvaluator(extraName = "FromLong") + static BytesRef fromLong(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/StGeotileToLong.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLong.java new file mode 100644 index 0000000000000..fd52f273a4f76 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLong.java @@ -0,0 +1,94 @@ +/* + * 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 StGeotileToLong extends AbstractConvertFunction implements EvaluatorMapper { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StGeotileToLong", + StGeotileToLong::new + ); + + private static final Map EVALUATORS = Map.ofEntries( + Map.entry(LONG, (source, fieldEval) -> fieldEval), + Map.entry(KEYWORD, StGeotileToLongFromStringEvaluator.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( + 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 StGeotileToLong(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + protected Map factories() { + return EVALUATORS; + } + + @Override + public DataType dataType() { + return LONG; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new StGeotileToLong(source(), newChildren.get(0)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StGeotileToLong::new, field()); + } + + @ConvertEvaluator(extraName = "FromString") + static long fromString(BytesRef gridId) { + return GeoTileUtils.longEncode(gridId.utf8ToString()); + } +} 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 new file mode 100644 index 0000000000000..1a2d2b88afc52 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToString.java @@ -0,0 +1,94 @@ +/* + * 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/optimizer/rules/physical/local/SpatialDocValuesExtraction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/SpatialDocValuesExtraction.java index d70153258871e..d55c0f9f17384 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/SpatialDocValuesExtraction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/SpatialDocValuesExtraction.java @@ -16,6 +16,7 @@ import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.aggregate.SpatialAggregateFunction; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.BinarySpatialFunction; +import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialGridFunction; import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction; import org.elasticsearch.xpack.esql.optimizer.LocalPhysicalOptimizerContext; import org.elasticsearch.xpack.esql.optimizer.PhysicalOptimizerRules; @@ -110,7 +111,10 @@ && allowedForDocValues(fieldAttribute, ctx.searchStats(), agg, foundAttributes)) if (exec instanceof EvalExec evalExec) { List fields = evalExec.fields(); List changed = fields.stream() - .map(f -> (Alias) f.transformDown(BinarySpatialFunction.class, s -> withDocValues(s, foundAttributes))) + .map( + f -> (Alias) f.transformDown(BinarySpatialFunction.class, s -> withDocValues(s, foundAttributes)) + .transformDown(SpatialGridFunction.class, s -> withDocValues(s, foundAttributes)) + ) .toList(); if (changed.equals(fields) == false) { exec = new EvalExec(exec.source(), exec.child(), changed); @@ -119,7 +123,9 @@ && allowedForDocValues(fieldAttribute, ctx.searchStats(), agg, foundAttributes)) if (exec instanceof FilterExec filterExec) { // Note that ST_CENTROID does not support shapes, but SpatialRelatesFunction does, so when we extend the centroid // to support shapes, we need to consider loading shape doc-values for both centroid and relates (ST_INTERSECTS) - var condition = filterExec.condition().transformDown(BinarySpatialFunction.class, s -> withDocValues(s, foundAttributes)); + var condition = filterExec.condition() + .transformDown(BinarySpatialFunction.class, s -> withDocValues(s, foundAttributes)) + .transformDown(SpatialGridFunction.class, s -> withDocValues(s, foundAttributes)); if (filterExec.condition().equals(condition) == false) { exec = new FilterExec(filterExec.source(), filterExec.child(), condition); } @@ -149,6 +155,12 @@ private BinarySpatialFunction withDocValues(BinarySpatialFunction spatial, Set foundAttributes) { + // Only update the docValues flags if the field is found in the attributes + boolean found = foundField(spatial.spatialField(), foundAttributes); + return found ? spatial.withDocValues(found) : spatial; + } + private boolean hasFieldAttribute(BinarySpatialFunction spatial, Set foundAttributes) { return foundField(spatial.left(), foundAttributes) || foundField(spatial.right(), foundAttributes); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometryTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometryTests.java new file mode 100644 index 0000000000000..2431d61752345 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalGeometryTests.java @@ -0,0 +1,96 @@ +/* + * 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.common.spatial; + +import org.apache.lucene.document.Document; +import org.apache.lucene.document.LatLonPoint; +import org.apache.lucene.document.ShapeField; +import org.apache.lucene.geo.GeoEncodingUtils; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.SerialMergeScheduler; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.store.Directory; +import org.elasticsearch.core.IOUtils; +import org.elasticsearch.geo.GeometryTestUtils; +import org.elasticsearch.geometry.Point; +import org.elasticsearch.h3.CellBoundary; +import org.elasticsearch.h3.H3; +import org.elasticsearch.h3.LatLng; +import org.elasticsearch.test.ESTestCase; + +/** + * TODO: This class is a copy of the same class in org.elasticsearch.xpack.spatial.common, we should find a common location for it. + */ +public class H3SphericalGeometryTests extends ESTestCase { + + private static final String FIELD_NAME = "field"; + + public void testIndexPoints() throws Exception { + Point queryPoint = GeometryTestUtils.randomPoint(); + long[] hexes = new long[H3.MAX_H3_RES + 1]; + for (int res = 0; res < hexes.length; res++) { + hexes[res] = H3.geoToH3(queryPoint.getLat(), queryPoint.getLon(), res); + } + IndexWriterConfig iwc = newIndexWriterConfig(); + // Else seeds may not reproduce: + iwc.setMergeScheduler(new SerialMergeScheduler()); + // Else we can get O(N^2) merging: + iwc.setMaxBufferedDocs(10); + Directory dir = newDirectory(); + // RandomIndexWriter is too slow here: + int[] counts = new int[H3.MAX_H3_RES + 1]; + IndexWriter w = new IndexWriter(dir, iwc); + for (long hex : hexes) { + CellBoundary cellBoundary = H3.h3ToGeoBoundary(hex); + for (int i = 0; i < cellBoundary.numPoints(); i++) { + Document doc = new Document(); + LatLng latLng = cellBoundary.getLatLon(i); + doc.add(new LatLonPoint(FIELD_NAME, latLng.getLatDeg(), latLng.getLonDeg())); + w.addDocument(doc); + computeCounts(hexes, latLng.getLonDeg(), latLng.getLatDeg(), counts); + } + + } + final int numDocs = randomIntBetween(1000, 2000); + for (int id = 0; id < numDocs; id++) { + Document doc = new Document(); + Point point = GeometryTestUtils.randomPoint(); + doc.add(new LatLonPoint(FIELD_NAME, point.getLat(), point.getLon())); + w.addDocument(doc); + computeCounts(hexes, point.getLon(), point.getLat(), counts); + } + + if (random().nextBoolean()) { + w.forceMerge(1); + } + final IndexReader r = DirectoryReader.open(w); + w.close(); + + IndexSearcher s = newSearcher(r); + for (int i = 0; i < H3.MAX_H3_RES + 1; i++) { + H3SphericalGeometry geometry = new H3SphericalGeometry(hexes[i]); + Query indexQuery = LatLonPoint.newGeometryQuery(FIELD_NAME, ShapeField.QueryRelation.INTERSECTS, geometry); + assertEquals(counts[i], s.count(indexQuery)); + } + IOUtils.close(r, dir); + } + + private void computeCounts(long[] hexes, double lon, double lat, int[] counts) { + double qLat = GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(lat)); + double qLon = GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(lon)); + for (int res = 0; res < hexes.length; res++) { + if (hexes[res] == H3.geoToH3(qLat, qLon, res)) { + counts[res]++; + } + } + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtilTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtilTests.java new file mode 100644 index 0000000000000..51537b11687e7 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/common/spatial/H3SphericalUtilTests.java @@ -0,0 +1,67 @@ +/* + * 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.common.spatial; + +import org.apache.lucene.spatial3d.geom.GeoPolygon; +import org.apache.lucene.spatial3d.geom.LatLonBounds; +import org.apache.lucene.tests.geo.GeoTestUtil; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.h3.H3; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.spatial.common.H3SphericalUtil; + +/** + * TODO: This class is a copy of the same class in org.elasticsearch.xpack.spatial.common, we should find a common location for it. + */ +public class H3SphericalUtilTests extends ESTestCase { + + private static final double LAT_DELTA = 1e-7; + private static final double LON_DELTA = 1e-5; + + public void testRandomBounds() { + GeoBoundingBox boundingBox = new GeoBoundingBox(new GeoPoint(), new GeoPoint()); + for (int res = 0; res < H3.MAX_H3_RES; res++) { + final long h3 = H3.geoToH3(GeoTestUtil.nextLatitude(), GeoTestUtil.nextLongitude(), res); + assertBounds(h3, boundingBox); + } + } + + public void testBoundsLevel0() { + GeoBoundingBox boundingBox = new GeoBoundingBox(new GeoPoint(), new GeoPoint()); + for (long h3 : H3.getLongRes0Cells()) { + assertBounds(h3, boundingBox); + } + } + + private void assertBounds(long h3, GeoBoundingBox boundingBox) { + org.elasticsearch.xpack.spatial.common.H3SphericalUtil.computeGeoBounds(h3, boundingBox); + GeoPolygon polygon = H3SphericalUtil.toGeoPolygon(h3); + LatLonBounds bounds = new LatLonBounds(); + polygon.getBounds(bounds); + if (bounds.checkNoLongitudeBound()) { + assertEquals(-180d, boundingBox.left(), LON_DELTA); + assertEquals(180d, boundingBox.right(), LON_DELTA); + } else { + assertEquals(Math.toDegrees(bounds.getLeftLongitude()), boundingBox.left(), LON_DELTA); + assertEquals(Math.toDegrees(bounds.getRightLongitude()), boundingBox.right(), LON_DELTA); + } + + if (bounds.checkNoTopLatitudeBound()) { + assertEquals(90d, boundingBox.top(), LAT_DELTA); + } else { + assertEquals(Math.toDegrees(bounds.getMaxLatitude()), boundingBox.top(), LAT_DELTA); + } + + if (bounds.checkNoBottomLatitudeBound()) { + assertEquals(-90d, boundingBox.bottom(), LAT_DELTA); + } else { + assertEquals(Math.toDegrees(bounds.getMinLatitude()), boundingBox.bottom(), LAT_DELTA); + } + } +} 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 new file mode 100644 index 0000000000000..3678ecd65df1f --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridFunctionTestCase.java @@ -0,0 +1,90 @@ +/* + * 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.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.List; +import java.util.function.BiFunction; + +import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialGeo; +import static org.hamcrest.Matchers.equalTo; + +public abstract class SpatialGridFunctionTestCase extends AbstractScalarFunctionTestCase { + + private static String getFunctionClassName() { + Class testClass = getTestClass(); + String testClassName = testClass.getSimpleName(); + return testClassName.replace("Tests", ""); + } + + protected static void addTestCaseSuppliers( + List suppliers, + DataType[] dataTypes, + BiFunction expectedValue + ) { + for (DataType spatialType : dataTypes) { + DataType shapeType = isSpatialGeo(spatialType) ? DataType.GEO_SHAPE : DataType.CARTESIAN_SHAPE; + TestCaseSupplier.TypedDataSupplier geometrySupplier = testCaseSupplier(spatialType, true); + suppliers.add(new TestCaseSupplier("with precision", List.of(spatialType, DataType.INTEGER), () -> { + TestCaseSupplier.TypedData geoTypedData = geometrySupplier.get(); + BytesRef geometry = (BytesRef) geoTypedData.data(); + int precision = between(1, 8); + TestCaseSupplier.TypedData precisionData = new TestCaseSupplier.TypedData(precision, DataType.INTEGER, "precision"); + return new TestCaseSupplier.TestCase( + List.of(geoTypedData, precisionData), + getFunctionClassName() + "FromFieldAndFieldEvaluator[in=Attribute[channel=0], precision=Attribute[channel=1]]", + LONG, + equalTo(expectedValue.apply(geometry, precision)) + ); + })); + /* + TODO: Implement non-foldable bounds + suppliers.add(new TestCaseSupplier("with precision and bounds", List.of(spatialType, DataType.INTEGER, shapeType), () -> { + TestCaseSupplier.TypedData geoTypedData = geometrySupplier.get(); + BytesRef geometry = (BytesRef) geoTypedData.data(); + int precision = between(1, 8); + TestCaseSupplier.TypedData precisionData = new TestCaseSupplier.TypedData(precision, DataType.INTEGER, "precision"); + Rectangle bounds = new Rectangle(-30, 30, 30, -30); + BytesRef boundsBytesRef = GEO.asWkb(bounds); + TestCaseSupplier.TypedData boundsData = new TestCaseSupplier.TypedData(boundsBytesRef, shapeType, "bounds"); + return new TestCaseSupplier.TestCase( + List.of(geoTypedData, precisionData, boundsData), + getFunctionClassName() + + "FromFieldAndFieldAndLiteralEvaluator[" + + "in=Attribute[channel=0], precision=Attribute[channel=1], bounds=Attribute[channel=2]]", + LONG, + equalTo(expectedValue.apply(geometry, precision)) + ); + })); + */ + } + } + + 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); + 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); + 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/SpatialGridTypeConversionTestCases.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridTypeConversionTestCases.java new file mode 100644 index 0000000000000..c69269cbf7a83 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/SpatialGridTypeConversionTestCases.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.spatial; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.test.ESTestCase; +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 java.util.List; +import java.util.function.Function; + +import static org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier.geoPointCases; + +public abstract class SpatialGridTypeConversionTestCases extends AbstractScalarFunctionTestCase { + public static void forUnaryGeoPoint( + DataType type, + List suppliers, + String expectedEvaluatorToString, + DataType expectedType, + Function geometryToGeotile, + Function expectedValue + ) { + TestCaseSupplier.unary( + suppliers, + expectedEvaluatorToString, + geoPointAsGeotileCases(type, geometryToGeotile), + expectedType, + expectedValue::apply, + List.of() + ); + } + + public static List geoPointAsGeotileCases( + DataType type, + Function geometryToGeotile + ) { + return geoPointCases(ESTestCase::randomBoolean).stream() + .map( + t -> new TestCaseSupplier.TypedDataSupplier( + t.name() + " as " + type, + () -> geometryToGeotile.apply((BytesRef) t.supplier().get()), + type + ) + ) + .toList(); + } +} 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 new file mode 100644 index 0000000000000..51efa32c95833 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashTests.java @@ -0,0 +1,46 @@ +/* + * 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.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.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +public class StGeohashTests extends SpatialGridFunctionTestCase { + public StGeohashTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeohashTests::valueOf); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(BytesRef wkb, int precision) { + return StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(wkb), precision); + } + + @Override + protected Expression build(Source source, List args) { + Expression bounds = args.size() > 2 ? args.get(2) : null; + return new StGeohash(source, args.get(0), args.get(1), bounds); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeTests.java new file mode 100644 index 0000000000000..6c0eaac7a69a0 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToGeoShapeTests.java @@ -0,0 +1,64 @@ +/* + * 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.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +@FunctionName("st_geohash_to_geoshape") +public class StGeohashToGeoShapeTests extends SpatialGridTypeConversionTestCases { + public StGeohashToGeoShapeTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + forUnaryGeoPoint( + DataType.LONG, + suppliers, + "StGeohashToGeoShapeFromLongEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), + StGeohashToGeoShapeTests::valueOf + ); + forUnaryGeoPoint( + DataType.KEYWORD, + suppliers, + "StGeohashToGeoShapeFromStringEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> new BytesRef(Geohash.stringEncode(StGeohash.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), + StGeohashToGeoShapeTests::valueOf + ); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static BytesRef valueOf(Object gridid) { + return (gridid instanceof Long hash) ? StGeohashToGeoShape.fromLong(hash) : StGeohashToGeoShape.fromString((BytesRef) gridid); + } + + @Override + protected Expression build(Source source, List args) { + return new StGeohashToGeoShape(source, args.get(0)); + } +} 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 new file mode 100644 index 0000000000000..fab3655677774 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToLongTests.java @@ -0,0 +1,63 @@ +/* + * 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 new file mode 100644 index 0000000000000..58feda75a8ab9 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohashToStringTests.java @@ -0,0 +1,64 @@ +/* + * 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 new file mode 100644 index 0000000000000..595e2c4f15249 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexTests.java @@ -0,0 +1,46 @@ +/* + * 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.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.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +public class StGeohexTests extends SpatialGridFunctionTestCase { + public StGeohexTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeohexTests::valueOf); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(BytesRef wkb, int precision) { + return StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(wkb), precision); + } + + @Override + protected Expression build(Source source, List args) { + Expression bounds = args.size() > 2 ? args.get(2) : null; + return new StGeohex(source, args.get(0), args.get(1), bounds); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeTests.java new file mode 100644 index 0000000000000..acd08a82e672e --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToGeoShapeTests.java @@ -0,0 +1,64 @@ +/* + * 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.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +@FunctionName("st_geohex_to_geoshape") +public class StGeohexToGeoShapeTests extends SpatialGridTypeConversionTestCases { + public StGeohexToGeoShapeTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + forUnaryGeoPoint( + DataType.LONG, + suppliers, + "StGeohexToGeoShapeFromLongEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), + StGeohexToGeoShapeTests::valueOf + ); + forUnaryGeoPoint( + DataType.KEYWORD, + suppliers, + "StGeohexToGeoShapeFromStringEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> new BytesRef(H3.h3ToString(StGeohex.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), + StGeohexToGeoShapeTests::valueOf + ); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static BytesRef valueOf(Object gridid) { + return (gridid instanceof Long hex) ? StGeohexToGeoShape.fromLong(hex) : StGeohexToGeoShape.fromString((BytesRef) gridid); + } + + @Override + protected Expression build(Source source, List args) { + return new StGeohexToGeoShape(source, args.get(0)); + } +} 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 new file mode 100644 index 0000000000000..7c28fdb551079 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToLongTests.java @@ -0,0 +1,63 @@ +/* + * 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 new file mode 100644 index 0000000000000..bf3c734869330 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeohexToStringTests.java @@ -0,0 +1,64 @@ +/* + * 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 new file mode 100644 index 0000000000000..5f7e8b0425a3f --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileTests.java @@ -0,0 +1,46 @@ +/* + * 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.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.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +public class StGeotileTests extends SpatialGridFunctionTestCase { + public StGeotileTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + addTestCaseSuppliers(suppliers, new DataType[] { DataType.GEO_POINT }, StGeotileTests::valueOf); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static long valueOf(BytesRef wkb, int precision) { + return StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(wkb), precision); + } + + @Override + protected Expression build(Source source, List args) { + Expression bounds = args.size() > 2 ? args.get(2) : null; + return new StGeotile(source, args.get(0), args.get(1), bounds); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeTests.java new file mode 100644 index 0000000000000..afed423cccbbe --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToGeoShapeTests.java @@ -0,0 +1,64 @@ +/* + * 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.GEO_SHAPE; +import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.UNSPECIFIED; + +@FunctionName("st_geotile_to_geoshape") +public class StGeotileToGeoShapeTests extends SpatialGridTypeConversionTestCases { + public StGeotileToGeoShapeTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + final List suppliers = new ArrayList<>(); + forUnaryGeoPoint( + DataType.LONG, + suppliers, + "StGeotileToGeoShapeFromLongEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2), + StGeotileToGeoShapeTests::valueOf + ); + forUnaryGeoPoint( + DataType.KEYWORD, + suppliers, + "StGeotileToGeoShapeFromStringEvaluator[gridId=Attribute[channel=0]]", + GEO_SHAPE, + g -> new BytesRef(GeoTileUtils.stringEncode(StGeotile.unboundedGrid.calculateGridId(UNSPECIFIED.wkbAsPoint(g), 2))), + StGeotileToGeoShapeTests::valueOf + ); + return parameterSuppliersFromTypedDataWithDefaultChecksNoErrors(true, suppliers); + } + + private static BytesRef valueOf(Object gridid) { + return (gridid instanceof Long hash) ? StGeotileToGeoShape.fromLong(hash) : StGeotileToGeoShape.fromString((BytesRef) gridid); + } + + @Override + protected Expression build(Source source, List args) { + return new StGeotileToGeoShape(source, args.get(0)); + } +} 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 new file mode 100644 index 0000000000000..1f43536719fd8 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToLongTests.java @@ -0,0 +1,63 @@ +/* + * 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 new file mode 100644 index 0000000000000..fd558887c0fda --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StGeotileToStringTests.java @@ -0,0 +1,64 @@ +/* + * 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/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml index 18ea2903d1d86..39929f6bba8d7 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml @@ -123,7 +123,7 @@ setup: - match: {esql.functions.coalesce: $functions_coalesce} - gt: {esql.functions.categorize: $functions_categorize} # Testing for the entire function set isn't feasible, so we just check that we return the correct count as an approximation. - - length: {esql.functions: 141} # check the "sister" test below for a likely update to the same esql.functions length check + - length: {esql.functions: 152} # check the "sister" test below for a likely update to the same esql.functions length check --- "Basic ESQL usage output (telemetry) non-snapshot version": @@ -221,7 +221,7 @@ setup: - gt: {esql.functions.to_long: $functions_to_long} - match: {esql.functions.coalesce: $functions_coalesce} - gt: {esql.functions.categorize: $functions_categorize} - - length: {esql.functions: 132} # check the "sister" test above for a likely update to the same esql.functions length check + - length: {esql.functions: 144} # check the "sister" test above for a likely update to the same esql.functions length check --- took: