This is an automated email from the ASF dual-hosted git repository.

jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git


The following commit(s) were added to refs/heads/master by this push:
     new 671c41d880 [GH-1874] Fix ST_XYMin/Max returning sentinel values for 
EMPTY geometries (#2621)
671c41d880 is described below

commit 671c41d8806fbf02fdae5342ecfc9c09782bc02a
Author: Jia Yu <[email protected]>
AuthorDate: Sat Feb 7 15:15:36 2026 -0700

    [GH-1874] Fix ST_XYMin/Max returning sentinel values for EMPTY geometries 
(#2621)
---
 .../java/org/apache/sedona/common/Functions.java   | 16 ++++++------
 .../org/apache/sedona/common/FunctionsTest.java    | 30 ++++++++++++++++++++++
 .../org/apache/sedona/snowflake/snowsql/UDFs.java  |  8 +++---
 .../apache/sedona/snowflake/snowsql/UDFsV2.java    |  8 +++---
 4 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/common/src/main/java/org/apache/sedona/common/Functions.java 
b/common/src/main/java/org/apache/sedona/common/Functions.java
index 0ade0e66a1..f6805668ce 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -668,40 +668,40 @@ public class Functions {
     return max == -Double.MAX_VALUE ? null : max;
   }
 
-  public static double xMin(Geometry geometry) {
+  public static Double xMin(Geometry geometry) {
     Coordinate[] points = geometry.getCoordinates();
     double min = Double.MAX_VALUE;
     for (int i = 0; i < points.length; i++) {
       min = Math.min(points[i].getX(), min);
     }
-    return min;
+    return min == Double.MAX_VALUE ? null : min;
   }
 
-  public static double xMax(Geometry geometry) {
+  public static Double xMax(Geometry geometry) {
     Coordinate[] points = geometry.getCoordinates();
     double max = -Double.MAX_VALUE;
     for (int i = 0; i < points.length; i++) {
       max = Math.max(points[i].getX(), max);
     }
-    return max;
+    return max == -Double.MAX_VALUE ? null : max;
   }
 
-  public static double yMin(Geometry geometry) {
+  public static Double yMin(Geometry geometry) {
     Coordinate[] points = geometry.getCoordinates();
     double min = Double.MAX_VALUE;
     for (int i = 0; i < points.length; i++) {
       min = Math.min(points[i].getY(), min);
     }
-    return min;
+    return min == Double.MAX_VALUE ? null : min;
   }
 
-  public static double yMax(Geometry geometry) {
+  public static Double yMax(Geometry geometry) {
     Coordinate[] points = geometry.getCoordinates();
     double max = -Double.MAX_VALUE;
     for (int i = 0; i < points.length; i++) {
       max = Math.max(points[i].getY(), max);
     }
-    return max;
+    return max == -Double.MAX_VALUE ? null : max;
   }
 
   public static Double zMax(Geometry geometry) {
diff --git a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java 
b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
index c2aeced939..19f29cc3bd 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -3620,6 +3620,36 @@ public class FunctionsTest extends TestBase {
     assertEquals(expected, actual);
   }
 
+  @Test
+  public void boundsEmptyGeometryReturnsNull() {
+    Geometry emptyPoint = GEOMETRY_FACTORY.createPoint();
+    assertNull(Functions.xMin(emptyPoint));
+    assertNull(Functions.xMax(emptyPoint));
+    assertNull(Functions.yMin(emptyPoint));
+    assertNull(Functions.yMax(emptyPoint));
+
+    Geometry emptyPolygon = GEOMETRY_FACTORY.createPolygon();
+    assertNull(Functions.xMin(emptyPolygon));
+    assertNull(Functions.xMax(emptyPolygon));
+    assertNull(Functions.yMin(emptyPolygon));
+    assertNull(Functions.yMax(emptyPolygon));
+
+    Geometry emptyLineString = GEOMETRY_FACTORY.createLineString();
+    assertNull(Functions.xMin(emptyLineString));
+    assertNull(Functions.xMax(emptyLineString));
+    assertNull(Functions.yMin(emptyLineString));
+    assertNull(Functions.yMax(emptyLineString));
+  }
+
+  @Test
+  public void boundsNonEmptyGeometry() throws ParseException {
+    Geometry polygon = Constructors.geomFromWKT("POLYGON ((-1 -11, 0 10, 1 11, 
2 12, -1 -11))", 0);
+    assertEquals(-1.0, Functions.xMin(polygon), 1e-9);
+    assertEquals(2.0, Functions.xMax(polygon), 1e-9);
+    assertEquals(-11.0, Functions.yMin(polygon), 1e-9);
+    assertEquals(12.0, Functions.yMax(polygon), 1e-9);
+  }
+
   @Test
   public void angleFourPoints() {
     Point start1 = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
diff --git 
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java 
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
index 3e2d0095a6..ccc5d88bea 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
@@ -1188,12 +1188,12 @@ public class UDFs {
   }
 
   @UDFAnnotations.ParamMeta(argNames = {"geometry"})
-  public static double ST_XMax(byte[] geometry) {
+  public static Double ST_XMax(byte[] geometry) {
     return Functions.xMax(GeometrySerde.deserialize(geometry));
   }
 
   @UDFAnnotations.ParamMeta(argNames = {"geometry"})
-  public static double ST_XMin(byte[] geometry) {
+  public static Double ST_XMin(byte[] geometry) {
     return Functions.xMin(GeometrySerde.deserialize(geometry));
   }
 
@@ -1203,12 +1203,12 @@ public class UDFs {
   }
 
   @UDFAnnotations.ParamMeta(argNames = {"geometry"})
-  public static double ST_YMax(byte[] geometry) {
+  public static Double ST_YMax(byte[] geometry) {
     return Functions.yMax(GeometrySerde.deserialize(geometry));
   }
 
   @UDFAnnotations.ParamMeta(argNames = {"geometry"})
-  public static double ST_YMin(byte[] geometry) {
+  public static Double ST_YMin(byte[] geometry) {
     return Functions.yMin(GeometrySerde.deserialize(geometry));
   }
 
diff --git 
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java 
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
index 5d545f4b6c..0cc7b4e622 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
@@ -1427,14 +1427,14 @@ public class UDFsV2 {
   @UDFAnnotations.ParamMeta(
       argNames = {"geometry"},
       argTypes = {"Geometry"})
-  public static double ST_XMax(String geometry) {
+  public static Double ST_XMax(String geometry) {
     return Functions.xMax(GeometrySerde.deserGeoJson(geometry));
   }
 
   @UDFAnnotations.ParamMeta(
       argNames = {"geometry"},
       argTypes = {"Geometry"})
-  public static double ST_XMin(String geometry) {
+  public static Double ST_XMin(String geometry) {
     return Functions.xMin(GeometrySerde.deserGeoJson(geometry));
   }
 
@@ -1448,14 +1448,14 @@ public class UDFsV2 {
   @UDFAnnotations.ParamMeta(
       argNames = {"geometry"},
       argTypes = {"Geometry"})
-  public static double ST_YMax(String geometry) {
+  public static Double ST_YMax(String geometry) {
     return Functions.yMax(GeometrySerde.deserGeoJson(geometry));
   }
 
   @UDFAnnotations.ParamMeta(
       argNames = {"geometry"},
       argTypes = {"Geometry"})
-  public static double ST_YMin(String geometry) {
+  public static Double ST_YMin(String geometry) {
     return Functions.yMin(GeometrySerde.deserGeoJson(geometry));
   }
 

Reply via email to