feat(sql): add within_box, within_radius, and geo_within_radius_latlon functions#6664
feat(sql): add within_box, within_radius, and geo_within_radius_latlon functions#6664bluestreak01 merged 9 commits intomasterfrom
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds four new geospatial function factories (distance, within-box, within-radius, within-radius-latlon) with optimized paths for constant inputs, comprehensive input validation, NaN handling, and extensive test suites. Minor refactoring of a switch statement to switch expression in an existing factory. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~120 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@core/src/main/java/io/questdb/griffin/engine/functions/bool/GeoWithinRadiusFunctionFactory.java`:
- Around line 227-381: GeoWithinRadiusFunction is missing an isEquivalentTo
override so equivalence checks fall back to identity; add an override in
GeoWithinRadiusFunction that first returns true for this==other, then checks
other instanceof GeoWithinRadiusFunction and compares child functions using
xFunc.isEquivalentTo(that.xFunc), yFunc.isEquivalentTo(that.yFunc),
centerXFunc.isEquivalentTo(that.centerXFunc),
centerYFunc.isEquivalentTo(that.centerYFunc), and
radiusFunc.isEquivalentTo(that.radiusFunc) (matching the pattern used in
GeoWithinBoxFunction).
core/src/main/java/io/questdb/griffin/engine/functions/geo/WithinRadiusFunctionFactory.java
Show resolved
Hide resolved
… radius, fix javadoc - Store original radius in const-optimized functions instead of computing Math.sqrt(radiusSq) - Add latitude validation (-90 to 90) and longitude validation (-180 to 180) - Use SqlException for compile-time validation of constant values - Use CairoException.nonCritical().position() for runtime validation - Escape < characters in javadoc comments Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…geo package - Add geo_distance_meters(lat1, lon1, lat2, lon2) function that returns distance in meters between two lat/lon points using equirectangular projection. Optimized for small distances with ~0.1% error for < 100km. - Move all geo spatial functions from bool package to geo package - Add isEquivalentTo() implementations to all geo function classes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests geo functions with dynamic parameters from joined tables: - geo_within_box: join points with zones table by box boundaries - geo_within_radius: join detections with sensors by center/radius - geo_within_radius_latlon: join customers with stores by delivery radius - geo_distance_meters: join on distance < threshold, distance matrix Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
[PR Coverage check]😍 pass : 481 / 717 (67.09%) file detail
|
|
@CodeRabbit did you find any bugs? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 6161
Missing ✅ Status: This was addressed in your subsequent commits (2b4deb5 to 5e91c22). Overall assessment: No critical bugs were identified. The implementation demonstrates:
The code quality is solid, and the one minor issue I flagged has been resolved. 🎉 🐰✨ |
Summary
Adds four new SQL functions optimized for spatial filtering, particularly useful for indexing lidar scans and local area queries.
Naming convention: Functions operating on Cartesian/Euclidean coordinates use simple names (
within_*), while functions operating on geographic lat/lon coordinates use thegeo_prefix.within_box(x, y, min_x, min_y, max_x, max_y)Returns
trueif point(x, y)is within the bounding box defined by(min_x, min_y)to(max_x, max_y), inclusive. Uses Cartesian coordinates.Example:
within_radius(x, y, center_x, center_y, radius)Returns
trueif point(x, y)is withinradiusdistance of(center_x, center_y)using Cartesian/Euclidean distance, inclusive.Example:
geo_within_radius_latlon(lat, lon, center_lat, center_lon, radius_meters)Returns
trueif point(lat, lon)is withinradius_metersof(center_lat, center_lon). Uses equirectangular projection for fast local distance calculations. Lat/lon in degrees, radius in meters.Accuracy: ~0.1% for distances < 100km. For lidar scans (typically < 1km), error is negligible.
Example:
geo_distance_meters(lat1, lon1, lat2, lon2)Returns distance in meters between two lat/lon points using equirectangular projection. Optimized for small distances (lidar/local area scans).
Accuracy: ~0.1% for distances < 100km. For lidar scans (typically < 1km), error is negligible.
Example:
Implementation Details
Math.cos()for lat/lon) are precomputed at query compile timefalse, distance function returnsnullfalse, distance function returnsnulltrueCoordinate Validation (lat/lon functions)
The lat/lon functions validate geographic coordinates and throw errors with correct SQL positions:
SqlException(compile-time) orCairoException(runtime)SqlException(compile-time) orCairoException(runtime)Compile-time validation (constant values):
Runtime validation (column values):
Edge Cases
falsenullfalsenullfalsefalsetruetrue0.0Test Plan
🤖 Generated with Claude Code