Skip to content

Add && operator for BOX_2D #601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: v1.3.1
Choose a base branch
from

Conversation

yutannihilation
Copy link

This pull request is my attempt to address #4, although I'm yet to figure out the proper scope of the issue. Also, I'm not sure how this is useful in terms of the performance. So, I'd appreciate feedbacks.

This pull request adds two functions:

  • ST_MakeBox2D()
  • && for BOX_2D and GEOMETRY
SELECT ST_MakeBox2D(ST_Point(0,0), ST_Point(2,2)) as box;
┌───────────────┐
│      box      │
│    box_2d     │
├───────────────┤
│ BOX(0 0, 2 2) │
└───────────────┘
SELECT ST_MakeBox2D(ST_Point(0,0), ST_Point(2,2)) && ST_Point(1,1) as overlap;
┌─────────┐
│ overlap │
│ boolean │
├─────────┤
│ true    │
└─────────┘

#### Signatures

```sql
BOOLEAN && (l1 ANY[], l2 ANY[])
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope I can remove this, but I couldn't find the way...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I can't think of an easy way to avoid this right now, but I think it's fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I first made this attempt at function auto doc generation, duckdb has added a FunctionDescription with a vector<string> categories field thats separate for each overload, so in the future we could use this to identify spatial-added functions instead of relying on the tags. But that will be part of a much larger change for the future.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good to know. Thanks!

Comment on lines 3260 to 3263
const auto box_min_x_data = FlatVector::GetData<double>(*bbox_vec[0]);
const auto box_min_y_data = FlatVector::GetData<double>(*bbox_vec[1]);
const auto box_max_x_data = FlatVector::GetData<double>(*bbox_vec[2]);
const auto box_max_y_data = FlatVector::GetData<double>(*bbox_vec[3]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STRUCT's are not guaranteed to be flat, so this isn't safe to do unless you call .Flatten() on the input args chunk (at which point the geom vector is also flat, so you don't need unified format). Or you can setup unified formats for both the struct vector and each component vector too - you need to check the validity of the struct and each component.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll fix.

Comment on lines +6686 to +6688
variant.AddParameter("point1", GeoTypes::GEOMETRY());
variant.AddParameter("point2", GeoTypes::GEOMETRY());
variant.SetReturnType(GeoTypes::BOX_2D());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having a overload for POINT_2D in the future (not this PR) would be great too!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I forgot to reply here. It seems it already accepts POINT_2D. Do you mean the overload is still useful to avoid the type conversion from POINT_2D to GEOMETRY? (I don't know how this works, but I guess this coercion happens under the hood)

D SELECT ST_MakeBox2D(ST_POINT2D(0, 0), ST_POINT2D(1, 1));
┌──────────────────────────────────────────────────┐
│ st_makebox2d(st_point2d(0, 0), st_point2d(1, 1)) │
│                      box_2d                      │
├──────────────────────────────────────────────────┤
│ BOX(0 0, 1 1)                                    │
└──────────────────────────────────────────────────┘


// Try to get the cached bounding box from the blob
Box2D<float> geom_bbox;
if (geom.TryGetCachedBounds(geom_bbox)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im trying to avoid using TryGetCachedBounds because it returns float boxes, not double, which might lead to imprecise results when comparing against doubles. But I think for now this is fine, if I remember right && in PostGIS is documented as being "approximate".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I remember right && in PostGIS is documented as being "approximate".

Yeah, I thought TryGetCachedBounds is fine for this reason. But, honestly, I'm not sure if the approximation is nice. So, if you want to change this, I'm fine to follow.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me correct a bit. The document doesn't say "approximate", but it surely uses float instead of double, so comparing by float precision is the right choice if we follow PostGIS's behavior.

https://postgis.net/docs/overlaps_box2df_geometry.html

Comment on lines +32 to +37
-- function-specific tweaks
AND CASE function_name
-- TODO: https://github.com/duckdb/duckdb-spatial/pull/601#discussion_r2144753435
WHEN '&&' THEN 'box' IN parameters
ELSE true
END
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't nice, but I think &&'s document should really note that the operation is not very accurate.

@yutannihilation
Copy link
Author

Okay, I think I addressed the comments!

@yutannihilation yutannihilation changed the base branch from v1.3.0 to v1.3.1 June 20, 2025 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants