From 024c07925ea7b427271231aca78fc70d77bb2cad Mon Sep 17 00:00:00 2001 From: Igor Motov <igor@motovs.org> Date: Fri, 2 Nov 2018 17:04:33 -0400 Subject: [PATCH 1/4] SQL: Add ST_WktToSQL function Adds support for ST_WktToSQL function which accepts a string and parses it as WKT representation of a geoshape. Relates to #29872 --- docs/reference/sql/functions/geo.asciidoc | 25 +++++++ .../qa/src/main/resources/command.csv-spec | 1 + .../sql/qa/src/main/resources/docs.csv-spec | 1 + .../qa/src/main/resources/geo/docs.csv-spec | 11 +++- .../qa/src/main/resources/geo/geosql.csv-spec | 29 +++++++++ .../expression/function/FunctionRegistry.java | 2 + .../function/scalar/Processors.java | 2 + .../function/scalar/geo/StWkttosql.java | 65 +++++++++++++++++++ .../scalar/geo/StWkttosqlProcessor.java | 57 ++++++++++++++++ .../whitelist/InternalSqlScriptUtils.java | 6 ++ .../xpack/sql/type/DataTypes.java | 4 ++ .../xpack/sql/plugin/sql_whitelist.txt | 10 ++- 12 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosql.java create mode 100644 x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java diff --git a/docs/reference/sql/functions/geo.asciidoc b/docs/reference/sql/functions/geo.asciidoc index af47ebd2c7de0..14bd5fad92c4b 100644 --- a/docs/reference/sql/functions/geo.asciidoc +++ b/docs/reference/sql/functions/geo.asciidoc @@ -30,3 +30,28 @@ Returns the WKT representation of the `geometry`. The return type is string. -------------------------------------------------- include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt] -------------------------------------------------- + + +[[sql-functions-geo-st-as-wkt]] +===== `ST_AsWKT` + +.Synopsis: +[source, sql] +-------------------------------------------------- +ST_WKTToSQL(string<1>) +-------------------------------------------------- + +*Input*: + +<1> string geometry + +*Output*: WKT string + +.Description: + +Returns the geometry from WKT representation. The return type is geometry. + +["source","sql",subs="attributes,macros"] +-------------------------------------------------- +include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt] +-------------------------------------------------- \ No newline at end of file diff --git a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec index 8588390405eca..5660bf93f740e 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec @@ -101,6 +101,7 @@ SPACE |SCALAR SUBSTRING |SCALAR UCASE |SCALAR ST_ASWKT |SCALAR +ST_WKTTOSQL |SCALAR CAST |SCALAR CONVERT |SCALAR SCORE |SCORE diff --git a/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec index 72046a982a408..9c52de592caa2 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec @@ -278,6 +278,7 @@ SPACE |SCALAR SUBSTRING |SCALAR UCASE |SCALAR ST_ASWKT |SCALAR +ST_WKTTOSQL |SCALAR CAST |SCALAR CONVERT |SCALAR SCORE |SCORE diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec index 2216a43f68c14..a288113375188 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec @@ -10,9 +10,18 @@ selectAsWKT // tag::aswkt -SELECT city, ST_ASWKT(location) location FROM "geo" WHERE city = 'Amsterdam'; +SELECT city, ST_AsWKT(location) location FROM "geo" WHERE city = 'Amsterdam'; city:s | location:s Amsterdam |point (4.850311987102032 52.347556999884546) // end::aswkt ; + +selectAsWKT +// tag::wkttosql +SELECT ST_AsWKT(ST_WKTToSQL('POINT (10 20)')) location; + + location:s +point (10.0 20.0) +// end::wkttosql +; diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec index ce58a112488ce..989fe76f7cc1e 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec @@ -102,3 +102,32 @@ SELECT COUNT(city) count, CAST(SUBSTRING(ST_ASWKT(location), 8, 1) = '-' AS STRI 9 |false 6 |true ; + +selectFakeCoordinatesFromCityAndRegion +SELECT region, city, ST_ASWKT(ST_WKTTOSQL(CONCAT(CONCAT(CONCAT(CONCAT('POINT (', CAST(LENGTH(city) AS STRING)), ' '), CAST(LENGTH(region) AS STRING)), ')'))) loc FROM geo ORDER BY region, city; + + region:s | city:s | loc:s +Americas |Chicago |point (7.0 8.0) +Americas |Mountain View |point (13.0 8.0) +Americas |New York |point (8.0 8.0) +Americas |Phoenix |point (7.0 8.0) +Americas |San Francisco |point (13.0 8.0) +Asia |Hong Kong |point (9.0 4.0) +Asia |Seoul |point (5.0 4.0) +Asia |Singapore |point (9.0 4.0) +Asia |Sydney |point (6.0 4.0) +Asia |Tokyo |point (5.0 4.0) +Europe |Amsterdam |point (9.0 6.0) +Europe |Berlin |point (6.0 6.0) +Europe |London |point (6.0 6.0) +Europe |Munich |point (6.0 6.0) +Europe |Paris |point (5.0 6.0) +; + +selectAllPointsGroupByHemisphereFromAsWKT +SELECT COUNT(city) count, CAST(SUBSTRING(ST_ASWKT(ST_WKTTOSQL(UCASE(ST_ASWKT(location)))), 8, 1) = '-' AS STRING) west FROM "geo" GROUP BY west ORDER BY west; + + count:l | west:s +9 |false +6 |true +; \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java index e44edafd9b03b..b563c4b4c8d5f 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java @@ -35,6 +35,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.WeekOfYear; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.Year; import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StAswkt; +import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StWkttosql; import org.elasticsearch.xpack.sql.expression.function.scalar.math.ACos; import org.elasticsearch.xpack.sql.expression.function.scalar.math.ASin; import org.elasticsearch.xpack.sql.expression.function.scalar.math.ATan; @@ -215,6 +216,7 @@ private void defineDefaultFunctions() { // Geo Functions addToMap(def(StAswkt.class, StAswkt::new)); + addToMap(def(StWkttosql.class, StWkttosql::new)); // DataType conversion addToMap(def(Cast.class, Cast::new, "CONVERT")); // Special diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java index 0ed87eb78d7f1..730477d3a1e7c 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java @@ -11,6 +11,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NamedDateTimeProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.QuarterProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoProcessor; +import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StWkttosqlProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.math.BinaryMathProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.string.BinaryStringNumericProcessor; @@ -90,6 +91,7 @@ public static List<NamedWriteableRegistry.Entry> getNamedWriteables() { entries.add(new Entry(Processor.class, ReplaceFunctionProcessor.NAME, ReplaceFunctionProcessor::new)); entries.add(new Entry(Processor.class, SubstringFunctionProcessor.NAME, SubstringFunctionProcessor::new)); entries.add(new Entry(Processor.class, GeoProcessor.NAME, GeoProcessor::new)); + entries.add(new Entry(Processor.class, StWkttosqlProcessor.NAME, StWkttosqlProcessor::new)); return entries; } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosql.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosql.java new file mode 100644 index 0000000000000..e396e17a8648e --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosql.java @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.sql.expression.function.scalar.geo; + +import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.Expressions; +import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; +import org.elasticsearch.xpack.sql.tree.Location; +import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.type.DataType; + +/** + * Constructs geometric objects from their WTK representations + */ +public class StWkttosql extends UnaryScalarFunction { + + public StWkttosql(Location location, Expression field) { + super(location, field); + } + + @Override + protected StWkttosql replaceChild(Expression newChild) { + return new StWkttosql(location(), newChild); + } + + @Override + protected TypeResolution resolveType() { + if (field().dataType().isString()) { + return TypeResolution.TYPE_RESOLVED; + } + return Expressions.typeMustBeString(field(), functionName(), Expressions.ParamOrdinal.DEFAULT); + } + + @Override + protected Processor makeProcessor() { + return StWkttosqlProcessor.INSTANCE; + } + + @Override + public DataType dataType() { + return DataType.GEO_SHAPE; + } + + @Override + protected NodeInfo<StWkttosql> info() { + return NodeInfo.create(this, StWkttosql::new, field()); + } + + @Override + public String processScript(String script) { + return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".wktToSql(" + script + ")"); + } + + @Override + public Object fold() { + return StWkttosqlProcessor.INSTANCE.process(field().fold()); + } + +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java new file mode 100644 index 0000000000000..33441532ac796 --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.sql.expression.function.scalar.geo; + +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; + +import java.io.IOException; + +public class StWkttosqlProcessor implements Processor { + + static final StWkttosqlProcessor INSTANCE = new StWkttosqlProcessor(); + + public static final String NAME = "geo_wkttosql"; + + private StWkttosqlProcessor() { + } + + public StWkttosqlProcessor(StreamInput in) throws IOException {} + + @Override + public Object process(Object input) { + return StWkttosqlProcessor.apply(input); + } + + + public static GeoShape apply(Object input) { + if (input == null) { + return null; + } + + if ((input instanceof String) == false) { + throw new SqlIllegalArgumentException("A string is required; received {}", input); + } + try { + return new GeoShape(input); + } catch (IOException ex) { + throw new SqlIllegalArgumentException("Cannot parse [{}] as a geo_shape value", input); + } + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + + } +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java index be961aae99b57..7c778054a0be0 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java @@ -12,6 +12,8 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NamedDateTimeProcessor.NameExtractor; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.QuarterProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoProcessor; +import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoShape; +import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StWkttosqlProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.math.BinaryMathProcessor.BinaryMathOperation; import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation; import org.elasticsearch.xpack.sql.expression.function.scalar.string.BinaryStringNumericProcessor.BinaryStringNumericOperation; @@ -403,4 +405,8 @@ public static String aswktPoint(Object v) { public static String aswktShape(Object v) { return GeoProcessor.GeoOperation.ASWKT_SHAPE.apply(v).toString(); } + + public static GeoShape wktToSql(String v) { + return StWkttosqlProcessor.apply(v); + } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java index 92bc6f33a5de5..d293422dfeb02 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.sql.type; import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; +import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoShape; import org.joda.time.DateTime; public final class DataTypes { @@ -51,6 +52,9 @@ public static DataType fromJava(Object value) { if (value instanceof String || value instanceof Character) { return DataType.KEYWORD; } + if (value instanceof GeoShape) { + return DataType.GEO_SHAPE; + } throw new SqlIllegalArgumentException("No idea what's the DataType for {}", value.getClass()); } diff --git a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt index fb37745d154ba..2794a2ff9e11d 100644 --- a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt +++ b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt @@ -4,7 +4,14 @@ # you may not use this file except in compliance with the Elastic License. # -# This file contains a whitelist for SQL specific utilities available inside SQL scripting +# This file contains a whitelist for SQL specific utilities and classes available inside SQL scripting + +#### Classes + +class org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoShape { + +} + class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalSqlScriptUtils { @@ -116,4 +123,5 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS String ucase(String) String aswktPoint(Object) String aswktShape(Object) + GeoShape wktToSql(String) } From ed0aa6c692083e977ef75e1a00c0745547c7ed78 Mon Sep 17 00:00:00 2001 From: Igor Motov <igor@motovs.org> Date: Mon, 12 Nov 2018 18:32:53 -0500 Subject: [PATCH 2/4] Address review comments and add some JDBC tests --- .../qa/src/main/resources/command.csv-spec | 2 + .../sql/qa/src/main/resources/docs.csv-spec | 2 + .../qa/src/main/resources/geo/docs.csv-spec | 2 +- .../src/main/resources/geo/geosql-bulk.json | 30 ++++----- .../qa/src/main/resources/geo/geosql.csv-spec | 64 ++++++++++++------- .../sql/qa/src/main/resources/geo/geosql.json | 3 + .../qa/src/main/resources/ogc/ogc.sql-spec | 12 ++++ .../expression/function/FunctionRegistry.java | 4 +- .../scalar/geo/StWkttosqlProcessor.java | 11 ++-- .../whitelist/InternalSqlScriptUtils.java | 4 +- .../scalar/geo/StWkttosqlProcessorTests.java | 42 ++++++++++++ 11 files changed, 127 insertions(+), 49 deletions(-) create mode 100644 x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessorTests.java diff --git a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec index 5660bf93f740e..34e8e1fbf1967 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec @@ -100,7 +100,9 @@ RTRIM |SCALAR SPACE |SCALAR SUBSTRING |SCALAR UCASE |SCALAR +ST_ASTEXT |SCALAR ST_ASWKT |SCALAR +ST_GEOMFROMTEXT |SCALAR ST_WKTTOSQL |SCALAR CAST |SCALAR CONVERT |SCALAR diff --git a/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec index 9c52de592caa2..437c66a4ea199 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec @@ -277,7 +277,9 @@ RTRIM |SCALAR SPACE |SCALAR SUBSTRING |SCALAR UCASE |SCALAR +ST_ASTEXT |SCALAR ST_ASWKT |SCALAR +ST_GEOMFROMTEXT |SCALAR ST_WKTTOSQL |SCALAR CAST |SCALAR CONVERT |SCALAR diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec index a288113375188..9bfd01ce9345c 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec @@ -17,7 +17,7 @@ Amsterdam |point (4.850311987102032 52.347556999884546) // end::aswkt ; -selectAsWKT +selectWKTToSQL // tag::wkttosql SELECT ST_AsWKT(ST_WKTToSQL('POINT (10 20)')) location; diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json index 56c76b9f769f3..7840c10150881 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql-bulk.json @@ -1,33 +1,33 @@ {"index":{"_id": "1"}} -{"region": "Americas", "city": "Mountain View", "location": {"lat":"37.386483", "lon":"-122.083843"}, "shape": "POINT (-122.083843 37.386483)"} +{"region": "Americas", "city": "Mountain View", "location": {"lat":"37.386483", "lon":"-122.083843"}, "shape": "POINT (-122.083843 37.386483)", "region_point": "POINT(-105.2551 54.5260)"} {"index":{"_id": "2"}} -{"region": "Americas", "city": "Chicago", "location": [-87.637874, 41.888783], "shape": {"type" : "point", "coordinates" : [-87.637874, 41.888783] }} +{"region": "Americas", "city": "Chicago", "location": [-87.637874, 41.888783], "shape": {"type" : "point", "coordinates" : [-87.637874, 41.888783]}, "region_point": "POINT(-105.2551 54.5260)"} {"index":{"_id": "3"}} -{"region": "Americas", "city": "New York", "location": "40.745171,-73.990027", "shape": "POINT (-73.990027 40.745171)"} +{"region": "Americas", "city": "New York", "location": "40.745171,-73.990027", "shape": "POINT (-73.990027 40.745171)", "region_point": "POINT(-105.2551 54.5260)"} {"index":{"_id": "4"}} -{"region": "Americas", "city": "San Francisco", "location": "37.789541,-122.394228", "shape": "POINT (-122.394228 37.789541)"} +{"region": "Americas", "city": "San Francisco", "location": "37.789541,-122.394228", "shape": "POINT (-122.394228 37.789541)", "region_point": "POINT(-105.2551 54.5260)"} {"index":{"_id": "5"}} -{"region": "Americas", "city": "Phoenix", "location": "33.376242,-111.973505", "shape": "POINT (-111.973505 33.376242)"} +{"region": "Americas", "city": "Phoenix", "location": "33.376242,-111.973505", "shape": "POINT (-111.973505 33.376242)", "region_point": "POINT(-105.2551 54.5260)"} {"index":{"_id": "6"}} -{"region": "Europe", "city": "Amsterdam", "location": "52.347557,4.850312", "shape": "POINT (4.850312 52.347557)"} +{"region": "Europe", "city": "Amsterdam", "location": "52.347557,4.850312", "shape": "POINT (4.850312 52.347557)", "region_point": "POINT(15.2551 54.5260)"} {"index":{"_id": "7"}} -{"region": "Europe", "city": "Berlin", "location": "52.486701,13.390889", "shape": "POINT (13.390889 52.486701)"} +{"region": "Europe", "city": "Berlin", "location": "52.486701,13.390889", "shape": "POINT (13.390889 52.486701)", "region_point": "POINT(15.2551 54.5260)"} {"index":{"_id": "8"}} -{"region": "Europe", "city": "Munich", "location": "48.146321,11.537505", "shape": "POINT (11.537505 48.146321)"} +{"region": "Europe", "city": "Munich", "location": "48.146321,11.537505", "shape": "POINT (11.537505 48.146321)", "region_point": "POINT(15.2551 54.5260)"} {"index":{"_id": "9"}} -{"region": "Europe", "city": "London", "location": "51.510871,-0.121672", "shape": "POINT (-0.121672 51.510871)"} +{"region": "Europe", "city": "London", "location": "51.510871,-0.121672", "shape": "POINT (-0.121672 51.510871)", "region_point": "POINT(15.2551 54.5260)"} {"index":{"_id": "10"}} -{"region": "Europe", "city": "Paris", "location": "48.845538,2.351773", "shape": "POINT (2.351773 48.845538)"} +{"region": "Europe", "city": "Paris", "location": "48.845538,2.351773", "shape": "POINT (2.351773 48.845538)", "region_point": "POINT(15.2551 54.5260)"} {"index":{"_id": "11"}} -{"region": "Asia", "city": "Singapore", "location": "1.295868,103.855535", "shape": "POINT (103.855535 1.295868)"} +{"region": "Asia", "city": "Singapore", "location": "1.295868,103.855535", "shape": "POINT (103.855535 1.295868)", "region_point": "POINT(100.6197 34.0479)"} {"index":{"_id": "12"}} -{"region": "Asia", "city": "Hong Kong", "location": "22.281397,114.183925", "shape": "POINT (114.183925 22.281397)"} +{"region": "Asia", "city": "Hong Kong", "location": "22.281397,114.183925", "shape": "POINT (114.183925 22.281397)", "region_point": "POINT(100.6197 34.0479)"} {"index":{"_id": "13"}} -{"region": "Asia", "city": "Seoul", "location": "37.509132,127.060851", "shape": "POINT (127.060851 37.509132)"} +{"region": "Asia", "city": "Seoul", "location": "37.509132,127.060851", "shape": "POINT (127.060851 37.509132)", "region_point": "POINT(100.6197 34.0479)"} {"index":{"_id": "14"}} -{"region": "Asia", "city": "Tokyo", "location": "35.669616,139.76402225", "shape": "POINT (139.76402225 35.669616)"} +{"region": "Asia", "city": "Tokyo", "location": "35.669616,139.76402225", "shape": "POINT (139.76402225 35.669616)", "region_point": "POINT(100.6197 34.0479)"} {"index":{"_id": "15"}} -{"region": "Asia", "city": "Sydney", "location": "-33.863385,151.208629", "shape": "POINT (151.208629 -33.863385)"} +{"region": "Asia", "city": "Sydney", "location": "-33.863385,151.208629", "shape": "POINT (151.208629 -33.863385)", "region_point": "POINT(100.6197 34.0479)"} diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec index 989fe76f7cc1e..7ec42197efa5a 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.csv-spec @@ -18,6 +18,7 @@ DESCRIBE "geo"; city | VARCHAR | KEYWORD location | OTHER | GEO_POINT region | VARCHAR | KEYWORD +region_point | VARCHAR | KEYWORD shape | OTHER | GEO_SHAPE ; @@ -103,31 +104,46 @@ SELECT COUNT(city) count, CAST(SUBSTRING(ST_ASWKT(location), 8, 1) = '-' AS STRI 6 |true ; -selectFakeCoordinatesFromCityAndRegion -SELECT region, city, ST_ASWKT(ST_WKTTOSQL(CONCAT(CONCAT(CONCAT(CONCAT('POINT (', CAST(LENGTH(city) AS STRING)), ' '), CAST(LENGTH(region) AS STRING)), ')'))) loc FROM geo ORDER BY region, city; - - region:s | city:s | loc:s -Americas |Chicago |point (7.0 8.0) -Americas |Mountain View |point (13.0 8.0) -Americas |New York |point (8.0 8.0) -Americas |Phoenix |point (7.0 8.0) -Americas |San Francisco |point (13.0 8.0) -Asia |Hong Kong |point (9.0 4.0) -Asia |Seoul |point (5.0 4.0) -Asia |Singapore |point (9.0 4.0) -Asia |Sydney |point (6.0 4.0) -Asia |Tokyo |point (5.0 4.0) -Europe |Amsterdam |point (9.0 6.0) -Europe |Berlin |point (6.0 6.0) -Europe |London |point (6.0 6.0) -Europe |Munich |point (6.0 6.0) -Europe |Paris |point (5.0 6.0) +selectRegionUsingWktToSql +SELECT region, city, ST_ASWKT(ST_WKTTOSQL(region_point)) region_wkt FROM geo ORDER BY region, city; + + region:s | city:s | region_wkt:s +Americas |Chicago |point (-105.2551 54.526) +Americas |Mountain View |point (-105.2551 54.526) +Americas |New York |point (-105.2551 54.526) +Americas |Phoenix |point (-105.2551 54.526) +Americas |San Francisco |point (-105.2551 54.526) +Asia |Hong Kong |point (100.6197 34.0479) +Asia |Seoul |point (100.6197 34.0479) +Asia |Singapore |point (100.6197 34.0479) +Asia |Sydney |point (100.6197 34.0479) +Asia |Tokyo |point (100.6197 34.0479) +Europe |Amsterdam |point (15.2551 54.526) +Europe |Berlin |point (15.2551 54.526) +Europe |London |point (15.2551 54.526) +Europe |Munich |point (15.2551 54.526) +Europe |Paris |point (15.2551 54.526) ; -selectAllPointsGroupByHemisphereFromAsWKT -SELECT COUNT(city) count, CAST(SUBSTRING(ST_ASWKT(ST_WKTTOSQL(UCASE(ST_ASWKT(location)))), 8, 1) = '-' AS STRING) west FROM "geo" GROUP BY west ORDER BY west; +selectCitiesWithAGroupByWktToSql +SELECT COUNT(city) city_by_region, CAST(ST_WKTTOSQL(region_point) AS STRING) region FROM geo WHERE city LIKE '%a%' GROUP BY ST_WKTTOSQL(region_point) ORDER BY ST_WKTTOSQL(region_point); - count:l | west:s -9 |false -6 |true + city_by_region:l | region:s +3 |point (-105.2551 54.526) +1 |point (100.6197 34.0479) +2 |point (15.2551 54.526) +; + +selectCitiesWithEOrderByWktToSql +SELECT region, city FROM geo WHERE city LIKE '%e%' ORDER BY ST_WKTTOSQL(region_point), city; + + region:s | city:s +Americas |Mountain View +Americas |New York +Americas |Phoenix +Asia |Seoul +Asia |Singapore +Asia |Sydney +Europe |Amsterdam +Europe |Berlin ; \ No newline at end of file diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json index d60910d098b40..05abbe6bb1e03 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/geosql.json @@ -16,6 +16,9 @@ }, "shape": { "type": "geo_shape" + }, + "region_point": { + "type": "keyword" } } } diff --git a/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec b/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec index effcb8c90910a..0bb78fa10a04f 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/ogc/ogc.sql-spec @@ -22,3 +22,15 @@ selectNamedPlaces SELECT fid, name, boundary FROM named_places ORDER BY fid; selectMapNeatLines SELECT fid, neatline FROM map_neatlines ORDER BY fid; + +// +// Type conversion functions +// + +// The string serialization is slightly different between ES and H2, so we need to tweak it a bit by uppercasing both +// and removing floating point +selectRoadSegmentsAsWkt +SELECT fid, name, num_lanes, aliases, REPLACE(UCASE(ST_AsText(centerline)), '.0', '') centerline_wkt FROM road_segments ORDER BY fid; + +selectSinglePoint +SELECT ST_GeomFromText('point (10.0 12.0)') point; diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java index b563c4b4c8d5f..b32e2a2a31a1a 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java @@ -215,8 +215,8 @@ private void defineDefaultFunctions() { def(UCase.class, UCase::new)); // Geo Functions - addToMap(def(StAswkt.class, StAswkt::new)); - addToMap(def(StWkttosql.class, StWkttosql::new)); + addToMap(def(StAswkt.class, StAswkt::new, "ST_ASTEXT")); + addToMap(def(StWkttosql.class, StWkttosql::new, "ST_GEOMFROMTEXT")); // DataType conversion addToMap(def(Cast.class, Cast::new, "CONVERT")); // Special diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java index 33441532ac796..83d9ce9c132a7 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessor.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.geo; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; @@ -19,28 +20,28 @@ public class StWkttosqlProcessor implements Processor { public static final String NAME = "geo_wkttosql"; - private StWkttosqlProcessor() { + StWkttosqlProcessor() { } - public StWkttosqlProcessor(StreamInput in) throws IOException {} + public StWkttosqlProcessor(StreamInput in) throws IOException { + } @Override public Object process(Object input) { return StWkttosqlProcessor.apply(input); } - public static GeoShape apply(Object input) { if (input == null) { return null; } if ((input instanceof String) == false) { - throw new SqlIllegalArgumentException("A string is required; received {}", input); + throw new SqlIllegalArgumentException("A string is required; received [{}]", input); } try { return new GeoShape(input); - } catch (IOException ex) { + } catch (IOException | IllegalArgumentException | ElasticsearchParseException ex) { throw new SqlIllegalArgumentException("Cannot parse [{}] as a geo_shape value", input); } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java index 7c778054a0be0..25cf92d3589be 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java @@ -406,7 +406,7 @@ public static String aswktShape(Object v) { return GeoProcessor.GeoOperation.ASWKT_SHAPE.apply(v).toString(); } - public static GeoShape wktToSql(String v) { - return StWkttosqlProcessor.apply(v); + public static GeoShape wktToSql(String wktString) { + return StWkttosqlProcessor.apply(wktString); } } diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessorTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessorTests.java new file mode 100644 index 0000000000000..fc7b33ae905d7 --- /dev/null +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/scalar/geo/StWkttosqlProcessorTests.java @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.expression.function.scalar.geo; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; + +import static org.hamcrest.Matchers.instanceOf; + +public class StWkttosqlProcessorTests extends ESTestCase { + public static StWkttosqlProcessor randomStWkttosqlProcessor() { + return new StWkttosqlProcessor(); + } + + public void testApply() { + StWkttosqlProcessor proc = new StWkttosqlProcessor(); + assertNull(proc.process(null)); + Object result = proc.process("POINT (10 20)"); + assertThat(result, instanceOf(GeoShape.class)); + GeoShape geoShape = (GeoShape) result; + assertEquals("point (10.0 20.0)", geoShape.toString()); + } + + public void testTypeCheck() { + StWkttosqlProcessor procPoint = new StWkttosqlProcessor(); + SqlIllegalArgumentException siae = expectThrows(SqlIllegalArgumentException.class, () -> procPoint.process(42)); + assertEquals("A string is required; received [42]", siae.getMessage()); + + siae = expectThrows(SqlIllegalArgumentException.class, () -> procPoint.process("some random string")); + assertEquals("Cannot parse [some random string] as a geo_shape value", siae.getMessage()); + + siae = expectThrows(SqlIllegalArgumentException.class, () -> procPoint.process("point (foo bar)")); + assertEquals("Cannot parse [point (foo bar)] as a geo_shape value", siae.getMessage()); + + + siae = expectThrows(SqlIllegalArgumentException.class, () -> procPoint.process("point (10 10")); + assertEquals("Cannot parse [point (10 10] as a geo_shape value", siae.getMessage()); + } +} From 68c6fa028c0e550e131f044050c323c9493a0fd8 Mon Sep 17 00:00:00 2001 From: Igor Motov <igor@motovs.org> Date: Tue, 13 Nov 2018 10:46:13 -0500 Subject: [PATCH 3/4] Cast geoshape in docs instead of using ST_AsWKT --- x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec index 9bfd01ce9345c..4444a86e233c8 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/geo/docs.csv-spec @@ -19,7 +19,7 @@ Amsterdam |point (4.850311987102032 52.347556999884546) selectWKTToSQL // tag::wkttosql -SELECT ST_AsWKT(ST_WKTToSQL('POINT (10 20)')) location; +SELECT CAST(ST_WKTToSQL('POINT (10 20)') AS STRING) location; location:s point (10.0 20.0) From 3be14f9e0b5036a461b4387b0d19205daf16cd3d Mon Sep 17 00:00:00 2001 From: Igor Motov <igor@motovs.org> Date: Tue, 13 Nov 2018 12:36:21 -0500 Subject: [PATCH 4/4] Add QueryTranslatorTests --- .../analyzer/FieldAttributeTests.java | 4 +- .../logical/command/sys/SysColumnsTests.java | 12 ++++- .../sql/planner/QueryTranslatorTests.java | 53 +++++++++++++++++++ .../mapping-multi-field-variation.json | 2 + 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/FieldAttributeTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/FieldAttributeTests.java index 9d05d151359fd..dbdadad3a2718 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/FieldAttributeTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/FieldAttributeTests.java @@ -153,7 +153,7 @@ public void testDottedFieldPathTypo() { public void testStarExpansionExcludesObjectAndUnsupportedTypes() { LogicalPlan plan = plan("SELECT * FROM test"); List<? extends NamedExpression> list = ((Project) plan).projections(); - assertThat(list, hasSize(8)); + assertThat(list, hasSize(10)); List<String> names = Expressions.names(list); assertThat(names, not(hasItem("some"))); assertThat(names, not(hasItem("some.dotted"))); @@ -194,4 +194,4 @@ public void testFieldAmbiguity() { assertThat(attribute.qualifier(), is("test")); assertThat(attribute.name(), is("test.test")); } -} \ No newline at end of file +} diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java index 0b82530022386..dd4f33311b42c 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java @@ -17,7 +17,7 @@ public class SysColumnsTests extends ESTestCase { public void testSysColumns() { List<List<?>> rows = new ArrayList<>(); SysColumns.fillInRows("test", "index", TypesTests.loadMapping("mapping-multi-field-variation.json", true), null, rows, null); - assertEquals(16, rows.size()); + assertEquals(18, rows.size()); assertEquals(24, rows.get(0).size()); List<?> row = rows.get(0); @@ -45,13 +45,21 @@ public void testSysColumns() { assertEquals(24, precision(row)); assertEquals(8, bufferLength(row)); + row = rows.get(6); + assertEquals("point", name(row)); + assertEquals(Types.OTHER, sqlType(row)); + row = rows.get(7); + assertEquals("shape", name(row)); + assertEquals(Types.OTHER, sqlType(row)); + + row = rows.get(9); assertEquals("some.dotted", name(row)); assertEquals(Types.STRUCT, sqlType(row)); assertEquals(null, radix(row)); assertEquals(-1, bufferLength(row)); - row = rows.get(15); + row = rows.get(17); assertEquals("some.ambiguous.normalized", name(row)); assertEquals(Types.VARCHAR, sqlType(row)); assertEquals(null, radix(row)); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java index 4423887c16135..120cea0c7894d 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java @@ -34,6 +34,7 @@ import java.util.TimeZone; import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.startsWith; public class QueryTranslatorTests extends ESTestCase { @@ -261,4 +262,56 @@ public void testTranslateInExpression_HavingClause_PainlessAndNullHandling() { assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->")); assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, null, 20, 30]}]")); } + + public void testTranslateStAsWktForPoints() { + LogicalPlan p = plan("SELECT ST_AsWKT(point), ST_AsWKT(shape) FROM test " + + "WHERE ST_AsWKT(point) = 'point (10 20)'"); + assertThat(p, instanceOf(Project.class)); + assertThat(p.children().get(0), instanceOf(Filter.class)); + Expression condition = ((Filter) p.children().get(0)).condition(); + assertFalse(condition.foldable()); + QueryTranslation translation = QueryTranslator.toQuery(condition, true); + assertNull(translation.query); + AggFilter aggFilter = translation.aggFilter; + assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.eq(" + + "InternalSqlScriptUtils.aswktPoint(InternalSqlScriptUtils.docValue(doc,params.v0))," + + "params.v1)" + + ")", + aggFilter.scriptTemplate().toString()); + assertEquals("[{v=point}, {v=point (10 20)}]", aggFilter.scriptTemplate().params().toString()); + } + + public void testTranslateStAsWktForShapes() { + LogicalPlan p = plan("SELECT ST_AsWKT(point), ST_AsWKT(shape) FROM test " + + "WHERE ST_AsWKT(shape) = 'point (10 20)'"); + assertThat(p, instanceOf(Project.class)); + assertThat(p.children().get(0), instanceOf(Filter.class)); + Expression condition = ((Filter) p.children().get(0)).condition(); + assertFalse(condition.foldable()); + QueryTranslation translation = QueryTranslator.toQuery(condition, true); + assertNull(translation.query); + AggFilter aggFilter = translation.aggFilter; + assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.eq(" + + "InternalSqlScriptUtils.aswktShape(InternalSqlScriptUtils.docValue(doc,params.v0))," + + "params.v1)" + + ")", + aggFilter.scriptTemplate().toString()); + assertEquals("[{v=shape}, {v=point (10 20)}]", aggFilter.scriptTemplate().params().toString()); + } + + public void testTranslateStWktToSql() { + LogicalPlan p = plan("SELECT shape FROM test WHERE ST_WKTToSQL(keyword) = ST_WKTToSQL('point (10 20)')"); + assertThat(p, instanceOf(Project.class)); + assertThat(p.children().get(0), instanceOf(Filter.class)); + Expression condition = ((Filter) p.children().get(0)).condition(); + assertFalse(condition.foldable()); + QueryTranslation translation = QueryTranslator.toQuery(condition, true); + assertNull(translation.query); + AggFilter aggFilter = translation.aggFilter; + assertEquals("InternalSqlScriptUtils.nullSafeFilter(" + + "InternalSqlScriptUtils.eq(InternalSqlScriptUtils.wktToSql(" + + "InternalSqlScriptUtils.docValue(doc,params.v0)),params.v1))", + aggFilter.scriptTemplate().toString()); + assertEquals("[{v=keyword}, {v=point (10.0 20.0)}]", aggFilter.scriptTemplate().params().toString()); + } } diff --git a/x-pack/plugin/sql/src/test/resources/mapping-multi-field-variation.json b/x-pack/plugin/sql/src/test/resources/mapping-multi-field-variation.json index 13c9f62b2136e..adc380580ceea 100644 --- a/x-pack/plugin/sql/src/test/resources/mapping-multi-field-variation.json +++ b/x-pack/plugin/sql/src/test/resources/mapping-multi-field-variation.json @@ -6,6 +6,8 @@ "keyword" : { "type" : "keyword" }, "date" : { "type" : "date" }, "unsupported" : { "type" : "ip_range" }, + "point": {"type" : "geo_point"}, + "shape": {"type" : "geo_shape"}, "some" : { "properties" : { "dotted" : {