Skip to content

Commit bd5449d

Browse files
authored
Merge pull request #757 from Maxxen/v1.5-variegata-dev
2 parents 5d5e34f + a2d205f commit bd5449d

24 files changed

+1186
-363
lines changed

duckdb

Submodule duckdb updated 77 files

src/spatial/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ add_subdirectory(operators)
66

77
set(EXTENSION_SOURCES
88
${EXTENSION_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/spatial_extension.cpp
9-
${CMAKE_CURRENT_SOURCE_DIR}/spatial_types.cpp
9+
${CMAKE_CURRENT_SOURCE_DIR}/spatial_types.cpp ${CMAKE_CURRENT_SOURCE_DIR}/spatial_settings.cpp
1010
PARENT_SCOPE)

src/spatial/index/rtree/rtree_index.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ void RTreeIndex::CommitDrop(IndexLock &index_lock) {
162162
tree->Reset();
163163
}
164164

165-
166-
template<class CALLBACK = std::function<void(const RTreeEntry &)>>
165+
template <class CALLBACK = std::function<void(const RTreeEntry &)>>
167166
static void ConvertToEntries(Vector &box_vec, Vector &rowid_vec, idx_t count, CALLBACK &&callback) {
168167
const auto &box_validity = FlatVector::Validity(box_vec);
169168
const auto &row_validity = FlatVector::Validity(rowid_vec);
@@ -181,7 +180,7 @@ static void ConvertToEntries(Vector &box_vec, Vector &rowid_vec, idx_t count, CA
181180
continue;
182181
}
183182

184-
Box2D <float> box;
183+
Box2D<float> box;
185184
box.min.x = box_xmin_data[i];
186185
box.min.y = box_ymin_data[i];
187186
box.max.x = box_xmax_data[i];
@@ -204,9 +203,7 @@ ErrorData RTreeIndex::Insert(IndexLock &lock, DataChunk &input, Vector &row_vec)
204203

205204
auto &box_vec = key_chunk.data[0];
206205

207-
ConvertToEntries(box_vec, row_vec, input.size(), [&](const RTreeEntry &entry) {
208-
tree->Insert(entry);
209-
});
206+
ConvertToEntries(box_vec, row_vec, input.size(), [&](const RTreeEntry &entry) { tree->Insert(entry); });
210207

211208
return ErrorData {};
212209
}
@@ -230,9 +227,7 @@ void RTreeIndex::Delete(IndexLock &lock, DataChunk &input, Vector &row_vec) {
230227
key_chunk.Flatten();
231228

232229
auto &box_vec = key_chunk.data[0];
233-
ConvertToEntries(box_vec, row_vec, count, [&](const RTreeEntry &entry) {
234-
tree->Delete(entry);
235-
});
230+
ConvertToEntries(box_vec, row_vec, count, [&](const RTreeEntry &entry) { tree->Delete(entry); });
236231
}
237232

238233
IndexStorageInfo RTreeIndex::SerializeToDisk(QueryContext context, const case_insensitive_map_t<Value> &options) {

src/spatial/index/rtree/rtree_index.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class RTreeIndex final : public BoundIndex {
3535

3636
static unique_ptr<BoundIndex> Create(CreateIndexInput &input) {
3737
auto res = make_uniq<RTreeIndex>(input.name, input.constraint_type, input.column_ids, input.table_io_manager,
38-
input.unbound_expressions, input.db, input.options, input.context, input.storage_info);
38+
input.unbound_expressions, input.db, input.options, input.context,
39+
input.storage_info);
3940
return std::move(res);
4041
}
4142

src/spatial/index/rtree/rtree_index_plan_scan.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include "duckdb/planner/filter/expression_filter.hpp"
2929
#include "duckdb/main/database.hpp"
3030

31-
3231
namespace duckdb {
3332
//-----------------------------------------------------------------------------
3433
// Plan rewriter
@@ -126,7 +125,8 @@ class RTreeIndexScanOptimizer : public OptimizerExtension {
126125
vector<unique_ptr<Expression>> children;
127126
children.push_back(expr.Copy());
128127

129-
const auto bbox_expr = make_uniq<BoundFunctionExpression>(GeoTypes::BOX_2DF(), func, std::move(children), nullptr);
128+
const auto bbox_expr =
129+
make_uniq<BoundFunctionExpression>(GeoTypes::BOX_2DF(), func, std::move(children), nullptr);
130130

131131
Value result;
132132
if (!ExpressionExecutor::TryEvaluateScalar(context, *bbox_expr, result)) {
@@ -216,9 +216,9 @@ class RTreeIndexScanOptimizer : public OptimizerExtension {
216216
auto &table_info = *table.GetStorage().GetDataTableInfo();
217217
unique_ptr<RTreeIndexScanBindData> bind_data = nullptr;
218218

219-
unordered_set<string> spatial_predicates = {"ST_Equals", "ST_Intersects", "ST_Touches", "ST_Crosses",
220-
"ST_Within", "ST_Contains", "ST_Overlaps", "ST_Covers",
221-
"ST_CoveredBy", "ST_ContainsProperly", "&&", "ST_IntersectsExtent"};
219+
unordered_set<string> spatial_predicates = {
220+
"ST_Equals", "ST_Intersects", "ST_Touches", "ST_Crosses", "ST_Within", "ST_Contains",
221+
"ST_Overlaps", "ST_Covers", "ST_CoveredBy", "ST_ContainsProperly", "&&", "ST_IntersectsExtent"};
222222

223223
table_info.BindIndexes(context, RTreeIndex::TYPE_NAME);
224224

src/spatial/modules/gdal/gdal_module.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "cpl_vsi_virtual.h"
3030
#include "duckdb/common/types/geometry_crs.hpp"
3131
#include "duckdb/main/settings.hpp"
32+
#include "spatial/spatial_settings.hpp"
33+
#include "spatial/modules/proj/proj_module.hpp"
3234

3335
namespace duckdb {
3436
namespace {
@@ -393,6 +395,8 @@ class DuckDBFileSystemHandler final : public VSIFilesystemHandler {
393395

394396
class DuckDBFileSystemPrefix final : public ClientContextState {
395397
public:
398+
static mutex vsi_mutex;
399+
396400
explicit DuckDBFileSystemPrefix(ClientContext &context) : context(context) {
397401
// Create a new random prefix for this client
398402
client_prefix = StringUtil::Format("/vsiduckdb-%s/", UUID::ToString(UUID::GenerateRandomUUID()));
@@ -401,11 +405,13 @@ class DuckDBFileSystemPrefix final : public ClientContextState {
401405
fs_handler = make_uniq<DuckDBFileSystemHandler>(client_prefix, context);
402406

403407
// Register the file handler
408+
lock_guard<mutex> lock(vsi_mutex);
404409
VSIFileManager::InstallHandler(client_prefix, fs_handler.get());
405410
}
406411

407412
~DuckDBFileSystemPrefix() override {
408413
// Uninstall the file handler for this prefix
414+
lock_guard<mutex> lock(vsi_mutex);
409415
VSIFileManager::RemoveHandler(client_prefix);
410416
}
411417

@@ -430,6 +436,8 @@ class DuckDBFileSystemPrefix final : public ClientContextState {
430436
unique_ptr<DuckDBFileSystemHandler> fs_handler;
431437
};
432438

439+
mutex DuckDBFileSystemPrefix::vsi_mutex;
440+
433441
//======================================================================================================================
434442
// GDAL READ
435443
//======================================================================================================================
@@ -628,6 +636,35 @@ auto Bind(ClientContext &ctx, TableFunctionBindInput &input, vector<LogicalType>
628636
col_names.push_back(child_schema.name);
629637
}
630638

639+
if (duck_type.id() != LogicalTypeId::GEOMETRY) {
640+
col_types.push_back(std::move(duck_type));
641+
continue;
642+
}
643+
644+
if (!GeoType::HasCRS(duck_type)) {
645+
col_types.push_back(std::move(duck_type));
646+
continue;
647+
}
648+
649+
// Try to identify the CRS
650+
const auto &gdal_crs = GeoType::GetCRS(duck_type);
651+
652+
// FIXME: GDAL should be able to do this on its own, but somehow
653+
// OGRSpatialReference::FindBestMatch() dont work
654+
655+
string auth_name;
656+
string auth_code;
657+
if (IdentifyProjCRS(gdal_crs.GetDefinition().c_str(), auth_name, auth_code)) {
658+
// If we can identify the CRS using PROJ, we can be pretty sure that DuckDB will recognize it.
659+
auto authcode = auth_name + ":" + auth_code;
660+
auto duck_crs = CoordinateReferenceSystem::TryIdentify(ctx, authcode);
661+
if (duck_crs) {
662+
col_types.push_back(LogicalType::GEOMETRY(*duck_crs));
663+
continue;
664+
}
665+
}
666+
667+
// Otherwise just pass on what we got
631668
col_types.push_back(std::move(duck_type));
632669
}
633670

@@ -1295,7 +1332,25 @@ auto InitGlobal(ClientContext &context, FunctionData &bdata_p, const string &rea
12951332
if (!bdata.target_srs.empty()) {
12961333
// Make a new spatial reference object, and set it from the user input
12971334
result->srs = OSRNewSpatialReference(nullptr);
1298-
OSRSetFromUserInput(result->srs, bdata.target_srs.c_str());
1335+
1336+
// Try get the complete SRS from duckdb
1337+
auto converted =
1338+
CoordinateReferenceSystem::TryConvert(context, bdata.target_srs, CoordinateReferenceSystemType::PROJJSON);
1339+
if (!converted) {
1340+
converted = CoordinateReferenceSystem::TryConvert(context, bdata.target_srs,
1341+
CoordinateReferenceSystemType::WKT2_2019);
1342+
if (!converted) {
1343+
converted = CoordinateReferenceSystem::TryConvert(context, bdata.target_srs,
1344+
CoordinateReferenceSystemType::AUTH_CODE);
1345+
}
1346+
}
1347+
1348+
if (converted) {
1349+
OSRSetFromUserInput(result->srs, converted->GetDefinition().c_str());
1350+
} else {
1351+
// Try to set it directly from the user input, in case it's in a format that duckdb doesn't recognize but GDAL does
1352+
OSRSetFromUserInput(result->srs, bdata.target_srs.c_str());
1353+
}
12991354
}
13001355

13011356
// Create Layer

0 commit comments

Comments
 (0)