Skip to content

Commit

Permalink
SQL: Switch JDBC driver to libs/geo objects for geo_shapes (#39204)
Browse files Browse the repository at this point in the history
Switches JDBC driver to use libs/geo objects when server returns a
geo_shape.
  • Loading branch information
imotov authored Feb 27, 2019
1 parent 3a0411f commit 44542b0
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 13 deletions.
4 changes: 2 additions & 2 deletions docs/reference/sql/functions/geo.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ include-tagged::{sql-specs}/geo/docs.csv-spec[aswkt]
--------------------------------------------------


[[sql-functions-geo-st-as-wkt]]
===== `ST_AsWKT`
[[sql-functions-geo-st-wkt-to-sql]]
===== `ST_WKTToSQL`

.Synopsis:
[source, sql]
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugin/sql/jdbc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ dependencies {
compile (project(':libs:x-content')) {
transitive = false
}
compile (project(':libs:elasticsearch-geo')) {
transitive = false
}
compile project(':libs:core')
runtime "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
testCompile "org.elasticsearch.test:framework:${version}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
*/
package org.elasticsearch.xpack.sql.jdbc;

import org.elasticsearch.geo.utils.WellKnownText;
import org.elasticsearch.xpack.sql.proto.StringUtils;

import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -234,8 +237,13 @@ static Object convert(Object v, EsType columnType, String typeString) throws SQL
case INTERVAL_MINUTE_TO_SECOND:
return Duration.parse(v.toString());
case GEO_POINT:
case GEO_SHAPE:
return v;
case GEO_SHAPE:
try {
return WellKnownText.fromWKT(v.toString());
} catch (IOException | ParseException ex) {
throw new SQLException("Cannot parse geo_shape", ex);
}
default:
throw new SQLException("Unexpected column type [" + typeString + "]");

Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugin/sql/qa/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ dependencies {
compile project(path: xpackModule('sql:sql-cli'), configuration: 'nodeps')
compile "org.jline:jline:3.8.2"
compile "org.orbisgis:h2gis-ext:1.3.2"
// TODO: Temporary solution until core removes JTS as a dependency
compile "com.vividsolutions:jts-core:1.14.0"
}

/* disable unit tests because these are all integration tests used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ public abstract class GeoSqlSpecTestCase extends SpecBaseIntegrationTestCase {
// Load GIS extensions
H2GISExtension.load(c);
c.createStatement().execute("RUNSCRIPT FROM 'classpath:/ogc/sqltsch.sql'");
c.createStatement().execute("RUNSCRIPT FROM 'classpath:/geo/setup_test_geo.sql'");
});

@ParametersFactory(argumentFormatting = PARAM_FORMATTING)
public static List<Object[]> readScriptSpec() throws Exception {
Parser parser = new SqlSpecParser();
List<Object[]> tests = new ArrayList<>();
tests.addAll(readScriptSpec("/ogc/ogc.sql-spec", parser));
tests.addAll(readScriptSpec("/geo/geosql.sql-spec", parser));
return tests;
}

Expand All @@ -51,6 +53,9 @@ public void setupTestGeoDataIfNeeded() throws Exception {
if (client().performRequest(new Request("HEAD", "/ogc")).getStatusLine().getStatusCode() == 404) {
GeoDataLoader.loadOGCDatasetIntoEs(client(), "ogc");
}
if (client().performRequest(new Request("HEAD", "/geo")).getStatusLine().getStatusCode() == 404) {
GeoDataLoader.loadGeoDatasetIntoEs(client(), "geo");
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
*/
package org.elasticsearch.xpack.sql.qa.jdbc;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import com.carrotsearch.hppc.IntObjectHashMap;

import org.apache.logging.log4j.Logger;
import org.elasticsearch.geo.geometry.Geometry;
import org.elasticsearch.geo.utils.WellKnownText;
import org.elasticsearch.xpack.sql.jdbc.EsType;
import org.elasticsearch.xpack.sql.proto.StringUtils;
import org.relique.jdbc.csv.CsvResultSet;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.text.ParseException;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.Calendar;
Expand All @@ -45,7 +46,6 @@
*/
public class JdbcAssert {
private static final Calendar UTC_CALENDAR = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
private static final WKTReader wkt = new WKTReader();

private static final IntObjectHashMap<EsType> SQL_TO_TYPE = new IntObjectHashMap<>();

Expand Down Expand Up @@ -269,11 +269,11 @@ else if (type == Types.DOUBLE) {
} else if (type == Types.FLOAT) {
assertEquals(msg, (float) expectedObject, (float) actualObject, lenientFloatingNumbers ? 1f : 0.0f);
} else if (type == Types.OTHER) {
if (expectedObject instanceof Geometry && actualObject instanceof String) {
// We need to convert the actual object to Geometry for comparision
if (actualObject instanceof Geometry) {
// We need to convert the expected object to libs/geo Geometry for comparision
try {
actualObject = wkt.read(actualObject.toString());
} catch (ParseException ex) {
expectedObject = WellKnownText.fromWKT(expectedObject.toString());
} catch (IOException | ParseException ex) {
fail(ex.getMessage());
}
}
Expand Down
16 changes: 16 additions & 0 deletions x-pack/plugin/sql/qa/src/main/resources/geo/geo.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
city,region,region_point,shape
Mountain View,Americas,POINT(-105.2551 54.5260),point (-122.083843 37.386483)
Chicago,Americas,POINT(-105.2551 54.5260),point (-87.637874 41.888783)
New York,Americas,POINT(-105.2551 54.5260),point (-73.990027 40.745171)
San Francisco,Americas,POINT(-105.2551 54.5260),point (-122.394228 37.789541)
Phoenix,Americas,POINT(-105.2551 54.5260),point (-111.973505 33.376242)
Amsterdam,Europe,POINT(15.2551 54.5260),point (4.850312 52.347557)
Berlin,Europe,POINT(15.2551 54.5260),point (13.390889 52.486701)
Munich,Europe,POINT(15.2551 54.5260),point (11.537505 48.146321)
London,Europe,POINT(15.2551 54.5260),point (-0.121672 51.510871)
Paris,Europe,POINT(15.2551 54.5260),point (2.351773 48.845538)
Singapore,Asia,POINT(100.6197 34.0479),point (103.855535 1.295868)
Hong Kong,Asia,POINT(100.6197 34.0479),point (114.183925 22.281397)
Seoul,Asia,POINT(100.6197 34.0479),point (127.060851 37.509132)
Tokyo,Asia,POINT(100.6197 34.0479),point (139.76402225 35.669616)
Sydney,Asia,POINT(100.6197 34.0479),point (151.208629 -33.863385)
18 changes: 18 additions & 0 deletions x-pack/plugin/sql/qa/src/main/resources/geo/geosql.sql-spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Commands on geo test data
//

selectAllPointsAsStrings
SELECT city, shape, region FROM "geo" ORDER BY "city";

selectAllPointsAsWKT
SELECT city, ST_GEOMFROMTEXT(ST_ASWKT(shape)) shape_wkt, region FROM "geo" ORDER BY "city";

selectRegionUsingWktToSqlWithoutConvertion
SELECT region, city, shape, ST_GEOMFROMTEXT(region_point) region_wkt FROM geo ORDER BY region, city;

selectCitiesWithAGroupByWktToSql
SELECT COUNT(city) city_by_region, ST_GEOMFROMTEXT(region_point) region_geom FROM geo WHERE city LIKE '%a%' GROUP BY region_geom ORDER BY city_by_region;

selectCitiesWithEOrderByWktToSql
SELECT region, city, UCASE(ST_ASWKT(ST_GEOMFROMTEXT(region_point))) region_wkt FROM geo WHERE city LIKE '%e%' ORDER BY region_wkt, city;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP TABLE IF EXISTS "geo";
CREATE TABLE "geo" (
"city" VARCHAR(50),
"region" VARCHAR(50),
"region_point" VARCHAR(50),
"shape" GEOMETRY
)
AS SELECT * FROM CSVREAD('classpath:/geo/geo.csv');

0 comments on commit 44542b0

Please sign in to comment.