From 4d16ff310cf4269ed218b6ad5b23e1ecbdcd7bc9 Mon Sep 17 00:00:00 2001 From: Guian Gumpac Date: Thu, 27 Jul 2023 14:52:09 -0700 Subject: [PATCH] Support geopoint type (#309) * Added changes from POC PR Signed-off-by: Guian Gumpac * Added geopoint parser for value factory Signed-off-by: Guian Gumpac * Fixed old tests Signed-off-by: Guian Gumpac * Fixed all old tests Signed-off-by: Guian Gumpac * Removed irrelevant changes Signed-off-by: Guian Gumpac * Removed irrelevant changes Signed-off-by: Guian Gumpac * Added integration tests Signed-off-by: Guian Gumpac * Fixed not throwing exception for geojson Signed-off-by: Guian Gumpac * Made GeoPointValue an ExprTupleValue to enable access to lat and lon Signed-off-by: Guian Gumpac * Fixed checkstyle Signed-off-by: Guian Gumpac * Added unit tests and removed unnecessary code Signed-off-by: Guian Gumpac * reverted irrelevant changes Signed-off-by: Guian Gumpac * Added to docs Signed-off-by: Guian Gumpac * Fixed doc typo Signed-off-by: Guian Gumpac * Test doctests Signed-off-by: Guian Gumpac * Test doctests Signed-off-by: Guian Gumpac * Remove geopoint data from doctests Signed-off-by: Guian Gumpac * Fixed doctest failure Signed-off-by: Guian Gumpac * Fixed doctest failure Signed-off-by: Guian Gumpac * Fix doctest clean up. Signed-off-by: Yury-Fridlyand * Minimized doc example Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Fixed reordering of results Signed-off-by: Guian Gumpac * Added more rows to doctests and removed IOException: Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Fixed doctest Signed-off-by: Guian Gumpac * Addressed PR comments Signed-off-by: Guian Gumpac --------- Signed-off-by: Guian Gumpac Signed-off-by: Yury-Fridlyand Co-authored-by: Yury-Fridlyand --- docs/user/dql/metadata.rst | 3 +- docs/user/general/datatypes.rst | 17 +++ doctest/test_data/geopoint.json | 3 + doctest/test_docs.py | 4 +- doctest/test_mapping/geopoint.json | 9 ++ .../sql/legacy/SQLIntegTestCase.java | 6 +- .../opensearch/sql/legacy/TestsConstants.java | 1 + .../org/opensearch/sql/sql/GeoPointIT.java | 120 ++++++++++++++++++ integ-test/src/test/resources/geo_point.json | 6 + .../indexDefinitions/geo_point_mapping.json | 32 +++++ .../data/type/OpenSearchDataType.java | 2 +- .../data/type/OpenSearchGeoPointType.java | 11 ++ .../data/utils/OpenSearchJsonContent.java | 19 ++- .../value/OpenSearchExprGeoPointValue.java | 50 ++------ .../client/OpenSearchNodeClientTest.java | 4 +- .../client/OpenSearchRestClientTest.java | 4 +- .../data/type/OpenSearchDataTypeTest.java | 2 +- .../OpenSearchExprGeoPointValueTest.java | 27 +--- .../value/OpenSearchExprValueFactoryTest.java | 20 ++- 19 files changed, 262 insertions(+), 78 deletions(-) create mode 100644 doctest/test_data/geopoint.json create mode 100644 doctest/test_mapping/geopoint.json create mode 100644 integ-test/src/test/java/org/opensearch/sql/sql/GeoPointIT.java create mode 100644 integ-test/src/test/resources/geo_point.json create mode 100644 integ-test/src/test/resources/indexDefinitions/geo_point_mapping.json diff --git a/docs/user/dql/metadata.rst b/docs/user/dql/metadata.rst index a02bcf096a..60b8af853b 100644 --- a/docs/user/dql/metadata.rst +++ b/docs/user/dql/metadata.rst @@ -35,7 +35,7 @@ Example 1: Show All Indices Information SQL query:: os> SHOW TABLES LIKE '%' - fetched rows / total rows = 9/9 + fetched rows / total rows = 10/10 +----------------+---------------+-----------------+--------------+-----------+------------+--------------+-------------+-----------------------------+------------------+ | TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_CAT | TYPE_SCHEM | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION | |----------------+---------------+-----------------+--------------+-----------+------------+--------------+-------------+-----------------------------+------------------| @@ -44,6 +44,7 @@ SQL query:: | docTestCluster | null | accounts | BASE TABLE | null | null | null | null | null | null | | docTestCluster | null | apache | BASE TABLE | null | null | null | null | null | null | | docTestCluster | null | books | BASE TABLE | null | null | null | null | null | null | + | docTestCluster | null | geopoint | BASE TABLE | null | null | null | null | null | null | | docTestCluster | null | nested | BASE TABLE | null | null | null | null | null | null | | docTestCluster | null | nyc_taxi | BASE TABLE | null | null | null | null | null | null | | docTestCluster | null | people | BASE TABLE | null | null | null | null | null | null | diff --git a/docs/user/general/datatypes.rst b/docs/user/general/datatypes.rst index a265ffd4c9..fcb0c4accd 100644 --- a/docs/user/general/datatypes.rst +++ b/docs/user/general/datatypes.rst @@ -103,6 +103,8 @@ The table below list the mapping between OpenSearch Data Type, OpenSearch SQL Da +-----------------+---------------------+-----------+ | nested | array | STRUCT | +-----------------+---------------------+-----------+ +| geo_point | geo_point | STRUCT | ++-----------------+---------------------+-----------+ Notes: * Not all the OpenSearch SQL Type has correspond OpenSearch Type. e.g. data and time. To use function which required such data type, user should explicitly convert the data type. @@ -456,3 +458,18 @@ A boolean can be represented by constant value ``TRUE`` or ``FALSE``. Besides, c |--------+---------+---------------------------+----------------------------| | True | False | True | False | +--------+---------+---------------------------+----------------------------+ + +Geopoint Data Types +================== + +A geopoint has a latitude and a longitude property. Although OpenSearch `supports multiple formats `_, the SQL plugin currently only supports the format :code:`{"lat": number, "lon": number}`. The geopoint object can be queried or lat and lon can be specified using dot notation. For example, :: + + os> SELECT geo_point_object, geo_point_object.lat, geo_point_object.lon FROM geopoint; + fetched rows / total rows = 3/3 + +----------------------------------+------------------------+------------------------+ + | geo_point_object | geo_point_object.lat | geo_point_object.lon | + |----------------------------------+------------------------+------------------------| + | {'lat': 40.71, 'lon': 74.0} | 40.71 | 74.0 | + | {'lat': -33.852, 'lon': 151.216} | -33.852 | 151.216 | + | null | null | null | + +----------------------------------+------------------------+------------------------+ diff --git a/doctest/test_data/geopoint.json b/doctest/test_data/geopoint.json new file mode 100644 index 0000000000..26f49506fb --- /dev/null +++ b/doctest/test_data/geopoint.json @@ -0,0 +1,3 @@ +{"geo_point_object": {"lat": 40.71, "lon": 74.00}} +{"geo_point_object": {"lat": -33.852, "lon": 151.216}} +{"geo_point_object": null} diff --git a/doctest/test_docs.py b/doctest/test_docs.py index 1fedbdf49e..93953cf73b 100644 --- a/doctest/test_docs.py +++ b/doctest/test_docs.py @@ -28,6 +28,7 @@ APACHE = "apache" WILDCARD = "wildcard" NESTED = "nested" +GEOPOINT = "geopoint" DATASOURCES = ".ql-datasources" @@ -97,6 +98,7 @@ def set_up_test_indices(test): load_file("apache.json", index_name=APACHE) load_file("wildcard.json", index_name=WILDCARD) load_file("nested_objects.json", index_name=NESTED) + load_file("geopoint.json", index_name=GEOPOINT) load_file("datasources.json", index_name=DATASOURCES) @@ -126,7 +128,7 @@ def set_up(test): def tear_down(test): # drop leftover tables after each test - test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED], ignore_unavailable=True) + test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED, GEOPOINT], ignore_unavailable=True) docsuite = partial(doctest.DocFileSuite, diff --git a/doctest/test_mapping/geopoint.json b/doctest/test_mapping/geopoint.json new file mode 100644 index 0000000000..034ad6184d --- /dev/null +++ b/doctest/test_mapping/geopoint.json @@ -0,0 +1,9 @@ +{ + "mappings": { + "properties": { + "geo_point_object": { + "type": "geo_point" + } + } + } +} diff --git a/integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java b/integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java index 7216c03d08..8a78cec91e 100644 --- a/integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java +++ b/integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java @@ -681,7 +681,11 @@ public enum Index { NESTED_WITH_NULLS(TestsConstants.TEST_INDEX_NESTED_WITH_NULLS, "multi_nested", getNestedTypeIndexMapping(), - "src/test/resources/nested_with_nulls.json"); + "src/test/resources/nested_with_nulls.json"), + GEOPOINT(TestsConstants.TEST_INDEX_GEOPOINT, + "geopoint", + getMappingFile("geo_point_mapping.json"), + "src/test/resources/geo_point.json"); private final String name; private final String type; diff --git a/integ-test/src/test/java/org/opensearch/sql/legacy/TestsConstants.java b/integ-test/src/test/java/org/opensearch/sql/legacy/TestsConstants.java index 338be25a0c..0d7376786a 100644 --- a/integ-test/src/test/java/org/opensearch/sql/legacy/TestsConstants.java +++ b/integ-test/src/test/java/org/opensearch/sql/legacy/TestsConstants.java @@ -60,6 +60,7 @@ public class TestsConstants { public final static String TEST_INDEX_WILDCARD = TEST_INDEX + "_wildcard"; public final static String TEST_INDEX_MULTI_NESTED_TYPE = TEST_INDEX + "_multi_nested"; public final static String TEST_INDEX_NESTED_WITH_NULLS = TEST_INDEX + "_nested_with_nulls"; + public final static String TEST_INDEX_GEOPOINT = TEST_INDEX + "_geopoint"; public final static String DATASOURCES = ".ql-datasources"; public final static String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; diff --git a/integ-test/src/test/java/org/opensearch/sql/sql/GeoPointIT.java b/integ-test/src/test/java/org/opensearch/sql/sql/GeoPointIT.java new file mode 100644 index 0000000000..e738418290 --- /dev/null +++ b/integ-test/src/test/java/org/opensearch/sql/sql/GeoPointIT.java @@ -0,0 +1,120 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.sql.sql; + +import org.json.JSONObject; +import org.junit.Test; +import org.opensearch.sql.legacy.SQLIntegTestCase; + +import java.util.Map; + +import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_GEOPOINT; +import static org.opensearch.sql.util.MatcherUtils.rows; +import static org.opensearch.sql.util.MatcherUtils.verifyDataRows; + +public class GeoPointIT extends SQLIntegTestCase { + @Override + protected void init() throws Exception { + loadIndex(Index.GEOPOINT); + } + + @Test + public void test_geo_point() { + String query = "SELECT geo_point_object FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows(new JSONObject(Map.of( + "lat", 40.71, + "lon", 74))), + rows(new JSONObject(Map.of( + "lat", -33.85253637358241, + "lon", 151.21652352950258))), + rows(JSONObject.NULL) + ); + } + + @Test + public void test_geo_point_unsupported_format() { + String query = "SELECT geo_point_geohash FROM " + TEST_INDEX_GEOPOINT; + Exception exception = assertThrows(RuntimeException.class, + () -> executeJdbcRequest(query)); + + assertTrue(exception.getMessage().contains( + " \"error\": {\n" + + " \"reason\": \"There was internal problem at backend\",\n" + + " \"details\": \"geo point must be in format of {\\\"lat\\\": number, \\\"lon\\\": number}\",\n" + + " \"type\": \"IllegalStateException\"\n" + + " }" + )); + } + + @Test + public void test_geo_point_in_objects() { + String query = "SELECT object.geo_point_object FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows( + (new JSONObject(Map.of( + "lat", 40.71, + "lon", 74)))), + rows(new JSONObject(Map.of( + "lat", -33.85253637358241, + "lon", 151.21652352950258))), + rows(JSONObject.NULL) + ); + } + + @Test + public void test_geo_point_lat_in_objects() { + String query = "SELECT object.geo_point_object.lat FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows(40.71), + rows( -33.85253637358241), + rows(JSONObject.NULL) + ); + } + + @Test + public void test_geo_point_lat_and_lon() { + String query = "SELECT geo_point_object.lat, geo_point_object.lon FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows(40.71, 74), + rows(-33.85253637358241, 151.21652352950258), + rows(JSONObject.NULL, JSONObject.NULL) + ); + } + + @Test + public void test_geo_point_object_with_lat_and_lon() { + String query = "SELECT geo_point_object, geo_point_object.lat," + + " geo_point_object.lon FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows(new JSONObject(Map.of( + "lat", 40.71, + "lon", 74)), + 40.71, 74), + rows(new JSONObject(Map.of( + "lat", -33.85253637358241, + "lon", 151.21652352950258)), + -33.85253637358241, 151.21652352950258), + rows(JSONObject.NULL, JSONObject.NULL, JSONObject.NULL) + ); + } + + @Test + public void test_geo_point_lat_in_functions() { + String query = "SELECT ABS(geo_point_object.lat) FROM " + TEST_INDEX_GEOPOINT; + JSONObject result = executeJdbcRequest(query); + verifyDataRows(result, + rows(40.71), + rows(33.85253637358241), + rows(JSONObject.NULL) + ); + } +} diff --git a/integ-test/src/test/resources/geo_point.json b/integ-test/src/test/resources/geo_point.json new file mode 100644 index 0000000000..4ba2d27828 --- /dev/null +++ b/integ-test/src/test/resources/geo_point.json @@ -0,0 +1,6 @@ +{"index":{"_id":"1"}} +{"geo_point_object": {"lat": 40.71, "lon": 74.00}, "object": {"geo_point_object": {"lat": 40.71, "lon": 74.00}}, "geo_point_string": "40.71, 74.00", "geo_point_geohash": "txhxegj0uyp3", "geo_point_array": [74.00, 40.71], "geo_point_string_point": "POINT (74.00 40.71)", "geo_point_geojson": {"type": "Point", "coordinates": [74.00, 40.71]}} +{"index":{"_id":"2"}} +{"geo_point_object": {"lat": -33.85253637358241, "lon": 151.21652352950258}, "object": {"geo_point_object": {"lat": -33.85253637358241, "lon": 151.21652352950258}},"geo_point_string": "-33.85356510743158, 151.22222172610114", "geo_point_geohash": "txhxegj0uyp3", "geo_point_array": [74.00, 40.71], "geo_point_string_point": "POINT (74.00 40.71)", "geo_point_geojson": {"type": "Point", "coordinates": [74.00, 40.71]}} +{"index":{"_id":"3"}} +{"geo_point_object": null, "object": {"geo_point_object": null},"geo_point_string": null, "geo_point_geohash": null, "geo_point_array": null, "geo_point_string_point": null, "geo_point_geojson": null} diff --git a/integ-test/src/test/resources/indexDefinitions/geo_point_mapping.json b/integ-test/src/test/resources/indexDefinitions/geo_point_mapping.json new file mode 100644 index 0000000000..8dc92fe5c4 --- /dev/null +++ b/integ-test/src/test/resources/indexDefinitions/geo_point_mapping.json @@ -0,0 +1,32 @@ +{ + "mappings": { + "properties": { + "geo_point_object": { + "type": "geo_point" + }, + "object": { + "type": "object", + "properties": { + "geo_point_object": { + "type": "geo_point" + } + } + }, + "geo_point_string": { + "type": "geo_point" + }, + "geo_point_geohash": { + "type": "geo_point" + }, + "geo_point_array": { + "type": "geo_point" + }, + "geo_point_string_point": { + "type": "geo_point" + }, + "geo_point_geojson": { + "type": "geo_point" + } + } + } +} diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataType.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataType.java index 273b980d2a..770518e54d 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataType.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataType.java @@ -46,7 +46,7 @@ public enum MappingType { ScaledFloat("scaled_float", ExprCoreType.DOUBLE), Double("double", ExprCoreType.DOUBLE), Boolean("boolean", ExprCoreType.BOOLEAN); - // TODO: ranges, geo shape, point, shape + // TODO: ranges, geo shape, shape private final String name; diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchGeoPointType.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchGeoPointType.java index c2428a59a8..4bccee43ab 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchGeoPointType.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/type/OpenSearchGeoPointType.java @@ -8,7 +8,11 @@ import static org.opensearch.sql.data.type.ExprCoreType.UNKNOWN; +import java.util.HashMap; +import java.util.Map; import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.opensearch.sql.data.type.ExprCoreType; /** * The type of a geo_point value. See @@ -22,8 +26,15 @@ public class OpenSearchGeoPointType extends OpenSearchDataType { private OpenSearchGeoPointType() { super(MappingType.GeoPoint); exprCoreType = UNKNOWN; + this.properties = new HashMap<>(); + this.properties.put("lat", new OpenSearchDataType(ExprCoreType.DOUBLE)); + this.properties.put("lon", new OpenSearchDataType(ExprCoreType.DOUBLE)); } + @Getter + @EqualsAndHashCode.Exclude + Map properties; + public static OpenSearchGeoPointType of() { return OpenSearchGeoPointType.instance; } diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/utils/OpenSearchJsonContent.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/utils/OpenSearchJsonContent.java index 61da7c3b74..6cac6de3b6 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/utils/OpenSearchJsonContent.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/utils/OpenSearchJsonContent.java @@ -126,9 +126,10 @@ public Object objectValue() { @Override public Pair geoValue() { final JsonNode value = value(); - if (value.has("lat") && value.has("lon")) { - Double lat = 0d; - Double lon = 0d; + Double lat = null; + Double lon = null; + + if (value.has("lat")) { try { lat = extractDoubleValue(value.get("lat")); } catch (Exception exception) { @@ -136,6 +137,9 @@ public Pair geoValue() { "latitude must be number value, but got value: " + value.get( "lat")); } + } + + if (value.has("lon")) { try { lon = extractDoubleValue(value.get("lon")); } catch (Exception exception) { @@ -143,11 +147,14 @@ public Pair geoValue() { "longitude must be number value, but got value: " + value.get( "lon")); } - return Pair.of(lat, lon); - } else { - throw new IllegalStateException("geo point must in format of {\"lat\": number, \"lon\": " + } + + if (lat == null && lon == null) { + throw new IllegalStateException("geo point must be in format of {\"lat\": number, \"lon\": " + "number}"); } + + return Pair.of(lat, lon); } /** diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValue.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValue.java index 72f7f4a4f2..a15272f594 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValue.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValue.java @@ -6,10 +6,10 @@ package org.opensearch.sql.opensearch.data.value; -import java.util.Objects; -import lombok.Data; -import org.opensearch.sql.data.model.AbstractExprValue; -import org.opensearch.sql.data.model.ExprValue; +import com.google.common.collect.ImmutableMap; +import java.util.LinkedHashMap; +import org.opensearch.sql.data.model.ExprDoubleValue; +import org.opensearch.sql.data.model.ExprTupleValue; import org.opensearch.sql.data.type.ExprType; import org.opensearch.sql.opensearch.data.type.OpenSearchGeoPointType; @@ -17,45 +17,21 @@ * OpenSearch GeoPointValue. * Todo, add this to avoid the unknown value type exception, the implementation will be changed. */ -public class OpenSearchExprGeoPointValue extends AbstractExprValue { - - private final GeoPoint geoPoint; +public class OpenSearchExprGeoPointValue extends ExprTupleValue { + /** + * Constructor for OpenSearchExprGeoPointValue. + * @param lat double value of latitude property of geo_point + * @param lon double value of longitude property of geo_point + */ public OpenSearchExprGeoPointValue(Double lat, Double lon) { - this.geoPoint = new GeoPoint(lat, lon); - } - - @Override - public Object value() { - return geoPoint; + super(new LinkedHashMap<>(ImmutableMap.of( + "lat", new ExprDoubleValue(lat), + "lon", new ExprDoubleValue(lon)))); } @Override public ExprType type() { return OpenSearchGeoPointType.of(); } - - @Override - public int compare(ExprValue other) { - return geoPoint.toString() - .compareTo((((OpenSearchExprGeoPointValue) other).geoPoint).toString()); - } - - @Override - public boolean equal(ExprValue other) { - return geoPoint.equals(((OpenSearchExprGeoPointValue) other).geoPoint); - } - - @Override - public int hashCode() { - return Objects.hashCode(geoPoint); - } - - @Data - public static class GeoPoint { - - private final Double lat; - - private final Double lon; - } } diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java index 9417a1de1d..ad4b92cc9f 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java @@ -169,9 +169,9 @@ void get_index_mappings() throws IOException { var parsedTypes = OpenSearchDataType.traverseAndFlatten(mapping); assertAll( () -> assertEquals(1, indexMappings.size()), - // 10 types extended to 17 after flattening + // 10 types extended to 19 after flattening () -> assertEquals(10, mapping.size()), - () -> assertEquals(17, parsedTypes.size()), + () -> assertEquals(19, parsedTypes.size()), () -> assertEquals("TEXT", mapping.get("address").legacyTypeName()), () -> assertEquals(OpenSearchTextType.of(MappingType.Text), parsedTypes.get("address")), diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java index 7f968733c1..e2bf48d368 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java @@ -163,9 +163,9 @@ void get_index_mappings() throws IOException { var parsedTypes = OpenSearchDataType.traverseAndFlatten(mapping); assertAll( () -> assertEquals(1, indexMappings.size()), - // 10 types extended to 17 after flattening + // 10 types extended to 19 after flattening () -> assertEquals(10, mapping.size()), - () -> assertEquals(17, parsedTypes.size()), + () -> assertEquals(19, parsedTypes.size()), () -> assertEquals("TEXT", mapping.get("address").legacyTypeName()), () -> assertEquals(OpenSearchTextType.of(MappingType.Text), parsedTypes.get("address")), diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataTypeTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataTypeTest.java index 8d69b3d855..20e6f5eeb4 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataTypeTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/type/OpenSearchDataTypeTest.java @@ -291,7 +291,7 @@ public void traverseAndFlatten() { var flattened = OpenSearchDataType.traverseAndFlatten(getSampleMapping()); var objectType = OpenSearchDataType.of(MappingType.Object); assertAll( - () -> assertEquals(9, flattened.size()), + () -> assertEquals(11, flattened.size()), () -> assertTrue(flattened.get("mapping").getProperties().isEmpty()), () -> assertTrue(flattened.get("mapping.submapping").getProperties().isEmpty()), () -> assertTrue( diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValueTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValueTest.java index 4edb25aff5..38e0b29702 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValueTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprGeoPointValueTest.java @@ -7,20 +7,15 @@ package org.opensearch.sql.opensearch.data.value; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import com.google.common.collect.ImmutableMap; +import java.util.LinkedHashMap; import org.junit.jupiter.api.Test; import org.opensearch.sql.opensearch.data.type.OpenSearchGeoPointType; class OpenSearchExprGeoPointValueTest { - private OpenSearchExprGeoPointValue geoPointValue = new OpenSearchExprGeoPointValue(1.0, 1.0); - - @Test - void value() { - assertEquals(new OpenSearchExprGeoPointValue.GeoPoint(1.0, 1.0), geoPointValue.value()); - } + private OpenSearchExprGeoPointValue geoPointValue = new OpenSearchExprGeoPointValue(1.0, 2.0); @Test void type() { @@ -28,18 +23,8 @@ void type() { } @Test - void compare() { - assertEquals(0, geoPointValue.compareTo(new OpenSearchExprGeoPointValue(1.0, 1.0))); - assertEquals(geoPointValue, new OpenSearchExprGeoPointValue(1.0, 1.0)); - } - - @Test - void equal() { - assertTrue(geoPointValue.equal(new OpenSearchExprGeoPointValue(1.0, 1.0))); - } - - @Test - void testHashCode() { - assertNotNull(geoPointValue.hashCode()); + void value() { + assertEquals(new LinkedHashMap<>(ImmutableMap.of("lat", 1.0, "lon", 2.0)), + geoPointValue.value()); } } diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java index 827606a961..e8873bb741 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java @@ -59,6 +59,7 @@ import org.opensearch.sql.opensearch.data.type.OpenSearchDataType; import org.opensearch.sql.opensearch.data.type.OpenSearchDateType; import org.opensearch.sql.opensearch.data.type.OpenSearchTextType; +import org.opensearch.sql.opensearch.data.utils.ObjectContent; import org.opensearch.sql.opensearch.data.utils.OpenSearchJsonContent; class OpenSearchExprValueFactoryTest { @@ -725,24 +726,33 @@ public void constructGeoPoint() { constructFromObject("geoV", "42.60355556,-97.25263889")); } + @Test + public void constructGeoPointLat() { + assertEquals(doubleValue(42.60355556), + tupleValue("{\"geoV\":{\"lat\":42.60355556}}").get("geoV").tupleValue().get("lat")); + assertEquals(doubleValue(-97.25263889), + tupleValue("{\"geoV\":{\"lon\":-97.25263889}}").get("geoV").tupleValue().get("lon")); + } + @Test public void constructGeoPointFromUnsupportedFormatShouldThrowException() { IllegalStateException exception = assertThrows(IllegalStateException.class, () -> tupleValue("{\"geoV\":[42.60355556,-97.25263889]}").get("geoV")); - assertEquals("geo point must in format of {\"lat\": number, \"lon\": number}", + assertEquals("geo point must be in format of {\"lat\": number, \"lon\": number}", exception.getMessage()); exception = assertThrows(IllegalStateException.class, - () -> tupleValue("{\"geoV\":{\"lon\":-97.25263889}}").get("geoV")); - assertEquals("geo point must in format of {\"lat\": number, \"lon\": number}", + () -> tupleValue("{\"geoV\":\"txhxegj0uyp3\"}").get("geoV")); + assertEquals("geo point must be in format of {\"lat\": number, \"lon\": number}", exception.getMessage()); exception = assertThrows(IllegalStateException.class, - () -> tupleValue("{\"geoV\":{\"lat\":-97.25263889}}").get("geoV")); - assertEquals("geo point must in format of {\"lat\": number, \"lon\": number}", + () -> tupleValue("{\"geoV\":{\"type\": \"Point\"," + + " \"coordinates\": [74.00, 40.71]}}").get("geoV")); + assertEquals("geo point must be in format of {\"lat\": number, \"lon\": number}", exception.getMessage()); exception =