diff --git a/docs/src/main/sphinx/functions/geospatial.md b/docs/src/main/sphinx/functions/geospatial.md index 1ad25203ede33..8b02504951abe 100644 --- a/docs/src/main/sphinx/functions/geospatial.md +++ b/docs/src/main/sphinx/functions/geospatial.md @@ -61,7 +61,7 @@ Returns a geometry type object from WKT representation. ::: :::{function} ST_GeomFromBinary(varbinary) -> Geometry -Returns a geometry type object from WKB representation. +Returns a geometry type object from WKB or EWKB representation. ::: :::{function} geometry_from_hadoop_shape(varbinary) -> Geometry diff --git a/plugin/trino-geospatial/src/main/java/io/trino/plugin/geospatial/GeoFunctions.java b/plugin/trino-geospatial/src/main/java/io/trino/plugin/geospatial/GeoFunctions.java index 5c217d2a66d9f..0348c91a3dfc5 100644 --- a/plugin/trino-geospatial/src/main/java/io/trino/plugin/geospatial/GeoFunctions.java +++ b/plugin/trino-geospatial/src/main/java/io/trino/plugin/geospatial/GeoFunctions.java @@ -62,6 +62,8 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKBReader; import org.locationtech.jts.linearref.LengthIndexedLine; import org.locationtech.jts.operation.distance.DistanceOp; @@ -175,6 +177,8 @@ public final class GeoFunctions private static final EnumSet VALID_TYPES_FOR_ST_POINTS = EnumSet.of( LINE_STRING, POLYGON, POINT, MULTI_POINT, MULTI_LINE_STRING, MULTI_POLYGON, GEOMETRY_COLLECTION); + private static final WKBReader WKB_READER = new WKBReader(); + private GeoFunctions() {} @Description("Returns a Geometry type LineString object from Well-Known Text representation (WKT)") @@ -1538,18 +1542,15 @@ private static OGCGeometry geometryFromText(Slice input) return geometry; } - private static OGCGeometry geomFromBinary(Slice input) + private static Geometry geomFromBinary(Slice input) { requireNonNull(input, "input is null"); - OGCGeometry geometry; try { - geometry = OGCGeometry.fromBinary(input.toByteBuffer().slice()); + return WKB_READER.read(input.getBytes()); } - catch (IllegalArgumentException | IndexOutOfBoundsException e) { + catch (ParseException e) { throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid WKB", e); } - geometry.setSpatialReference(null); - return geometry; } private static ByteBuffer getShapeByteBuffer(Slice input) diff --git a/plugin/trino-geospatial/src/test/java/io/trino/plugin/geospatial/TestGeoFunctions.java b/plugin/trino-geospatial/src/test/java/io/trino/plugin/geospatial/TestGeoFunctions.java index 51b15225925db..ff70ab54b965e 100644 --- a/plugin/trino-geospatial/src/test/java/io/trino/plugin/geospatial/TestGeoFunctions.java +++ b/plugin/trino-geospatial/src/test/java/io/trino/plugin/geospatial/TestGeoFunctions.java @@ -2159,6 +2159,12 @@ public void testSTGeometryFromBinary() assertGeomFromBinary("MULTIPOLYGON (((1 1, 3 1, 3 3, 1 3, 1 1)), ((2 4, 6 4, 6 6, 2 6, 2 4)))"); assertGeomFromBinary("GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (0 0, 1 2, 3 4), POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)))"); + // The EWKB representation of "SRID=4326;POINT (1 1)". + assertThat(assertions.expression("ST_AsText(ST_GeomFromBinary(wkb))") + .binding("wkb", "x'0101000020E6100000000000000000F03F000000000000F03F'")) + .hasType(VARCHAR) + .isEqualTo("POINT (1 1)"); + // array of geometries assertThat(assertions.expression("transform(a, wkb -> ST_AsText(ST_GeomFromBinary(wkb)))") .binding("a", "ARRAY[ST_AsBinary(ST_Point(1, 2)), ST_AsBinary(ST_Point(3, 4))]"))