Skip to content

Commit aa54108

Browse files
authored
Merge pull request #653 from Maxxen/main-dev
Misc bugfixes
2 parents fc28541 + 4fafb07 commit aa54108

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

src/spatial/modules/main/spatial_functions_scalar.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,11 +2018,11 @@ struct ST_CollectionExtract {
20182018
struct ST_Contains {
20192019

20202020
//------------------------------------------------------------------------------------------------------------------
2021-
// POINT_2D -> POLYGON_2D
2021+
// POLYGON_2D -> POINT_2D
20222022
//------------------------------------------------------------------------------------------------------------------
20232023
// TODO: This should probably be revised. Im not sure if the current implementation is entirely accurate
20242024

2025-
static void Operation(Vector &in_point, Vector &in_polygon, Vector &result, idx_t count) {
2025+
static void Operation(Vector &in_polygon, Vector &in_point, Vector &result, idx_t count) {
20262026
enum class Side { LEFT, RIGHT, ON };
20272027

20282028
in_polygon.Flatten(count);
@@ -2043,7 +2043,6 @@ struct ST_Contains {
20432043
auto y_data = FlatVector::GetData<double>(*coord_children[1]);
20442044

20452045
auto result_data = FlatVector::GetData<bool>(result);
2046-
20472046
for (idx_t polygon_idx = 0; polygon_idx < count; polygon_idx++) {
20482047
auto polygon = polygon_entries[polygon_idx];
20492048
auto polygon_offset = polygon.offset;
@@ -8702,7 +8701,7 @@ struct ST_Within {
87028701
auto &polygon_in = args.data[1];
87038702

87048703
// Just execute ST_Contains, but reversed
8705-
ST_Contains::Operation(point_in, polygon_in, result, args.size());
8704+
ST_Contains::Operation(polygon_in, point_in, result, args.size());
87068705
}
87078706

87088707
//------------------------------------------------------------------------------------------------------------------

src/spatial/operators/spatial_join_optimizer.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
#include "duckdb/planner/operator/logical_any_join.hpp"
88
#include "duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp"
99
#include "duckdb/planner/operator/logical_filter.hpp"
10+
#include "spatial/spatial_types.hpp"
1011

1112
namespace duckdb {
1213

1314
// All of these imply bounding box intersection
14-
static case_insensitive_set_t spatial_predicate_map = {
15+
static const case_insensitive_set_t spatial_predicate_map = {
1516
"ST_Equals", "ST_Intersects", "ST_Touches", "ST_Crosses", "ST_Within", "ST_Contains",
1617
"ST_Overlaps", "ST_Covers", "ST_CoveredBy", "ST_ContainsProperly", "ST_WithinProperly", "ST_DWithin",
1718
};
1819

19-
static case_insensitive_map_t<string> spatial_predicate_inverse_map = {
20+
static const case_insensitive_map_t<string> spatial_predicate_inverse_map = {
2021
{"ST_Equals", "ST_Equals"},
2122
{"ST_Intersects", "ST_Intersects"}, // Symmetric
2223
{"ST_Touches", "ST_Touches"}, // Symmetric
@@ -139,6 +140,13 @@ static void InsertSpatialJoin(OptimizerExtensionInput &input, unique_ptr<Logical
139140
continue;
140141
}
141142

143+
// The function must operate on two GEOMETRY types
144+
if (func.children[0]->return_type != GeoTypes::GEOMETRY() ||
145+
func.children[1]->return_type != GeoTypes::GEOMETRY()) {
146+
extra_predicates.push_back(std::move(expr));
147+
continue;
148+
}
149+
142150
// The function must be a recognized spatial predicate
143151
if (spatial_predicate_map.count(func.function.name) == 0) {
144152
extra_predicates.push_back(std::move(expr));

src/spatial/operators/spatial_join_physical.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ class SpatialJoinGlobalState final : public GlobalSinkState {
452452

453453
// This is initialized in the finalize state
454454
unique_ptr<FlatRTree> rtree = nullptr;
455+
456+
mutex combine_lock;
455457
};
456458

457459
unique_ptr<GlobalSinkState> PhysicalSpatialJoin::GetGlobalSinkState(ClientContext &context) const {
@@ -580,6 +582,7 @@ SinkCombineResultType PhysicalSpatialJoin::Combine(ExecutionContext &context, Op
580582
lstate.collection->FinalizePinState(lstate.append_state.pin_state);
581583

582584
// Append the local collection to the global collection
585+
lock_guard<mutex> lock(gstate.combine_lock);
583586
gstate.collection->Combine(*lstate.collection);
584587

585588
// Merge the non-null and non-empty count
@@ -1019,14 +1022,13 @@ class SpatialJoinGlobalSourceState final : public GlobalSourceState {
10191022
column_ids.push_back(op.build_side_key_types.size() + op.build_side_payload_types.size());
10201023

10211024
// We dont need to keep the tuples aroun after scanning
1022-
state.collection->InitializeScan(scan_state, std::move(column_ids), TupleDataPinProperties::DESTROY_AFTER_DONE);
1025+
state.collection->InitializeScan(scan_state, std::move(column_ids), TupleDataPinProperties::KEEP_EVERYTHING_PINNED);
10231026

10241027
tuples_maximum = state.collection->Count();
10251028
}
10261029

10271030
const PhysicalSpatialJoin &op;
10281031
TupleDataParallelScanState scan_state;
1029-
10301032
// How many tuples we have scanned so far
10311033
idx_t tuples_maximum = 0;
10321034
atomic<idx_t> tuples_scanned = {0};
@@ -1056,7 +1058,7 @@ class SpatialJoinLocalSourceState final : public LocalSourceState {
10561058
column_ids.push_back(op.build_side_key_types.size() + op.build_side_payload_types.size());
10571059

10581060
// We dont need to keep the tuples aroun after scanning
1059-
state.collection->InitializeScan(scan_state, std::move(column_ids), TupleDataPinProperties::DESTROY_AFTER_DONE);
1061+
state.collection->InitializeScan(scan_state, std::move(column_ids));
10601062
state.collection->InitializeScanChunk(scan_state, scan_chunk);
10611063
}
10621064

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# name: test/sql/join/spatial_join_cte.test
2+
# group: [join]
3+
4+
require spatial
5+
6+
query IIII
7+
with bigger as (
8+
select 'a' as region, ST_GeomFromText('POLYGON ((0 0, 0 10, 10 10, 10 0 , 0 0 ))') as geom
9+
union all
10+
select 'b' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
11+
union all
12+
select 'c' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
13+
union all
14+
select 'd' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
15+
union all
16+
select 'e' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
17+
union all
18+
select 'f' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
19+
union all
20+
select 'g' as region, ST_GeomFromText('POLYGON ((50 50, 50 60, 60 60, 60 50 , 50 50 ))') as geom
21+
), smaller as (
22+
select '1' as region, ST_GeomFromText('POLYGON ((2 2, 2 8, 8 8, 8 2 , 2 2 ))') as geom
23+
union all
24+
select '2' as region, ST_GeomFromText('POLYGON ((3 3, 3 5, 5 5, 5 3 , 3 3 ))') as geom
25+
)
26+
select * from smaller left join bigger on st_intersects(bigger.geom, smaller.geom) order by all;
27+
----
28+
1 POLYGON ((2 2, 2 8, 8 8, 8 2, 2 2)) a POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))
29+
2 POLYGON ((3 3, 3 5, 5 5, 5 3, 3 3)) a POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))

0 commit comments

Comments
 (0)