You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@sedona.apache.org by "jiayuasu (via GitHub)" <gi...@apache.org> on 2026/10/08 06:44:27 UTC
[PR] [GH-3440] Return NULL or false instead of throwing for empty geometries in spheroid and sphere distance [sedona]
jiayuasu opened a new pull request, #3441:
URL: https://github.com/apache/sedona/pull/3441
## Did you read the Contributor Guide?
- Yes, I have read the [Contributor Rules](https://sedona.apache.org/latest/community/rule/) and [Contributor Development Guide](https://sedona.apache.org/latest/community/develop/)
## Is this PR related to a ticket?
- Yes, and the PR name follows the format `[GH-XXX] my subject`. Closes #3440
## What changes were proposed in this PR?
`Spheroid.distance` and `Haversine.distance` read the coordinate (or centroid coordinate) of each input. For an empty geometry that coordinate is `null`, so `ST_DistanceSpheroid`, `ST_DistanceSphere`, `ST_DWithin(..., true)`, the joins built on them, and broadcast `ST_KNN(..., true)` joins all threw `NullPointerException`. This PR makes them handle empty input the way the planar functions and PostGIS do.
- `Spheroid.distance` and both `Haversine.distance` overloads now return `Double` and return `null` when either input is empty, like `Functions.distance`. `ST_DistanceSpheroid` and `ST_DistanceSphere` therefore return `NULL` in Spark, Flink and Snowflake. The Spark expressions, Flink functions and Snowflake UDFs already declared a nullable `Double` return type, so they need no code changes.
- `Predicates.dWithin` returns `false` when either input is empty, for both the spheroid and the planar path. The planar path needs the same guard: JTS `isWithinDistance` treats the distance to an empty geometry as 0 once its envelope pre-check passes. For example, `ST_DWithin(POINT (0 0), POLYGON EMPTY, 1000)` returned `true`, but a planar distance join never matched that pair.
- `Haversine.expandEnvelope` keeps a null envelope null. Before, it expanded the placeholder bounds of an empty geometry's null envelope into a real box near (-0.5, -0.5), which sent empty geometries into the refinement step of sphere and spheroid distance joins. `Envelope.expandBy` already behaves this way for the planar join, and the raster distance join has the same guard.
- The KNN metrics `HaversineItemDistance` (used by `ST_KNN(..., true)`) and `SpheroidDistance` (RDD API) treat a `null` distance as positive infinity. Empty geometries can reach these metrics: the partitioned KNN join already drops them, but in broadcast mode an empty query geometry is still passed to the metric. The planar metric has no defined behavior here (JTS reports a distance of 0, so an empty query gets arbitrary neighbors in broadcast mode but none in partitioned mode). Infinity ranks empty pairs last. The JTS STRtree k-NN search stops at an infinite distance, so an empty query geometry gets no neighbors in every join strategy, and an empty object is never a neighbor. This matches the existing partitioned behavior and the existing "should not fail with empty geometries" KNN test.
- Java API: the return type of `Spheroid.distance(Geometry, Geometry)` and the two `Haversine.distance(Geometry, Geometry...)` overloads changes from `double` to `Double`. Java and Scala callers recompile unchanged (auto-unboxing), and only empty input yields `null`, which previously threw. Code compiled against the old signature must be recompiled. Inside Sedona, every caller (Spark, Flink, Snowflake, KNN metrics) already handles a nullable result.
- Docs for `ST_DistanceSpheroid`, `ST_DistanceSphere` and `ST_DWithin` (SQL, Flink, Snowflake) and for `ST_KNN` describe the empty-input result.
`ST_LengthSpheroid`, `ST_AreaSpheroid`, `ST_Perimeter(geom, true)` and `ST_Buffer(geom, d, true)` already handle empty input (0.0, or an empty polygon for the buffer), the same as their planar counterparts. They are unchanged, and new unit tests cover the length and area cases.
## How was this patch tested?
New regression tests, each confirmed to fail before the fix (NullPointerException, or `true` from planar `ST_DWithin`) and pass after it:
- `sedona-common`: `FunctionsTest.sphereAndSpheroidDistanceEmptyGeometries`, `PredicatesTest.testDWithinEmptyGeometries`, `HaversineEnvelopeTest.testExpandNullEnvelope`, `SpheroidTest.testLengthAndAreaOfEmptyGeometries` (passes before and after; guards the existing behavior)
- Spark: `functionTestScala` (sphere and spheroid distance on empty input), `predicateTestScala` (`ST_DWithin` on empty input), `SphereDistanceJoinSuite` (`ST_DWithin(..., true)`, `ST_DistanceSphere` and `ST_DistanceSpheroid` joins with `POLYGON EMPTY` and `POINT EMPTY` rows: partitioned, broadcast left and broadcast right), `KnnJoinSuite` (`ST_KNN(..., true)` with empty rows in all three join strategies), `KnnJoinQueryTest` (RDD `knnJoin` with `HAVERSINE` and `SPHEROID`, broadcasting either side)
- Flink: `FunctionTest.testDistanceSphereAndSpheroidEmptyGeometries`, `PredicateTest.testDWithinEmptyGeometries`
Full runs also pass: the `sedona-common` module (1430 tests) and the Flink module (355 tests). On Spark, 13 suites pass (all tests succeeded): `functionTestScala`, `predicateTestScala`, `SphereDistanceJoinSuite`, `KnnJoinSuite`, `KnnJoinQueryTest`, `BroadcastIndexJoinSuite`, `predicateJoinTestScala`, `dataFrameAPITestScala`, `GeoParquetSpatialFilterPushDownSuite`, `Box2DJoinSuite`, `BarrierFunctionTest`, `RasterJoinSuite` and `BroadcastIndexJoinGeographySuite`. The Snowflake module compiles without changes, because its UDFs already return a nullable `Double`.
## Did this PR include necessary documentation updates?
- Yes, I have updated the documentation.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@sedona.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [GH-3440] Return NULL or false instead of throwing for empty geometries in spheroid and sphere distance [sedona]
Posted by "jiayuasu (via GitHub)" <gi...@apache.org>.
jiayuasu merged PR #3441:
URL: https://github.com/apache/sedona/pull/3441
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@sedona.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org