You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to the Box2D spatial-join work in #2939. That PR explicitly scoped out the distance-join case because ST_DWithin only accepted (Geometry, Geometry, distance) and (Geography, Geography, distance) overloads — so ST_DWithin(box, box, d) was rejected at analysis time.
Scope
Add a planar (Box2D, Box2D, distance) overload so distance joins on Box2D columns are accepted and route through Sedona's existing distance-join planner (BroadcastIndexJoinExec and DistanceJoinExec).
Semantics
Closed-interval Euclidean distance between two AABBs: sqrt(dx² + dy²) where dx = max(0, max(a.xmin - b.xmax, b.xmin - a.xmax)) and similarly for dy. Overlapping or edge/corner-touching boxes have distance 0 and therefore match any non-negative radius.
Inverted bounds (xmin > xmax / ymin > ymax) throw IllegalArgumentException, matching the contract of ST_BoxIntersects / ST_BoxContains. Inverted-bound values are reserved for the future antimeridian-wraparound semantics.
Negative radius never matches.
Why a new overload
ST_DWithin is already wired through JoinQueryDetector and OptimizableJoinCondition; both treat the 3-arg form generically based on shape expression dataType, and the toExpandedEnvelopeRDD path uses the Box2D → polygon dispatch landed in #2939. The only thing blocking Box2D × Box2D distance joins is the absence of a scalar Predicates.dWithin(Box2D, Box2D, double) overload and a matching inferrableFunction3 entry in the ST_DWithin InferredExpression. With those, the join planner accepts the predicate and the per-pair refine dispatches back to the new scalar.
Deliverables
Predicates.dWithin(Box2D, Box2D, double) in common.
4th inferrableFunction3 entry on ST_DWithin in spark/common/.../Predicates.scala. The pre-existing 3-arg geometry entry needs an explicit lambda because two arity-3 overloads named Predicates.dWithin now exist on the Java side.
Scalar tests in PredicatesTest (overlap, edge/corner touching, separation on one axis, Pythagorean separation, negative radius, inverted-bound rejection).
Join tests in Box2DJoinSuite (broadcast-index path at multiple radii, non-broadcast DistanceJoinExec path, zero-radius edge-touching).
Docs: new docs/api/sql/box2d/Box2D-Predicates/ST_DWithin.md and a row in Box2D-Functions.md.
Out of scope
A (Box2D, Box2D, distance, useSpheroid) 4-arg overload. useSpheroid is geography territory; Box2D is planar.
Follow-up to the Box2D spatial-join work in #2939. That PR explicitly scoped out the distance-join case because
ST_DWithinonly accepted(Geometry, Geometry, distance)and(Geography, Geography, distance)overloads — soST_DWithin(box, box, d)was rejected at analysis time.Scope
Add a planar
(Box2D, Box2D, distance)overload so distance joins on Box2D columns are accepted and route through Sedona's existing distance-join planner (BroadcastIndexJoinExecandDistanceJoinExec).Semantics
sqrt(dx² + dy²)wheredx = max(0, max(a.xmin - b.xmax, b.xmin - a.xmax))and similarly fordy. Overlapping or edge/corner-touching boxes have distance0and therefore match any non-negative radius.xmin > xmax/ymin > ymax) throwIllegalArgumentException, matching the contract ofST_BoxIntersects/ST_BoxContains. Inverted-bound values are reserved for the future antimeridian-wraparound semantics.Why a new overload
ST_DWithinis already wired throughJoinQueryDetectorandOptimizableJoinCondition; both treat the 3-arg form generically based on shape expression dataType, and thetoExpandedEnvelopeRDDpath uses the Box2D → polygon dispatch landed in #2939. The only thing blocking Box2D × Box2D distance joins is the absence of a scalarPredicates.dWithin(Box2D, Box2D, double)overload and a matchinginferrableFunction3entry in theST_DWithinInferredExpression. With those, the join planner accepts the predicate and the per-pair refine dispatches back to the new scalar.Deliverables
Predicates.dWithin(Box2D, Box2D, double)incommon.inferrableFunction3entry onST_DWithininspark/common/.../Predicates.scala. The pre-existing 3-arg geometry entry needs an explicit lambda because two arity-3 overloads namedPredicates.dWithinnow exist on the Java side.PredicatesTest(overlap, edge/corner touching, separation on one axis, Pythagorean separation, negative radius, inverted-bound rejection).Box2DJoinSuite(broadcast-index path at multiple radii, non-broadcastDistanceJoinExecpath, zero-radius edge-touching).docs/api/sql/box2d/Box2D-Predicates/ST_DWithin.mdand a row inBox2D-Functions.md.Out of scope
(Box2D, Box2D, distance, useSpheroid)4-arg overload.useSpheroidis geography territory; Box2D is planar.