Skip to content

Commit 35a3635

Browse files
authored
Merge pull request #663 from Maxxen/main-dev
2 parents cf29a21 + 31f29b5 commit 35a3635

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed

duckdb

Submodule duckdb updated 606 files

src/sgl/sgl.cpp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,7 +2857,10 @@ void prepared_geometry::build(allocator &allocator) {
28572857
box = extent_xy::smallest();
28582858

28592859
const auto beg = i * NODE_SIZE;
2860-
const auto end = math::min(beg + NODE_SIZE, vertex_count);
2860+
2861+
// We add +1 to the node size here, to get not just the start point of the segment, but also the end point,
2862+
// which may be in the next node. This ensures there is no gaps between node bounding boxes.
2863+
const auto end = math::min(beg + NODE_SIZE + 1, vertex_count);
28612864

28622865
for (uint32_t j = beg; j < end; j++) {
28632866
vertex_xy curr = {0, 0};
@@ -2921,6 +2924,7 @@ point_in_polygon_result prepared_geometry::contains(const vertex_xy &vert) const
29212924
const auto &box = level.entry_array[entry];
29222925

29232926
// Check if the vertex is in the box y-slice
2927+
D_ASSERT(box.min.y <= box.max.y);
29242928
if (box.min.y <= vert.y && box.max.y >= vert.y) {
29252929
if (depth != index.level_count - 1) {
29262930
// We are not at a leaf, so go downwards
@@ -2966,7 +2970,13 @@ point_in_polygon_result prepared_geometry::contains(const vertex_xy &vert) const
29662970
return crossings % 2 == 0 ? point_in_polygon_result::EXTERIOR : point_in_polygon_result::INTERIOR;
29672971
}
29682972

2969-
if (stack[depth] != index.level_array[depth].entry_count - 1) {
2973+
// The end of this node is either the end of the current node, or the end of the level
2974+
const auto node_end = ((stack[depth - 1] + 1) * NODE_SIZE) - 1;
2975+
const auto levl_end = index.level_array[depth].entry_count - 1;
2976+
2977+
const auto end = math::min(node_end, levl_end);
2978+
2979+
if(stack[depth] != end) {
29702980
// Go sideways!
29712981
stack[depth]++;
29722982
break;
@@ -3220,10 +3230,10 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
32203230
if (lhs_is_leaf && rhs_is_leaf) {
32213231

32223232
const auto lhs_beg_idx = pair.lhs_entry * NODE_SIZE;
3223-
const auto lhs_end_idx = math::min(lhs_beg_idx + NODE_SIZE, lhs.index.items_count);
3233+
const auto lhs_end_idx = math::min(lhs_beg_idx + NODE_SIZE + 1, lhs.index.items_count);
32243234

32253235
const auto rhs_beg_idx = pair.rhs_entry * NODE_SIZE;
3226-
const auto rhs_end_idx = math::min(rhs_beg_idx + NODE_SIZE, rhs.index.items_count);
3236+
const auto rhs_end_idx = math::min(rhs_beg_idx + NODE_SIZE + 1, rhs.index.items_count);
32273237

32283238
if (lhs_beg_idx >= lhs_end_idx || rhs_beg_idx >= rhs_end_idx) {
32293239
continue; // No segments to check
@@ -3240,9 +3250,15 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
32403250
for (uint32_t i = lhs_beg_idx + 1; i < lhs_end_idx; i++) {
32413251
memcpy(&lhs_next, lhs_vertex_array + i * lhs_vertex_width, sizeof(vertex_xy));
32423252

3243-
// Quick check. If the distance between the segment and the box (all the segments)
3253+
// Quick check: If the distance between the segment and the box (all the segments)
32443254
// is greater than min_dist, we can skip the exact distance check
3245-
extent_xy lhs_seg = {lhs_prev, lhs_next};
3255+
3256+
extent_xy lhs_seg;
3257+
lhs_seg.min.x = std::min(lhs_prev.x, lhs_next.x);
3258+
lhs_seg.min.y = std::min(lhs_prev.y, lhs_next.y);
3259+
lhs_seg.max.x = std::max(lhs_prev.x, lhs_next.x);
3260+
lhs_seg.max.y = std::max(lhs_prev.y, lhs_next.y);
3261+
32463262
if (lhs_seg.distance_to_sq(rhs_box) > min_dist) {
32473263
lhs_prev = lhs_next;
32483264
continue;
@@ -3252,17 +3268,21 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
32523268
for (uint32_t j = rhs_beg_idx + 1; j < rhs_end_idx; j++) {
32533269
memcpy(&rhs_next, rhs_vertex_array + j * rhs_vertex_width, sizeof(vertex_xy));
32543270

3255-
extent_xy rhs_seg = {rhs_prev, rhs_next};
3256-
3257-
// Quick check. If the distance between the segment bounds are greater than min_dist,
3271+
// Quick check: If the distance between the segment bounds are greater than min_dist,
32583272
// we can skip the exact distance check
3259-
if (lhs_seg.distance_to_sq(rhs_seg) > min_dist) {
3273+
extent_xy rhs_seg;
3274+
rhs_seg.min.x = std::min(rhs_prev.x, rhs_next.x);
3275+
rhs_seg.min.y = std::min(rhs_prev.y, rhs_next.y);
3276+
rhs_seg.max.x = std::max(rhs_prev.x, rhs_next.x);
3277+
rhs_seg.max.y = std::max(rhs_prev.y, rhs_next.y);
3278+
3279+
if (rhs_seg.distance_to_sq(lhs_seg) > min_dist) {
32603280
rhs_prev = rhs_next;
32613281
continue;
32623282
}
32633283

32643284
const auto dist = segment_segment_dist_sq(lhs_prev, lhs_next, rhs_prev, rhs_next);
3265-
if (dist <= min_dist) {
3285+
if (dist < min_dist) {
32663286
min_dist = dist;
32673287
found_any = true;
32683288
}
@@ -3346,7 +3366,7 @@ static bool try_get_prepared_distance_lines(const prepared_geometry &lhs, const
33463366
}
33473367

33483368
if (found_any) {
3349-
distance = std::sqrt(min_dist);
3369+
distance = std::sqrt(min_dist); // Convert squared distance to actual distance
33503370
return true; // We found a distance
33513371
}
33523372
return false; // No distance found
@@ -3361,6 +3381,7 @@ bool prepared_geometry::try_get_distance(const prepared_geometry &other, double
33613381
// WKT Parsing
33623382
//======================================================================================================================
33633383

3384+
33643385
namespace sgl {
33653386

33663387
namespace {

src/spatial/operators/spatial_join_physical.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,10 @@ SinkFinalizeType PhysicalSpatialJoin::Finalize(Pipeline &pipeline, Event &event,
613613

614614
auto &sel = *FlatVector::IncrementalSelectionVector();
615615
Vector geom_vec(GeoTypes::GEOMETRY());
616+
auto &validity = FlatVector::Validity(geom_vec);
616617

617618
do {
619+
validity.Reset();
618620
const auto row_count = iterator.GetCurrentChunkCount();
619621

620622
// We only need to fetch the build-side key column to build the rtree.
@@ -628,7 +630,7 @@ SinkFinalizeType PhysicalSpatialJoin::Finalize(Pipeline &pipeline, Event &event,
628630
const auto geom_ptr = FlatVector::GetData<geometry_t>(geom_vec);
629631
// Push the bounding boxes into the R-Tree
630632
for (idx_t row_idx = 0; row_idx < row_count; row_idx++) {
631-
if (FlatVector::IsNull(geom_vec, row_idx)) {
633+
if (!validity.RowIsValid(row_idx)) {
632634
// Skip null geometries
633635
continue;
634636
}

0 commit comments

Comments
 (0)