From 0733ef6f92043a03d99dc46a4ddf1237279d6296 Mon Sep 17 00:00:00 2001 From: Uros Bojanic Date: Wed, 15 Oct 2025 19:14:56 +0200 Subject: [PATCH] Initial commit --- .../org/apache/spark/sql/types/DataTypes.java | 36 +++++++ .../sql/types/JavaGeographyTypeSuite.java | 97 ++++++++++++++++++ .../sql/types/JavaGeometryTypeSuite.java | 98 +++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeographyTypeSuite.java create mode 100644 sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeometryTypeSuite.java diff --git a/sql/api/src/main/java/org/apache/spark/sql/types/DataTypes.java b/sql/api/src/main/java/org/apache/spark/sql/types/DataTypes.java index 0034b8e715183..a32a27602f0a3 100644 --- a/sql/api/src/main/java/org/apache/spark/sql/types/DataTypes.java +++ b/sql/api/src/main/java/org/apache/spark/sql/types/DataTypes.java @@ -94,6 +94,42 @@ public class DataTypes { */ public static final DataType ShortType = ShortType$.MODULE$; + /** + * Creates a GeographyType by specifying the SRID value. + * + * @since 4.1.0 + */ + public static GeographyType createGeographyType(int srid) { + return GeographyType$.MODULE$.apply(srid); + } + + /** + * Creates a GeographyType by specifying the CRS value. + * + * @since 4.1.0 + */ + public static GeographyType createGeographyType(String crs) { + return GeographyType$.MODULE$.apply(crs); + } + + /** + * Creates a GeometryType by specifying the SRID value. + * + * @since 4.1.0 + */ + public static GeometryType createGeometryType(int srid) { + return GeometryType$.MODULE$.apply(srid); + } + + /** + * Creates a GeometryType by specifying the CRS value. + * + * @since 4.1.0 + */ + public static GeometryType createGeometryType(String crs) { + return GeometryType$.MODULE$.apply(crs); + } + /** * Gets the NullType object. */ diff --git a/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeographyTypeSuite.java b/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeographyTypeSuite.java new file mode 100644 index 0000000000000..39ecd3893c7f0 --- /dev/null +++ b/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeographyTypeSuite.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.spark.sql.types; + +import org.apache.spark.sql.internal.types.SpatialReferenceSystemMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.apache.spark.SparkIllegalArgumentException; + +import java.util.stream.Stream; + +public class JavaGeographyTypeSuite { + + /* + * Test cases GeographyType construction based on SRID. + */ + + @Test + public void geographyTypeWithSpecifiedValidSridTest() { + // Valid SRID values for GEOGRAPHY. Note that only 4326 is supported for now. + Stream.of(4326).forEach(srid -> { + DataType geographyType = DataTypes.createGeographyType(srid); + Assertions.assertEquals("GEOGRAPHY(" + srid + ")", geographyType.sql()); + Assertions.assertEquals("geography(" + srid + ")", geographyType.typeName()); + Assertions.assertEquals("geography(" + srid + ")", geographyType.simpleString()); + }); + } + + @Test + public void geographyTypeWithSpecifiedInvalidSridTest() { + // Invalid SRID values for GEOGRAPHY. + Stream.of(-1, -2, 0, 1, 2).forEach(srid -> { + try { + DataTypes.createGeographyType(srid); + Assertions.fail("Expected SparkIllegalArgumentException for SRID: " + srid); + } catch (SparkIllegalArgumentException e) { + Assertions.assertEquals("ST_INVALID_SRID_VALUE", e.getCondition()); + Assertions.assertEquals(String.valueOf(srid), e.getMessageParameters().get("srid")); + } + }); + } + + /* + * Test cases GeographyType construction based on CRS. + */ + + @Test + public void geographyTypeWithSpecifiedValidCrsTest() { + // Valid CRS values for GEOGRAPHY. Note that only 4326 is supported for now. + int srid = GeographyType.GEOGRAPHY_DEFAULT_SRID(); + Stream.of("OGC:CRS84", "EPSG:4326").forEach(crs -> { + DataType geographyType = DataTypes.createGeographyType(crs); + Assertions.assertEquals("GEOGRAPHY(" + srid + ")", geographyType.sql()); + Assertions.assertEquals("geography(" + srid + ")", geographyType.typeName()); + Assertions.assertEquals("geography(" + srid + ")", geographyType.simpleString()); + }); + } + + @Test + public void geographyTypeWithSpecifiedInvalidCrsTest() { + // Invalid CRS values for GEOGRAPHY. + Stream.of("0", "SRID", "SRID:-1", "SRID:4326", "CRS84", "").forEach(crs -> { + try { + DataTypes.createGeographyType(crs); + Assertions.fail("Expected SparkIllegalArgumentException for CRS: " + crs); + } catch (SparkIllegalArgumentException e) { + Assertions.assertEquals("ST_INVALID_CRS_VALUE", e.getCondition()); + Assertions.assertEquals(crs, e.getMessageParameters().get("crs")); + } + }); + } + + @Test + public void geographyTypeWithSpecifiedAnyTest() { + // Special string value "ANY" in place of CRS is used to denote a mixed GEOGRAPHY type. + DataType geographyType = DataTypes.createGeographyType("ANY"); + Assertions.assertEquals("GEOGRAPHY(ANY)", geographyType.sql()); + Assertions.assertEquals("geography(any)", geographyType.typeName()); + Assertions.assertEquals("geography(any)", geographyType.simpleString()); + } +} diff --git a/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeometryTypeSuite.java b/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeometryTypeSuite.java new file mode 100644 index 0000000000000..03485feeb3f91 --- /dev/null +++ b/sql/core/src/test/scala/org/apache/spark/sql/types/JavaGeometryTypeSuite.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.spark.sql.types; + +import org.apache.spark.sql.internal.types.SpatialReferenceSystemMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.apache.spark.SparkIllegalArgumentException; + +import java.util.stream.Stream; + +public class JavaGeometryTypeSuite { + + /* + * Test cases GeometryType construction based on SRID. + */ + + @Test + public void geometryTypeWithSpecifiedValidSridTest() { + // Valid SRID values for GEOMETRY. + Stream.of(0, 3857, 4326).forEach(srid -> { + DataType geometryType = DataTypes.createGeometryType(srid); + Assertions.assertEquals("GEOMETRY(" + srid + ")", geometryType.sql()); + Assertions.assertEquals("geometry(" + srid + ")", geometryType.typeName()); + Assertions.assertEquals("geometry(" + srid + ")", geometryType.simpleString()); + }); + } + + @Test + public void geometryTypeWithSpecifiedInvalidSridTest() { + // Invalid SRID values for GEOMETRY. + Stream.of(-1, -2, 1, 2).forEach(srid -> { + try { + DataTypes.createGeometryType(srid); + Assertions.fail("Expected SparkIllegalArgumentException for SRID: " + srid); + } catch (SparkIllegalArgumentException e) { + Assertions.assertEquals("ST_INVALID_SRID_VALUE", e.getCondition()); + Assertions.assertEquals(String.valueOf(srid), e.getMessageParameters().get("srid")); + } + }); + } + + /* + * Test cases GeometryType construction based on CRS. + */ + + @Test + public void geometryTypeWithSpecifiedValidCrsTest() { + // Valid CRS values for GEOMETRY. + SpatialReferenceSystemMapper srsMapper = SpatialReferenceSystemMapper.get(); + Stream.of("SRID:0", "EPSG:3857", "OGC:CRS84").forEach(crs -> { + int srid = srsMapper.getSrid(crs); + DataType geometryType = DataTypes.createGeometryType(crs); + Assertions.assertEquals("GEOMETRY(" + srid + ")", geometryType.sql()); + Assertions.assertEquals("geometry(" + srid + ")", geometryType.typeName()); + Assertions.assertEquals("geometry(" + srid + ")", geometryType.simpleString()); + }); + } + + @Test + public void geometryTypeWithSpecifiedInvalidCrsTest() { + // Invalid CRS values for GEOMETRY. + Stream.of("0", "SRID", "SRID:-1", "SRID:4326", "CRS84", "").forEach(crs -> { + try { + DataTypes.createGeometryType(crs); + Assertions.fail("Expected SparkIllegalArgumentException for CRS: " + crs); + } catch (SparkIllegalArgumentException e) { + Assertions.assertEquals("ST_INVALID_CRS_VALUE", e.getCondition()); + Assertions.assertEquals(crs, e.getMessageParameters().get("crs")); + } + }); + } + + @Test + public void geometryTypeWithSpecifiedAnyTest() { + // Special string value "ANY" in place of CRS is used to denote a mixed GEOMETRY type. + DataType geometryType = DataTypes.createGeometryType("ANY"); + Assertions.assertEquals("GEOMETRY(ANY)", geometryType.sql()); + Assertions.assertEquals("geometry(any)", geometryType.typeName()); + Assertions.assertEquals("geometry(any)", geometryType.simpleString()); + } +}