duckdb 0.7.2-dev2233.0 → 0.7.2-dev2320.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +1 -0
- package/package.json +1 -1
- package/src/duckdb/src/catalog/catalog.cpp +18 -17
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +0 -4
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +0 -4
- package/src/duckdb/src/catalog/catalog_set.cpp +3 -3
- package/src/duckdb/src/common/adbc/adbc.cpp +441 -0
- package/src/duckdb/src/common/adbc/driver_manager.cpp +749 -0
- package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +1 -1
- package/src/duckdb/src/common/tree_renderer.cpp +3 -3
- package/src/duckdb/src/common/types/conflict_manager.cpp +2 -1
- package/src/duckdb/src/execution/column_binding_resolver.cpp +1 -1
- package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +1 -1
- package/src/duckdb/src/execution/operator/filter/physical_filter.cpp +2 -2
- package/src/duckdb/src/execution/operator/helper/physical_execute.cpp +2 -2
- package/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp +5 -5
- package/src/duckdb/src/execution/operator/join/physical_cross_product.cpp +1 -1
- package/src/duckdb/src/execution/operator/join/physical_delim_join.cpp +11 -10
- package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +3 -3
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +9 -9
- package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +4 -4
- package/src/duckdb/src/execution/operator/join/physical_join.cpp +7 -7
- package/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp +3 -3
- package/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp +3 -3
- package/src/duckdb/src/execution/operator/join/physical_positional_join.cpp +2 -2
- package/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp +8 -9
- package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +20 -19
- package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +3 -3
- package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +25 -24
- package/src/duckdb/src/execution/operator/persistent/physical_update.cpp +1 -1
- package/src/duckdb/src/execution/operator/projection/physical_projection.cpp +2 -2
- package/src/duckdb/src/execution/operator/scan/physical_column_data_scan.cpp +12 -6
- package/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp +10 -11
- package/src/duckdb/src/execution/operator/set/physical_union.cpp +2 -2
- package/src/duckdb/src/execution/physical_operator.cpp +13 -13
- package/src/duckdb/src/execution/physical_plan/plan_column_data_get.cpp +2 -4
- package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +1 -1
- package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +5 -5
- package/src/duckdb/src/execution/physical_plan/plan_delete.cpp +3 -3
- package/src/duckdb/src/execution/physical_plan/plan_delim_join.cpp +6 -7
- package/src/duckdb/src/execution/physical_plan/plan_explain.cpp +2 -4
- package/src/duckdb/src/execution/physical_plan/plan_insert.cpp +2 -2
- package/src/duckdb/src/execution/physical_plan/plan_show_select.cpp +2 -4
- package/src/duckdb/src/execution/physical_plan/plan_update.cpp +3 -3
- package/src/duckdb/src/function/compression_config.cpp +9 -9
- package/src/duckdb/src/function/scalar/date/strftime.cpp +1 -1
- package/src/duckdb/src/function/table/copy_csv.cpp +5 -0
- package/src/duckdb/src/function/table/pragma_detailed_profiling_output.cpp +6 -5
- package/src/duckdb/src/function/table/pragma_last_profiling_output.cpp +7 -5
- package/src/duckdb/src/function/table/system/duckdb_databases.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_dependencies.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_extensions.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_indexes.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_keywords.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_schemas.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_sequences.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_settings.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_tables.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_temporary_files.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_types.cpp +1 -1
- package/src/duckdb/src/function/table/system/pragma_collations.cpp +1 -1
- package/src/duckdb/src/function/table/system/pragma_database_size.cpp +1 -1
- package/src/duckdb/src/function/table/system/pragma_storage_info.cpp +5 -5
- package/src/duckdb/src/function/table/system/pragma_table_info.cpp +1 -1
- package/src/duckdb/src/function/table/system/test_all_types.cpp +1 -1
- package/src/duckdb/src/function/table/table_scan.cpp +3 -4
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +3 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +1 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_catalog_entry.hpp +1 -2
- package/src/duckdb/src/include/duckdb/common/adbc/adbc-init.hpp +37 -0
- package/src/duckdb/src/include/duckdb/common/adbc/adbc.h +1088 -0
- package/src/duckdb/src/include/duckdb/common/adbc/adbc.hpp +85 -0
- package/src/duckdb/src/include/duckdb/common/adbc/driver_manager.h +84 -0
- package/src/duckdb/src/include/duckdb/common/helper.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/conflict_manager.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/types.hpp +0 -1
- package/src/duckdb/src/include/duckdb/execution/executor.hpp +7 -7
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_execute.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_cross_product.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_delim_join.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_index_join.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_join.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_positional_join.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_export.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/scan/physical_column_data_scan.hpp +3 -4
- package/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/set/physical_union.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/physical_operator.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/physical_operator_states.hpp +1 -1
- package/src/duckdb/src/include/duckdb/function/cast/cast_function_set.hpp +1 -1
- package/src/duckdb/src/include/duckdb/main/config.hpp +2 -2
- package/src/duckdb/src/include/duckdb/main/query_profiler.hpp +10 -9
- package/src/duckdb/src/include/duckdb/parallel/meta_pipeline.hpp +4 -4
- package/src/duckdb/src/include/duckdb/parallel/pipeline.hpp +18 -17
- package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/bind_context.hpp +14 -17
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +6 -6
- package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +4 -4
- package/src/duckdb/src/include/duckdb/planner/expression_binder/where_binder.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create.hpp +3 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/parsed_data/bound_create_function_info.hpp +3 -2
- package/src/duckdb/src/include/duckdb/planner/parsed_data/bound_create_table_info.hpp +3 -2
- package/src/duckdb/src/include/duckdb/planner/table_binding.hpp +6 -5
- package/src/duckdb/src/include/duckdb/planner/tableref/bound_basetableref.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_compress.hpp +3 -7
- package/src/duckdb/src/include/duckdb/storage/compression/patas/patas_compress.hpp +3 -7
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/column_data_checkpointer.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +4 -4
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +3 -3
- package/src/duckdb/src/include/duckdb/transaction/cleanup_state.hpp +3 -3
- package/src/duckdb/src/include/duckdb/transaction/commit_state.hpp +5 -5
- package/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp +3 -3
- package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +31 -30
- package/src/duckdb/src/include/duckdb/transaction/transaction_data.hpp +2 -1
- package/src/duckdb/src/include/duckdb/transaction/undo_buffer.hpp +1 -1
- package/src/duckdb/src/main/client_context.cpp +1 -1
- package/src/duckdb/src/main/query_profiler.cpp +24 -22
- package/src/duckdb/src/parallel/executor.cpp +55 -49
- package/src/duckdb/src/parallel/meta_pipeline.cpp +5 -5
- package/src/duckdb/src/parallel/pipeline.cpp +43 -26
- package/src/duckdb/src/parallel/pipeline_executor.cpp +22 -22
- package/src/duckdb/src/planner/bind_context.cpp +67 -71
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +6 -7
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +6 -8
- package/src/duckdb/src/planner/binder/statement/bind_delete.cpp +3 -4
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +17 -18
- package/src/duckdb/src/planner/binder/statement/bind_update.cpp +16 -17
- package/src/duckdb/src/planner/binder/statement/bind_vacuum.cpp +6 -5
- package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +9 -9
- package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +20 -18
- package/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +1 -1
- package/src/duckdb/src/planner/binder.cpp +4 -4
- package/src/duckdb/src/planner/expression_binder/index_binder.cpp +2 -1
- package/src/duckdb/src/planner/expression_binder/where_binder.cpp +3 -2
- package/src/duckdb/src/planner/operator/logical_create_table.cpp +1 -1
- package/src/duckdb/src/planner/operator/logical_delete.cpp +5 -5
- package/src/duckdb/src/planner/operator/logical_insert.cpp +6 -7
- package/src/duckdb/src/planner/operator/logical_update.cpp +6 -7
- package/src/duckdb/src/planner/parsed_data/bound_create_table_info.cpp +4 -5
- package/src/duckdb/src/planner/table_binding.cpp +6 -5
- package/src/duckdb/src/storage/compression/bitpacking.cpp +5 -6
- package/src/duckdb/src/storage/compression/dictionary_compression.cpp +5 -6
- package/src/duckdb/src/storage/compression/fsst.cpp +3 -5
- package/src/duckdb/src/storage/compression/rle.cpp +4 -6
- package/src/duckdb/src/storage/data_table.cpp +27 -28
- package/src/duckdb/src/storage/local_storage.cpp +70 -68
- package/src/duckdb/src/storage/storage_manager.cpp +12 -13
- package/src/duckdb/src/storage/table/column_checkpoint_state.cpp +2 -2
- package/src/duckdb/src/storage/table/column_data.cpp +2 -2
- package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +18 -6
- package/src/duckdb/src/storage/table/column_segment.cpp +23 -24
- package/src/duckdb/src/storage/table/row_group.cpp +3 -3
- package/src/duckdb/src/storage/table/row_group_collection.cpp +1 -1
- package/src/duckdb/src/storage/table/update_segment.cpp +15 -15
- package/src/duckdb/src/storage/wal_replay.cpp +1 -1
- package/src/duckdb/src/transaction/cleanup_state.cpp +10 -10
- package/src/duckdb/src/transaction/commit_state.cpp +19 -19
- package/src/duckdb/src/transaction/duck_transaction.cpp +7 -7
- package/src/duckdb/src/transaction/rollback_state.cpp +1 -1
- package/src/duckdb/src/transaction/undo_buffer.cpp +2 -1
- package/src/duckdb/ub_src_common_adbc.cpp +4 -0
- package/src/duckdb/src/include/duckdb/common/single_thread_ptr.hpp +0 -185
@@ -0,0 +1,749 @@
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
3
|
+
// distributed with this work for additional information
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
6
|
+
// "License"); you may not use this file except in compliance
|
7
|
+
// with the License. You may obtain a copy of the License at
|
8
|
+
//
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
//
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
12
|
+
// software distributed under the License is distributed on an
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
// KIND, either express or implied. See the License for the
|
15
|
+
// specific language governing permissions and limitations
|
16
|
+
// under the License.
|
17
|
+
|
18
|
+
#include "duckdb/common/adbc/driver_manager.h"
|
19
|
+
#include "duckdb/common/adbc/adbc.h"
|
20
|
+
#include "duckdb/common/adbc/adbc.hpp"
|
21
|
+
|
22
|
+
#include <algorithm>
|
23
|
+
#include <cstring>
|
24
|
+
#include <string>
|
25
|
+
#include <unordered_map>
|
26
|
+
#include <utility>
|
27
|
+
|
28
|
+
#if defined(_WIN32)
|
29
|
+
#include <windows.h> // Must come first
|
30
|
+
|
31
|
+
#include <libloaderapi.h>
|
32
|
+
#include <strsafe.h>
|
33
|
+
#else
|
34
|
+
#include <dlfcn.h>
|
35
|
+
#endif // defined(_WIN32)
|
36
|
+
|
37
|
+
namespace duckdb_adbc {
|
38
|
+
|
39
|
+
// Platform-specific helpers
|
40
|
+
|
41
|
+
#if defined(_WIN32)
|
42
|
+
/// Append a description of the Windows error to the buffer.
|
43
|
+
void GetWinError(std::string *buffer) {
|
44
|
+
DWORD rc = GetLastError();
|
45
|
+
LPVOID message;
|
46
|
+
|
47
|
+
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
48
|
+
/*lpSource=*/nullptr, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
49
|
+
reinterpret_cast<LPSTR>(&message), /*nSize=*/0, /*Arguments=*/nullptr);
|
50
|
+
|
51
|
+
(*buffer) += '(';
|
52
|
+
(*buffer) += std::to_string(rc);
|
53
|
+
(*buffer) += ") ";
|
54
|
+
(*buffer) += reinterpret_cast<char *>(message);
|
55
|
+
LocalFree(message);
|
56
|
+
}
|
57
|
+
|
58
|
+
#endif // defined(_WIN32)
|
59
|
+
|
60
|
+
// Error handling
|
61
|
+
|
62
|
+
void ReleaseError(struct AdbcError *error) {
|
63
|
+
if (error) {
|
64
|
+
if (error->message)
|
65
|
+
delete[] error->message;
|
66
|
+
error->message = nullptr;
|
67
|
+
error->release = nullptr;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
void SetError(struct AdbcError *error, const std::string &message) {
|
72
|
+
if (!error)
|
73
|
+
return;
|
74
|
+
if (error->message) {
|
75
|
+
// Append
|
76
|
+
std::string buffer = error->message;
|
77
|
+
buffer.reserve(buffer.size() + message.size() + 1);
|
78
|
+
buffer += '\n';
|
79
|
+
buffer += message;
|
80
|
+
error->release(error);
|
81
|
+
|
82
|
+
error->message = new char[buffer.size() + 1];
|
83
|
+
buffer.copy(error->message, buffer.size());
|
84
|
+
error->message[buffer.size()] = '\0';
|
85
|
+
} else {
|
86
|
+
error->message = new char[message.size() + 1];
|
87
|
+
message.copy(error->message, message.size());
|
88
|
+
error->message[message.size()] = '\0';
|
89
|
+
}
|
90
|
+
error->release = ReleaseError;
|
91
|
+
}
|
92
|
+
|
93
|
+
// Driver state
|
94
|
+
|
95
|
+
/// Hold the driver DLL and the driver release callback in the driver struct.
|
96
|
+
struct ManagerDriverState {
|
97
|
+
// The original release callback
|
98
|
+
AdbcStatusCode (*driver_release)(struct AdbcDriver *driver, struct AdbcError *error);
|
99
|
+
|
100
|
+
#if defined(_WIN32)
|
101
|
+
// The loaded DLL
|
102
|
+
HMODULE handle;
|
103
|
+
#endif // defined(_WIN32)
|
104
|
+
};
|
105
|
+
|
106
|
+
/// Unload the driver DLL.
|
107
|
+
static AdbcStatusCode ReleaseDriver(struct AdbcDriver *driver, struct AdbcError *error) {
|
108
|
+
AdbcStatusCode status = ADBC_STATUS_OK;
|
109
|
+
|
110
|
+
if (!driver->private_manager)
|
111
|
+
return status;
|
112
|
+
ManagerDriverState *state = reinterpret_cast<ManagerDriverState *>(driver->private_manager);
|
113
|
+
|
114
|
+
if (state->driver_release) {
|
115
|
+
status = state->driver_release(driver, error);
|
116
|
+
}
|
117
|
+
|
118
|
+
#if defined(_WIN32)
|
119
|
+
// TODO(apache/arrow-adbc#204): causes tests to segfault
|
120
|
+
// if (!FreeLibrary(state->handle)) {
|
121
|
+
// std::string message = "FreeLibrary() failed: ";
|
122
|
+
// GetWinError(&message);
|
123
|
+
// SetError(error, message);
|
124
|
+
// }
|
125
|
+
#endif // defined(_WIN32)
|
126
|
+
|
127
|
+
driver->private_manager = nullptr;
|
128
|
+
delete state;
|
129
|
+
return status;
|
130
|
+
}
|
131
|
+
|
132
|
+
// Default stubs
|
133
|
+
|
134
|
+
AdbcStatusCode ConnectionCommit(struct AdbcConnection *, struct AdbcError *error) {
|
135
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
136
|
+
}
|
137
|
+
|
138
|
+
AdbcStatusCode ConnectionGetInfo(struct AdbcConnection *connection, uint32_t *info_codes, size_t info_codes_length,
|
139
|
+
struct ArrowArrayStream *out, struct AdbcError *error) {
|
140
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
141
|
+
}
|
142
|
+
|
143
|
+
AdbcStatusCode ConnectionGetTableSchema(struct AdbcConnection *, const char *, const char *, const char *,
|
144
|
+
struct ArrowSchema *, struct AdbcError *error) {
|
145
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
146
|
+
}
|
147
|
+
|
148
|
+
AdbcStatusCode ConnectionReadPartition(struct AdbcConnection *connection, const uint8_t *serialized_partition,
|
149
|
+
size_t serialized_length, struct ArrowArrayStream *out,
|
150
|
+
struct AdbcError *error) {
|
151
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
152
|
+
}
|
153
|
+
|
154
|
+
AdbcStatusCode ConnectionRollback(struct AdbcConnection *, struct AdbcError *error) {
|
155
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
156
|
+
}
|
157
|
+
|
158
|
+
AdbcStatusCode StatementBind(struct AdbcStatement *, struct ArrowArray *, struct ArrowSchema *,
|
159
|
+
struct AdbcError *error) {
|
160
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
161
|
+
}
|
162
|
+
|
163
|
+
AdbcStatusCode StatementExecutePartitions(struct AdbcStatement *statement, struct ArrowSchema *schema,
|
164
|
+
struct AdbcPartitions *partitions, int64_t *rows_affected,
|
165
|
+
struct AdbcError *error) {
|
166
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
167
|
+
}
|
168
|
+
|
169
|
+
AdbcStatusCode StatementGetParameterSchema(struct AdbcStatement *statement, struct ArrowSchema *schema,
|
170
|
+
struct AdbcError *error) {
|
171
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
172
|
+
}
|
173
|
+
AdbcStatusCode StatementSetSubstraitPlan(struct AdbcStatement *, const uint8_t *, size_t, struct AdbcError *error) {
|
174
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
175
|
+
}
|
176
|
+
|
177
|
+
/// Temporary state while the database is being configured.
|
178
|
+
struct TempDatabase {
|
179
|
+
std::unordered_map<std::string, std::string> options;
|
180
|
+
std::string driver;
|
181
|
+
// Default name (see adbc.h)
|
182
|
+
std::string entrypoint = "AdbcDriverInit";
|
183
|
+
AdbcDriverInitFunc init_func = nullptr;
|
184
|
+
};
|
185
|
+
|
186
|
+
/// Temporary state while the database is being configured.
|
187
|
+
struct TempConnection {
|
188
|
+
std::unordered_map<std::string, std::string> options;
|
189
|
+
};
|
190
|
+
|
191
|
+
// Direct implementations of API methods
|
192
|
+
|
193
|
+
AdbcStatusCode AdbcDatabaseNew(struct AdbcDatabase *database, struct AdbcError *error) {
|
194
|
+
// Allocate a temporary structure to store options pre-Init
|
195
|
+
database->private_data = new TempDatabase();
|
196
|
+
database->private_driver = nullptr;
|
197
|
+
return ADBC_STATUS_OK;
|
198
|
+
}
|
199
|
+
|
200
|
+
AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase *database, const char *key, const char *value,
|
201
|
+
struct AdbcError *error) {
|
202
|
+
if (database->private_driver) {
|
203
|
+
return database->private_driver->DatabaseSetOption(database, key, value, error);
|
204
|
+
}
|
205
|
+
|
206
|
+
TempDatabase *args = reinterpret_cast<TempDatabase *>(database->private_data);
|
207
|
+
if (std::strcmp(key, "driver") == 0) {
|
208
|
+
args->driver = value;
|
209
|
+
} else if (std::strcmp(key, "entrypoint") == 0) {
|
210
|
+
args->entrypoint = value;
|
211
|
+
} else {
|
212
|
+
args->options[key] = value;
|
213
|
+
}
|
214
|
+
return ADBC_STATUS_OK;
|
215
|
+
}
|
216
|
+
|
217
|
+
AdbcStatusCode AdbcDriverManagerDatabaseSetInitFunc(struct AdbcDatabase *database, AdbcDriverInitFunc init_func,
|
218
|
+
struct AdbcError *error) {
|
219
|
+
if (database->private_driver) {
|
220
|
+
return ADBC_STATUS_INVALID_STATE;
|
221
|
+
}
|
222
|
+
|
223
|
+
TempDatabase *args = reinterpret_cast<TempDatabase *>(database->private_data);
|
224
|
+
args->init_func = init_func;
|
225
|
+
return ADBC_STATUS_OK;
|
226
|
+
}
|
227
|
+
|
228
|
+
AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase *database, struct AdbcError *error) {
|
229
|
+
if (!database->private_data) {
|
230
|
+
SetError(error, "Must call AdbcDatabaseNew first");
|
231
|
+
return ADBC_STATUS_INVALID_STATE;
|
232
|
+
}
|
233
|
+
TempDatabase *args = reinterpret_cast<TempDatabase *>(database->private_data);
|
234
|
+
if (args->init_func) {
|
235
|
+
// Do nothing
|
236
|
+
} else if (args->driver.empty()) {
|
237
|
+
SetError(error, "Must provide 'driver' parameter");
|
238
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
239
|
+
}
|
240
|
+
|
241
|
+
database->private_driver = new AdbcDriver;
|
242
|
+
std::memset(database->private_driver, 0, sizeof(AdbcDriver));
|
243
|
+
AdbcStatusCode status;
|
244
|
+
// So we don't confuse a driver into thinking it's initialized already
|
245
|
+
database->private_data = nullptr;
|
246
|
+
if (args->init_func) {
|
247
|
+
status = AdbcLoadDriverFromInitFunc(args->init_func, ADBC_VERSION_1_0_0, database->private_driver, error);
|
248
|
+
} else {
|
249
|
+
status = AdbcLoadDriver(args->driver.c_str(), args->entrypoint.c_str(), ADBC_VERSION_1_0_0,
|
250
|
+
database->private_driver, error);
|
251
|
+
}
|
252
|
+
if (status != ADBC_STATUS_OK) {
|
253
|
+
// Restore private_data so it will be released by AdbcDatabaseRelease
|
254
|
+
database->private_data = args;
|
255
|
+
if (database->private_driver->release) {
|
256
|
+
database->private_driver->release(database->private_driver, error);
|
257
|
+
}
|
258
|
+
delete database->private_driver;
|
259
|
+
database->private_driver = nullptr;
|
260
|
+
return status;
|
261
|
+
}
|
262
|
+
status = database->private_driver->DatabaseNew(database, error);
|
263
|
+
if (status != ADBC_STATUS_OK) {
|
264
|
+
if (database->private_driver->release) {
|
265
|
+
database->private_driver->release(database->private_driver, error);
|
266
|
+
}
|
267
|
+
delete database->private_driver;
|
268
|
+
database->private_driver = nullptr;
|
269
|
+
return status;
|
270
|
+
}
|
271
|
+
for (const auto &option : args->options) {
|
272
|
+
status =
|
273
|
+
database->private_driver->DatabaseSetOption(database, option.first.c_str(), option.second.c_str(), error);
|
274
|
+
if (status != ADBC_STATUS_OK) {
|
275
|
+
delete args;
|
276
|
+
// Release the database
|
277
|
+
std::ignore = database->private_driver->DatabaseRelease(database, error);
|
278
|
+
if (database->private_driver->release) {
|
279
|
+
database->private_driver->release(database->private_driver, error);
|
280
|
+
}
|
281
|
+
delete database->private_driver;
|
282
|
+
database->private_driver = nullptr;
|
283
|
+
// Should be redundant, but ensure that AdbcDatabaseRelease
|
284
|
+
// below doesn't think that it contains a TempDatabase
|
285
|
+
database->private_data = nullptr;
|
286
|
+
return status;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
delete args;
|
290
|
+
return database->private_driver->DatabaseInit(database, error);
|
291
|
+
}
|
292
|
+
|
293
|
+
AdbcStatusCode AdbcDatabaseRelease(struct AdbcDatabase *database, struct AdbcError *error) {
|
294
|
+
if (!database->private_driver) {
|
295
|
+
if (database->private_data) {
|
296
|
+
TempDatabase *args = reinterpret_cast<TempDatabase *>(database->private_data);
|
297
|
+
delete args;
|
298
|
+
database->private_data = nullptr;
|
299
|
+
return ADBC_STATUS_OK;
|
300
|
+
}
|
301
|
+
return ADBC_STATUS_INVALID_STATE;
|
302
|
+
}
|
303
|
+
auto status = database->private_driver->DatabaseRelease(database, error);
|
304
|
+
if (database->private_driver->release) {
|
305
|
+
database->private_driver->release(database->private_driver, error);
|
306
|
+
}
|
307
|
+
delete database->private_driver;
|
308
|
+
database->private_data = nullptr;
|
309
|
+
database->private_driver = nullptr;
|
310
|
+
return status;
|
311
|
+
}
|
312
|
+
|
313
|
+
AdbcStatusCode AdbcConnectionCommit(struct AdbcConnection *connection, struct AdbcError *error) {
|
314
|
+
if (!connection->private_driver) {
|
315
|
+
return ADBC_STATUS_INVALID_STATE;
|
316
|
+
}
|
317
|
+
return connection->private_driver->ConnectionCommit(connection, error);
|
318
|
+
}
|
319
|
+
|
320
|
+
AdbcStatusCode AdbcConnectionGetInfo(struct AdbcConnection *connection, uint32_t *info_codes, size_t info_codes_length,
|
321
|
+
struct ArrowArrayStream *out, struct AdbcError *error) {
|
322
|
+
if (!connection->private_driver) {
|
323
|
+
return ADBC_STATUS_INVALID_STATE;
|
324
|
+
}
|
325
|
+
return connection->private_driver->ConnectionGetInfo(connection, info_codes, info_codes_length, out, error);
|
326
|
+
}
|
327
|
+
|
328
|
+
AdbcStatusCode AdbcConnectionGetObjects(struct AdbcConnection *connection, int depth, const char *catalog,
|
329
|
+
const char *db_schema, const char *table_name, const char **table_types,
|
330
|
+
const char *column_name, struct ArrowArrayStream *stream,
|
331
|
+
struct AdbcError *error) {
|
332
|
+
if (!connection->private_driver) {
|
333
|
+
return ADBC_STATUS_INVALID_STATE;
|
334
|
+
}
|
335
|
+
return connection->private_driver->ConnectionGetObjects(connection, depth, catalog, db_schema, table_name,
|
336
|
+
table_types, column_name, stream, error);
|
337
|
+
}
|
338
|
+
|
339
|
+
AdbcStatusCode AdbcConnectionGetTableSchema(struct AdbcConnection *connection, const char *catalog,
|
340
|
+
const char *db_schema, const char *table_name, struct ArrowSchema *schema,
|
341
|
+
struct AdbcError *error) {
|
342
|
+
if (!connection->private_driver) {
|
343
|
+
return ADBC_STATUS_INVALID_STATE;
|
344
|
+
}
|
345
|
+
return connection->private_driver->ConnectionGetTableSchema(connection, catalog, db_schema, table_name, schema,
|
346
|
+
error);
|
347
|
+
}
|
348
|
+
|
349
|
+
AdbcStatusCode AdbcConnectionGetTableTypes(struct AdbcConnection *connection, struct ArrowArrayStream *stream,
|
350
|
+
struct AdbcError *error) {
|
351
|
+
if (!connection->private_driver) {
|
352
|
+
return ADBC_STATUS_INVALID_STATE;
|
353
|
+
}
|
354
|
+
return connection->private_driver->ConnectionGetTableTypes(connection, stream, error);
|
355
|
+
}
|
356
|
+
|
357
|
+
AdbcStatusCode AdbcConnectionInit(struct AdbcConnection *connection, struct AdbcDatabase *database,
|
358
|
+
struct AdbcError *error) {
|
359
|
+
if (!connection->private_data) {
|
360
|
+
SetError(error, "Must call AdbcConnectionNew first");
|
361
|
+
return ADBC_STATUS_INVALID_STATE;
|
362
|
+
} else if (!database->private_driver) {
|
363
|
+
SetError(error, "Database is not initialized");
|
364
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
365
|
+
}
|
366
|
+
TempConnection *args = reinterpret_cast<TempConnection *>(connection->private_data);
|
367
|
+
connection->private_data = nullptr;
|
368
|
+
std::unordered_map<std::string, std::string> options = std::move(args->options);
|
369
|
+
delete args;
|
370
|
+
|
371
|
+
auto status = database->private_driver->ConnectionNew(connection, error);
|
372
|
+
if (status != ADBC_STATUS_OK)
|
373
|
+
return status;
|
374
|
+
connection->private_driver = database->private_driver;
|
375
|
+
|
376
|
+
for (const auto &option : options) {
|
377
|
+
status = database->private_driver->ConnectionSetOption(connection, option.first.c_str(), option.second.c_str(),
|
378
|
+
error);
|
379
|
+
if (status != ADBC_STATUS_OK)
|
380
|
+
return status;
|
381
|
+
}
|
382
|
+
return connection->private_driver->ConnectionInit(connection, database, error);
|
383
|
+
}
|
384
|
+
|
385
|
+
AdbcStatusCode AdbcConnectionNew(struct AdbcConnection *connection, struct AdbcError *error) {
|
386
|
+
// Allocate a temporary structure to store options pre-Init, because
|
387
|
+
// we don't get access to the database (and hence the driver
|
388
|
+
// function table) until then
|
389
|
+
connection->private_data = new TempConnection;
|
390
|
+
connection->private_driver = nullptr;
|
391
|
+
return ADBC_STATUS_OK;
|
392
|
+
}
|
393
|
+
|
394
|
+
AdbcStatusCode AdbcConnectionReadPartition(struct AdbcConnection *connection, const uint8_t *serialized_partition,
|
395
|
+
size_t serialized_length, struct ArrowArrayStream *out,
|
396
|
+
struct AdbcError *error) {
|
397
|
+
if (!connection->private_driver) {
|
398
|
+
return ADBC_STATUS_INVALID_STATE;
|
399
|
+
}
|
400
|
+
return connection->private_driver->ConnectionReadPartition(connection, serialized_partition, serialized_length, out,
|
401
|
+
error);
|
402
|
+
}
|
403
|
+
|
404
|
+
AdbcStatusCode AdbcConnectionRelease(struct AdbcConnection *connection, struct AdbcError *error) {
|
405
|
+
if (!connection->private_driver) {
|
406
|
+
if (connection->private_data) {
|
407
|
+
TempConnection *args = reinterpret_cast<TempConnection *>(connection->private_data);
|
408
|
+
delete args;
|
409
|
+
connection->private_data = nullptr;
|
410
|
+
return ADBC_STATUS_OK;
|
411
|
+
}
|
412
|
+
return ADBC_STATUS_INVALID_STATE;
|
413
|
+
}
|
414
|
+
auto status = connection->private_driver->ConnectionRelease(connection, error);
|
415
|
+
connection->private_driver = nullptr;
|
416
|
+
return status;
|
417
|
+
}
|
418
|
+
|
419
|
+
AdbcStatusCode AdbcConnectionRollback(struct AdbcConnection *connection, struct AdbcError *error) {
|
420
|
+
if (!connection->private_driver) {
|
421
|
+
return ADBC_STATUS_INVALID_STATE;
|
422
|
+
}
|
423
|
+
return connection->private_driver->ConnectionRollback(connection, error);
|
424
|
+
}
|
425
|
+
|
426
|
+
AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection *connection, const char *key, const char *value,
|
427
|
+
struct AdbcError *error) {
|
428
|
+
if (!connection->private_data) {
|
429
|
+
SetError(error, "AdbcConnectionSetOption: must AdbcConnectionNew first");
|
430
|
+
return ADBC_STATUS_INVALID_STATE;
|
431
|
+
}
|
432
|
+
if (!connection->private_driver) {
|
433
|
+
// Init not yet called, save the option
|
434
|
+
TempConnection *args = reinterpret_cast<TempConnection *>(connection->private_data);
|
435
|
+
args->options[key] = value;
|
436
|
+
return ADBC_STATUS_OK;
|
437
|
+
}
|
438
|
+
return connection->private_driver->ConnectionSetOption(connection, key, value, error);
|
439
|
+
}
|
440
|
+
|
441
|
+
AdbcStatusCode AdbcStatementBind(struct AdbcStatement *statement, struct ArrowArray *values, struct ArrowSchema *schema,
|
442
|
+
struct AdbcError *error) {
|
443
|
+
if (!statement->private_driver) {
|
444
|
+
return ADBC_STATUS_INVALID_STATE;
|
445
|
+
}
|
446
|
+
return statement->private_driver->StatementBind(statement, values, schema, error);
|
447
|
+
}
|
448
|
+
|
449
|
+
AdbcStatusCode AdbcStatementBindStream(struct AdbcStatement *statement, struct ArrowArrayStream *stream,
|
450
|
+
struct AdbcError *error) {
|
451
|
+
if (!statement->private_driver) {
|
452
|
+
return ADBC_STATUS_INVALID_STATE;
|
453
|
+
}
|
454
|
+
return statement->private_driver->StatementBindStream(statement, stream, error);
|
455
|
+
}
|
456
|
+
|
457
|
+
// XXX: cpplint gets confused here if declared as 'struct ArrowSchema* schema'
|
458
|
+
AdbcStatusCode AdbcStatementExecutePartitions(struct AdbcStatement *statement, ArrowSchema *schema,
|
459
|
+
struct AdbcPartitions *partitions, int64_t *rows_affected,
|
460
|
+
struct AdbcError *error) {
|
461
|
+
if (!statement->private_driver) {
|
462
|
+
return ADBC_STATUS_INVALID_STATE;
|
463
|
+
}
|
464
|
+
return statement->private_driver->StatementExecutePartitions(statement, schema, partitions, rows_affected, error);
|
465
|
+
}
|
466
|
+
|
467
|
+
AdbcStatusCode AdbcStatementExecuteQuery(struct AdbcStatement *statement, struct ArrowArrayStream *out,
|
468
|
+
int64_t *rows_affected, struct AdbcError *error) {
|
469
|
+
if (!statement->private_driver) {
|
470
|
+
return ADBC_STATUS_INVALID_STATE;
|
471
|
+
}
|
472
|
+
return statement->private_driver->StatementExecuteQuery(statement, out, rows_affected, error);
|
473
|
+
}
|
474
|
+
|
475
|
+
AdbcStatusCode AdbcStatementGetParameterSchema(struct AdbcStatement *statement, struct ArrowSchema *schema,
|
476
|
+
struct AdbcError *error) {
|
477
|
+
if (!statement->private_driver) {
|
478
|
+
return ADBC_STATUS_INVALID_STATE;
|
479
|
+
}
|
480
|
+
return statement->private_driver->StatementGetParameterSchema(statement, schema, error);
|
481
|
+
}
|
482
|
+
|
483
|
+
AdbcStatusCode AdbcStatementNew(struct AdbcConnection *connection, struct AdbcStatement *statement,
|
484
|
+
struct AdbcError *error) {
|
485
|
+
if (!connection->private_driver) {
|
486
|
+
return ADBC_STATUS_INVALID_STATE;
|
487
|
+
}
|
488
|
+
auto status = connection->private_driver->StatementNew(connection, statement, error);
|
489
|
+
statement->private_driver = connection->private_driver;
|
490
|
+
return status;
|
491
|
+
}
|
492
|
+
|
493
|
+
AdbcStatusCode AdbcStatementPrepare(struct AdbcStatement *statement, struct AdbcError *error) {
|
494
|
+
if (!statement->private_driver) {
|
495
|
+
return ADBC_STATUS_INVALID_STATE;
|
496
|
+
}
|
497
|
+
return statement->private_driver->StatementPrepare(statement, error);
|
498
|
+
}
|
499
|
+
|
500
|
+
AdbcStatusCode AdbcStatementRelease(struct AdbcStatement *statement, struct AdbcError *error) {
|
501
|
+
if (!statement->private_driver) {
|
502
|
+
return ADBC_STATUS_INVALID_STATE;
|
503
|
+
}
|
504
|
+
auto status = statement->private_driver->StatementRelease(statement, error);
|
505
|
+
statement->private_driver = nullptr;
|
506
|
+
return status;
|
507
|
+
}
|
508
|
+
|
509
|
+
AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement *statement, const char *key, const char *value,
|
510
|
+
struct AdbcError *error) {
|
511
|
+
if (!statement->private_driver) {
|
512
|
+
return ADBC_STATUS_INVALID_STATE;
|
513
|
+
}
|
514
|
+
return statement->private_driver->StatementSetOption(statement, key, value, error);
|
515
|
+
}
|
516
|
+
|
517
|
+
AdbcStatusCode AdbcStatementSetSqlQuery(struct AdbcStatement *statement, const char *query, struct AdbcError *error) {
|
518
|
+
if (!statement->private_driver) {
|
519
|
+
return ADBC_STATUS_INVALID_STATE;
|
520
|
+
}
|
521
|
+
return statement->private_driver->StatementSetSqlQuery(statement, query, error);
|
522
|
+
}
|
523
|
+
|
524
|
+
AdbcStatusCode AdbcStatementSetSubstraitPlan(struct AdbcStatement *statement, const uint8_t *plan, size_t length,
|
525
|
+
struct AdbcError *error) {
|
526
|
+
if (!statement->private_driver) {
|
527
|
+
return ADBC_STATUS_INVALID_STATE;
|
528
|
+
}
|
529
|
+
return statement->private_driver->StatementSetSubstraitPlan(statement, plan, length, error);
|
530
|
+
}
|
531
|
+
|
532
|
+
const char *AdbcStatusCodeMessage(AdbcStatusCode code) {
|
533
|
+
#define STRINGIFY(s) #s
|
534
|
+
#define STRINGIFY_VALUE(s) STRINGIFY(s)
|
535
|
+
#define CASE(CONSTANT) \
|
536
|
+
case CONSTANT: \
|
537
|
+
return #CONSTANT " (" STRINGIFY_VALUE(CONSTANT) ")";
|
538
|
+
|
539
|
+
switch (code) {
|
540
|
+
CASE(ADBC_STATUS_OK);
|
541
|
+
CASE(ADBC_STATUS_UNKNOWN);
|
542
|
+
CASE(ADBC_STATUS_NOT_IMPLEMENTED);
|
543
|
+
CASE(ADBC_STATUS_NOT_FOUND);
|
544
|
+
CASE(ADBC_STATUS_ALREADY_EXISTS);
|
545
|
+
CASE(ADBC_STATUS_INVALID_ARGUMENT);
|
546
|
+
CASE(ADBC_STATUS_INVALID_STATE);
|
547
|
+
CASE(ADBC_STATUS_INVALID_DATA);
|
548
|
+
CASE(ADBC_STATUS_INTEGRITY);
|
549
|
+
CASE(ADBC_STATUS_INTERNAL);
|
550
|
+
CASE(ADBC_STATUS_IO);
|
551
|
+
CASE(ADBC_STATUS_CANCELLED);
|
552
|
+
CASE(ADBC_STATUS_TIMEOUT);
|
553
|
+
CASE(ADBC_STATUS_UNAUTHENTICATED);
|
554
|
+
CASE(ADBC_STATUS_UNAUTHORIZED);
|
555
|
+
default:
|
556
|
+
return "(invalid code)";
|
557
|
+
}
|
558
|
+
#undef CASE
|
559
|
+
#undef STRINGIFY_VALUE
|
560
|
+
#undef STRINGIFY
|
561
|
+
}
|
562
|
+
|
563
|
+
AdbcStatusCode AdbcLoadDriver(const char *driver_name, const char *entrypoint, int version, void *raw_driver,
|
564
|
+
struct AdbcError *error) {
|
565
|
+
AdbcDriverInitFunc init_func;
|
566
|
+
std::string error_message;
|
567
|
+
|
568
|
+
if (version != ADBC_VERSION_1_0_0) {
|
569
|
+
SetError(error, "Only ADBC 1.0.0 is supported");
|
570
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
571
|
+
}
|
572
|
+
|
573
|
+
auto *driver = reinterpret_cast<struct AdbcDriver *>(raw_driver);
|
574
|
+
|
575
|
+
if (!entrypoint) {
|
576
|
+
// Default entrypoint (see adbc.h)
|
577
|
+
entrypoint = "AdbcDriverInit";
|
578
|
+
}
|
579
|
+
|
580
|
+
#if defined(_WIN32)
|
581
|
+
|
582
|
+
HMODULE handle = LoadLibraryExA(driver_name, NULL, 0);
|
583
|
+
if (!handle) {
|
584
|
+
error_message += driver_name;
|
585
|
+
error_message += ": LoadLibraryExA() failed: ";
|
586
|
+
GetWinError(&error_message);
|
587
|
+
|
588
|
+
std::string full_driver_name = driver_name;
|
589
|
+
full_driver_name += ".lib";
|
590
|
+
handle = LoadLibraryExA(full_driver_name.c_str(), NULL, 0);
|
591
|
+
if (!handle) {
|
592
|
+
error_message += '\n';
|
593
|
+
error_message += full_driver_name;
|
594
|
+
error_message += ": LoadLibraryExA() failed: ";
|
595
|
+
GetWinError(&error_message);
|
596
|
+
}
|
597
|
+
}
|
598
|
+
if (!handle) {
|
599
|
+
SetError(error, error_message);
|
600
|
+
return ADBC_STATUS_INTERNAL;
|
601
|
+
}
|
602
|
+
|
603
|
+
void *load_handle = reinterpret_cast<void *>(GetProcAddress(handle, entrypoint));
|
604
|
+
init_func = reinterpret_cast<AdbcDriverInitFunc>(load_handle);
|
605
|
+
if (!init_func) {
|
606
|
+
std::string message = "GetProcAddress(";
|
607
|
+
message += entrypoint;
|
608
|
+
message += ") failed: ";
|
609
|
+
GetWinError(&message);
|
610
|
+
if (!FreeLibrary(handle)) {
|
611
|
+
message += "\nFreeLibrary() failed: ";
|
612
|
+
GetWinError(&message);
|
613
|
+
}
|
614
|
+
SetError(error, message);
|
615
|
+
return ADBC_STATUS_INTERNAL;
|
616
|
+
}
|
617
|
+
|
618
|
+
#else
|
619
|
+
|
620
|
+
#if defined(__APPLE__)
|
621
|
+
const std::string kPlatformLibraryPrefix = "lib";
|
622
|
+
const std::string kPlatformLibrarySuffix = ".dylib";
|
623
|
+
#else
|
624
|
+
const std::string kPlatformLibraryPrefix = "lib";
|
625
|
+
const std::string kPlatformLibrarySuffix = ".so";
|
626
|
+
#endif // defined(__APPLE__)
|
627
|
+
|
628
|
+
void *handle = dlopen(driver_name, RTLD_NOW | RTLD_LOCAL);
|
629
|
+
if (!handle) {
|
630
|
+
error_message = "dlopen() failed: ";
|
631
|
+
error_message += dlerror();
|
632
|
+
|
633
|
+
// If applicable, append the shared library prefix/extension and
|
634
|
+
// try again (this way you don't have to hardcode driver names by
|
635
|
+
// platform in the application)
|
636
|
+
const std::string driver_str = driver_name;
|
637
|
+
|
638
|
+
std::string full_driver_name;
|
639
|
+
if (driver_str.size() < kPlatformLibraryPrefix.size() ||
|
640
|
+
driver_str.compare(0, kPlatformLibraryPrefix.size(), kPlatformLibraryPrefix) != 0) {
|
641
|
+
full_driver_name += kPlatformLibraryPrefix;
|
642
|
+
}
|
643
|
+
full_driver_name += driver_name;
|
644
|
+
if (driver_str.size() < kPlatformLibrarySuffix.size() ||
|
645
|
+
driver_str.compare(full_driver_name.size() - kPlatformLibrarySuffix.size(), kPlatformLibrarySuffix.size(),
|
646
|
+
kPlatformLibrarySuffix) != 0) {
|
647
|
+
full_driver_name += kPlatformLibrarySuffix;
|
648
|
+
}
|
649
|
+
handle = dlopen(full_driver_name.c_str(), RTLD_NOW | RTLD_LOCAL);
|
650
|
+
if (!handle) {
|
651
|
+
error_message += "\ndlopen() failed: ";
|
652
|
+
error_message += dlerror();
|
653
|
+
}
|
654
|
+
}
|
655
|
+
if (!handle) {
|
656
|
+
SetError(error, error_message);
|
657
|
+
// AdbcDatabaseInit tries to call this if set
|
658
|
+
driver->release = nullptr;
|
659
|
+
return ADBC_STATUS_INTERNAL;
|
660
|
+
}
|
661
|
+
|
662
|
+
void *load_handle = dlsym(handle, entrypoint);
|
663
|
+
if (!load_handle) {
|
664
|
+
std::string message = "dlsym(";
|
665
|
+
message += entrypoint;
|
666
|
+
message += ") failed: ";
|
667
|
+
message += dlerror();
|
668
|
+
SetError(error, message);
|
669
|
+
return ADBC_STATUS_INTERNAL;
|
670
|
+
}
|
671
|
+
init_func = reinterpret_cast<AdbcDriverInitFunc>(load_handle);
|
672
|
+
|
673
|
+
#endif // defined(_WIN32)
|
674
|
+
|
675
|
+
AdbcStatusCode status = AdbcLoadDriverFromInitFunc(init_func, version, driver, error);
|
676
|
+
if (status == ADBC_STATUS_OK) {
|
677
|
+
ManagerDriverState *state = new ManagerDriverState;
|
678
|
+
state->driver_release = driver->release;
|
679
|
+
#if defined(_WIN32)
|
680
|
+
state->handle = handle;
|
681
|
+
#endif // defined(_WIN32)
|
682
|
+
driver->release = &ReleaseDriver;
|
683
|
+
driver->private_manager = state;
|
684
|
+
} else {
|
685
|
+
#if defined(_WIN32)
|
686
|
+
if (!FreeLibrary(handle)) {
|
687
|
+
std::string message = "FreeLibrary() failed: ";
|
688
|
+
GetWinError(&message);
|
689
|
+
SetError(error, message);
|
690
|
+
}
|
691
|
+
#endif // defined(_WIN32)
|
692
|
+
}
|
693
|
+
return status;
|
694
|
+
}
|
695
|
+
|
696
|
+
AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int version, void *raw_driver,
|
697
|
+
struct AdbcError *error) {
|
698
|
+
#define FILL_DEFAULT(DRIVER, STUB) \
|
699
|
+
if (!DRIVER->STUB) { \
|
700
|
+
DRIVER->STUB = &STUB; \
|
701
|
+
}
|
702
|
+
#define CHECK_REQUIRED(DRIVER, STUB) \
|
703
|
+
if (!DRIVER->STUB) { \
|
704
|
+
SetError(error, "Driver does not implement required function Adbc" #STUB); \
|
705
|
+
return ADBC_STATUS_INTERNAL; \
|
706
|
+
}
|
707
|
+
|
708
|
+
auto result = init_func(version, raw_driver, error);
|
709
|
+
if (result != ADBC_STATUS_OK) {
|
710
|
+
return result;
|
711
|
+
}
|
712
|
+
|
713
|
+
if (version == ADBC_VERSION_1_0_0) {
|
714
|
+
auto *driver = reinterpret_cast<struct AdbcDriver *>(raw_driver);
|
715
|
+
CHECK_REQUIRED(driver, DatabaseNew);
|
716
|
+
CHECK_REQUIRED(driver, DatabaseInit);
|
717
|
+
CHECK_REQUIRED(driver, DatabaseRelease);
|
718
|
+
FILL_DEFAULT(driver, DatabaseSetOption);
|
719
|
+
|
720
|
+
CHECK_REQUIRED(driver, ConnectionNew);
|
721
|
+
CHECK_REQUIRED(driver, ConnectionInit);
|
722
|
+
CHECK_REQUIRED(driver, ConnectionRelease);
|
723
|
+
FILL_DEFAULT(driver, ConnectionCommit);
|
724
|
+
FILL_DEFAULT(driver, ConnectionGetInfo);
|
725
|
+
FILL_DEFAULT(driver, ConnectionGetObjects);
|
726
|
+
FILL_DEFAULT(driver, ConnectionGetTableSchema);
|
727
|
+
FILL_DEFAULT(driver, ConnectionGetTableTypes);
|
728
|
+
FILL_DEFAULT(driver, ConnectionReadPartition);
|
729
|
+
FILL_DEFAULT(driver, ConnectionRollback);
|
730
|
+
FILL_DEFAULT(driver, ConnectionSetOption);
|
731
|
+
|
732
|
+
FILL_DEFAULT(driver, StatementExecutePartitions);
|
733
|
+
CHECK_REQUIRED(driver, StatementExecuteQuery);
|
734
|
+
CHECK_REQUIRED(driver, StatementNew);
|
735
|
+
CHECK_REQUIRED(driver, StatementRelease);
|
736
|
+
FILL_DEFAULT(driver, StatementBind);
|
737
|
+
FILL_DEFAULT(driver, StatementGetParameterSchema);
|
738
|
+
FILL_DEFAULT(driver, StatementPrepare);
|
739
|
+
FILL_DEFAULT(driver, StatementSetOption);
|
740
|
+
FILL_DEFAULT(driver, StatementSetSqlQuery);
|
741
|
+
FILL_DEFAULT(driver, StatementSetSubstraitPlan);
|
742
|
+
}
|
743
|
+
|
744
|
+
return ADBC_STATUS_OK;
|
745
|
+
|
746
|
+
#undef FILL_DEFAULT
|
747
|
+
#undef CHECK_REQUIRED
|
748
|
+
}
|
749
|
+
} // namespace duckdb_adbc
|