duckdb 0.8.1-dev31.0 → 0.8.1-dev65.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/package.json +1 -1
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +3 -0
- package/src/duckdb/src/catalog/catalog_entry.cpp +4 -4
- package/src/duckdb/src/catalog/duck_catalog.cpp +1 -0
- package/src/duckdb/src/common/adbc/adbc.cpp +183 -94
- package/src/duckdb/src/common/adbc/driver_manager.cpp +10 -2
- package/src/duckdb/src/common/file_system.cpp +15 -2
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/adbc/adbc.hpp +5 -0
- package/src/duckdb/src/optimizer/expression_heuristics.cpp +1 -0
- package/src/duckdb/src/storage/index.cpp +1 -3
- package/src/duckdb/src/storage/local_storage.cpp +2 -1
- package/src/duckdb/src/storage/magic_bytes.cpp +1 -1
package/package.json
CHANGED
@@ -206,6 +206,7 @@ const vector<unique_ptr<Constraint>> &TableCatalogEntry::GetConstraints() {
|
|
206
206
|
return constraints;
|
207
207
|
}
|
208
208
|
|
209
|
+
// LCOV_EXCL_START
|
209
210
|
DataTable &TableCatalogEntry::GetStorage() {
|
210
211
|
throw InternalException("Calling GetStorage on a TableCatalogEntry that is not a DuckTableEntry");
|
211
212
|
}
|
@@ -213,4 +214,6 @@ DataTable &TableCatalogEntry::GetStorage() {
|
|
213
214
|
const vector<unique_ptr<BoundConstraint>> &TableCatalogEntry::GetBoundConstraints() {
|
214
215
|
throw InternalException("Calling GetBoundConstraints on a TableCatalogEntry that is not a DuckTableEntry");
|
215
216
|
}
|
217
|
+
// LCOV_EXCL_STOP
|
218
|
+
|
216
219
|
} // namespace duckdb
|
@@ -34,10 +34,6 @@ unique_ptr<CatalogEntry> CatalogEntry::Copy(ClientContext &context) const {
|
|
34
34
|
string CatalogEntry::ToSQL() const {
|
35
35
|
throw InternalException("Unsupported catalog type for ToSQL()");
|
36
36
|
}
|
37
|
-
// LCOV_EXCL_STOP
|
38
|
-
|
39
|
-
void CatalogEntry::Verify(Catalog &catalog_p) {
|
40
|
-
}
|
41
37
|
|
42
38
|
Catalog &CatalogEntry::ParentCatalog() {
|
43
39
|
throw InternalException("CatalogEntry::ParentCatalog called on catalog entry without catalog");
|
@@ -46,6 +42,10 @@ Catalog &CatalogEntry::ParentCatalog() {
|
|
46
42
|
SchemaCatalogEntry &CatalogEntry::ParentSchema() {
|
47
43
|
throw InternalException("CatalogEntry::ParentSchema called on catalog entry without schema");
|
48
44
|
}
|
45
|
+
// LCOV_EXCL_STOP
|
46
|
+
|
47
|
+
void CatalogEntry::Verify(Catalog &catalog_p) {
|
48
|
+
}
|
49
49
|
|
50
50
|
InCatalogEntry::InCatalogEntry(CatalogType type, Catalog &catalog, string name)
|
51
51
|
: CatalogEntry(type, catalog, std::move(name)), catalog(catalog) {
|
@@ -12,7 +12,7 @@
|
|
12
12
|
#include <string.h>
|
13
13
|
#include <stdlib.h>
|
14
14
|
|
15
|
-
// We
|
15
|
+
// We must leak the symbols of the init function
|
16
16
|
duckdb_adbc::AdbcStatusCode duckdb_adbc_init(size_t count, struct duckdb_adbc::AdbcDriver *driver,
|
17
17
|
struct duckdb_adbc::AdbcError *error) {
|
18
18
|
if (!driver) {
|
@@ -41,23 +41,16 @@ duckdb_adbc::AdbcStatusCode duckdb_adbc_init(size_t count, struct duckdb_adbc::A
|
|
41
41
|
}
|
42
42
|
|
43
43
|
namespace duckdb_adbc {
|
44
|
-
|
45
|
-
if (!
|
46
|
-
|
47
|
-
e->message = strdup(m); /* TODO Set cleanup callback */ \
|
48
|
-
} \
|
49
|
-
return ADBC_STATUS_INVALID_ARGUMENT; \
|
44
|
+
AdbcStatusCode SetErrorMaybe(const void *result, AdbcError *error, const std::string &error_message) {
|
45
|
+
if (!error) {
|
46
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
50
47
|
}
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
if (e) { \
|
55
|
-
e->message = strdup(m); \
|
56
|
-
} \
|
57
|
-
return ADBC_STATUS_INTERNAL; \
|
58
|
-
} else { \
|
59
|
-
return ADBC_STATUS_OK; \
|
48
|
+
if (!result) {
|
49
|
+
SetError(error, error_message);
|
50
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
60
51
|
}
|
52
|
+
return ADBC_STATUS_OK;
|
53
|
+
}
|
61
54
|
|
62
55
|
struct DuckDBAdbcDatabaseWrapper {
|
63
56
|
//! The DuckDB Database Configuration
|
@@ -68,25 +61,58 @@ struct DuckDBAdbcDatabaseWrapper {
|
|
68
61
|
std::string path;
|
69
62
|
};
|
70
63
|
|
71
|
-
|
72
|
-
|
64
|
+
void InitiliazeADBCError(AdbcError *error) {
|
65
|
+
if (!error) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
error->message = nullptr;
|
69
|
+
error->release = nullptr;
|
70
|
+
std::memset(error->sqlstate, '\0', sizeof(error->sqlstate));
|
71
|
+
error->vendor_code = -1;
|
72
|
+
}
|
73
73
|
|
74
|
+
AdbcStatusCode CheckResult(duckdb_state &res, AdbcError *error, const char *error_msg) {
|
75
|
+
if (!error) {
|
76
|
+
// Error should be a non-null pointer
|
77
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
78
|
+
}
|
79
|
+
if (res != DuckDBSuccess) {
|
80
|
+
duckdb_adbc::SetError(error, error_msg);
|
81
|
+
return ADBC_STATUS_INTERNAL;
|
82
|
+
}
|
83
|
+
return ADBC_STATUS_OK;
|
84
|
+
}
|
85
|
+
|
86
|
+
AdbcStatusCode DatabaseNew(struct AdbcDatabase *database, struct AdbcError *error) {
|
87
|
+
auto status = SetErrorMaybe(database, error, "Missing database object");
|
88
|
+
if (status != ADBC_STATUS_OK) {
|
89
|
+
return status;
|
90
|
+
}
|
74
91
|
database->private_data = nullptr;
|
75
92
|
// you can't malloc a struct with a non-trivial C++ constructor
|
76
93
|
// and std::string has a non-trivial constructor. so we need
|
77
94
|
// to use new and delete rather than malloc and free.
|
78
95
|
auto wrapper = new DuckDBAdbcDatabaseWrapper;
|
79
|
-
|
80
|
-
|
96
|
+
status = SetErrorMaybe(wrapper, error, "Allocation error");
|
97
|
+
if (status != ADBC_STATUS_OK) {
|
98
|
+
return status;
|
99
|
+
}
|
81
100
|
database->private_data = wrapper;
|
82
101
|
auto res = duckdb_create_config(&wrapper->config);
|
83
|
-
|
102
|
+
return CheckResult(res, error, "Failed to allocate");
|
84
103
|
}
|
85
104
|
|
86
105
|
AdbcStatusCode DatabaseSetOption(struct AdbcDatabase *database, const char *key, const char *value,
|
87
106
|
struct AdbcError *error) {
|
88
|
-
|
89
|
-
|
107
|
+
auto status = SetErrorMaybe(database, error, "Missing database object");
|
108
|
+
if (status != ADBC_STATUS_OK) {
|
109
|
+
return status;
|
110
|
+
}
|
111
|
+
|
112
|
+
status = SetErrorMaybe(key, error, "Missing key");
|
113
|
+
if (status != ADBC_STATUS_OK) {
|
114
|
+
return status;
|
115
|
+
}
|
90
116
|
|
91
117
|
auto wrapper = (DuckDBAdbcDatabaseWrapper *)database->private_data;
|
92
118
|
if (strcmp(key, "path") == 0) {
|
@@ -95,17 +121,22 @@ AdbcStatusCode DatabaseSetOption(struct AdbcDatabase *database, const char *key,
|
|
95
121
|
}
|
96
122
|
auto res = duckdb_set_config(wrapper->config, key, value);
|
97
123
|
|
98
|
-
|
124
|
+
return CheckResult(res, error, "Failed to set configuration option");
|
99
125
|
}
|
100
126
|
|
101
127
|
AdbcStatusCode DatabaseInit(struct AdbcDatabase *database, struct AdbcError *error) {
|
128
|
+
if (!error) {
|
129
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
130
|
+
}
|
131
|
+
if (!database) {
|
132
|
+
duckdb_adbc::SetError(error, "ADBC Database has an invalid pointer");
|
133
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
134
|
+
}
|
102
135
|
char *errormsg;
|
103
136
|
// TODO can we set the database path via option, too? Does not look like it...
|
104
137
|
auto wrapper = (DuckDBAdbcDatabaseWrapper *)database->private_data;
|
105
138
|
auto res = duckdb_open_ext(wrapper->path.c_str(), &wrapper->database, wrapper->config, &errormsg);
|
106
|
-
|
107
|
-
// TODO this leaks memory because errormsg is malloc-ed
|
108
|
-
CHECK_RES(res, error, errormsg);
|
139
|
+
return CheckResult(res, error, errormsg);
|
109
140
|
}
|
110
141
|
|
111
142
|
AdbcStatusCode DatabaseRelease(struct AdbcDatabase *database, struct AdbcError *error) {
|
@@ -122,8 +153,11 @@ AdbcStatusCode DatabaseRelease(struct AdbcDatabase *database, struct AdbcError *
|
|
122
153
|
}
|
123
154
|
|
124
155
|
AdbcStatusCode ConnectionNew(struct AdbcConnection *connection, struct AdbcError *error) {
|
156
|
+
auto status = SetErrorMaybe(connection, error, "Missing connection object");
|
157
|
+
if (status != ADBC_STATUS_OK) {
|
158
|
+
return status;
|
159
|
+
}
|
125
160
|
|
126
|
-
CHECK_TRUE(connection, error, "Missing connection object");
|
127
161
|
connection->private_data = nullptr;
|
128
162
|
return ADBC_STATUS_OK;
|
129
163
|
}
|
@@ -136,14 +170,23 @@ AdbcStatusCode ConnectionSetOption(struct AdbcConnection *connection, const char
|
|
136
170
|
|
137
171
|
AdbcStatusCode ConnectionInit(struct AdbcConnection *connection, struct AdbcDatabase *database,
|
138
172
|
struct AdbcError *error) {
|
139
|
-
|
140
|
-
|
141
|
-
|
173
|
+
auto status = SetErrorMaybe(database, error, "Missing database");
|
174
|
+
if (status != ADBC_STATUS_OK) {
|
175
|
+
return status;
|
176
|
+
}
|
177
|
+
status = SetErrorMaybe(database->private_data, error, "Invalid database");
|
178
|
+
if (status != ADBC_STATUS_OK) {
|
179
|
+
return status;
|
180
|
+
}
|
181
|
+
status = SetErrorMaybe(connection, error, "Missing connection");
|
182
|
+
if (status != ADBC_STATUS_OK) {
|
183
|
+
return status;
|
184
|
+
}
|
142
185
|
auto database_wrapper = (DuckDBAdbcDatabaseWrapper *)database->private_data;
|
143
186
|
|
144
187
|
connection->private_data = nullptr;
|
145
188
|
auto res = duckdb_connect(database_wrapper->database, (duckdb_connection *)&connection->private_data);
|
146
|
-
|
189
|
+
return CheckResult(res, error, "Failed to connect to Database");
|
147
190
|
}
|
148
191
|
|
149
192
|
AdbcStatusCode ConnectionRelease(struct AdbcConnection *connection, struct AdbcError *error) {
|
@@ -213,9 +256,20 @@ void stream_schema(uintptr_t factory_ptr, duckdb::ArrowSchemaWrapper &schema) {
|
|
213
256
|
AdbcStatusCode Ingest(duckdb_connection connection, const char *table_name, struct ArrowArrayStream *input,
|
214
257
|
struct AdbcError *error) {
|
215
258
|
|
216
|
-
|
217
|
-
|
218
|
-
|
259
|
+
auto status = SetErrorMaybe(connection, error, "Invalid connection");
|
260
|
+
if (status != ADBC_STATUS_OK) {
|
261
|
+
return status;
|
262
|
+
}
|
263
|
+
|
264
|
+
status = SetErrorMaybe(input, error, "Missing input arrow stream pointer");
|
265
|
+
if (status != ADBC_STATUS_OK) {
|
266
|
+
return status;
|
267
|
+
}
|
268
|
+
|
269
|
+
status = SetErrorMaybe(table_name, error, "Missing database object name");
|
270
|
+
if (status != ADBC_STATUS_OK) {
|
271
|
+
return status;
|
272
|
+
}
|
219
273
|
|
220
274
|
try {
|
221
275
|
// TODO evil cast, do we need a way to do this from the C api?
|
@@ -251,14 +305,28 @@ struct DuckDBAdbcStatementWrapper {
|
|
251
305
|
AdbcStatusCode StatementNew(struct AdbcConnection *connection, struct AdbcStatement *statement,
|
252
306
|
struct AdbcError *error) {
|
253
307
|
|
254
|
-
|
255
|
-
|
256
|
-
|
308
|
+
auto status = SetErrorMaybe(connection, error, "Missing connection object");
|
309
|
+
if (status != ADBC_STATUS_OK) {
|
310
|
+
return status;
|
311
|
+
}
|
312
|
+
|
313
|
+
status = SetErrorMaybe(connection->private_data, error, "Invalid connection object");
|
314
|
+
if (status != ADBC_STATUS_OK) {
|
315
|
+
return status;
|
316
|
+
}
|
317
|
+
|
318
|
+
status = SetErrorMaybe(statement, error, "Missing statement object");
|
319
|
+
if (status != ADBC_STATUS_OK) {
|
320
|
+
return status;
|
321
|
+
}
|
257
322
|
|
258
323
|
statement->private_data = nullptr;
|
259
324
|
|
260
325
|
auto statement_wrapper = (DuckDBAdbcStatementWrapper *)malloc(sizeof(DuckDBAdbcStatementWrapper));
|
261
|
-
|
326
|
+
status = SetErrorMaybe(statement_wrapper, error, "Allocation error");
|
327
|
+
if (status != ADBC_STATUS_OK) {
|
328
|
+
return status;
|
329
|
+
}
|
262
330
|
|
263
331
|
statement->private_data = statement_wrapper;
|
264
332
|
statement_wrapper->connection = (duckdb_connection)connection->private_data;
|
@@ -298,8 +366,16 @@ AdbcStatusCode StatementRelease(struct AdbcStatement *statement, struct AdbcErro
|
|
298
366
|
|
299
367
|
AdbcStatusCode StatementExecuteQuery(struct AdbcStatement *statement, struct ArrowArrayStream *out,
|
300
368
|
int64_t *rows_affected, struct AdbcError *error) {
|
301
|
-
|
302
|
-
|
369
|
+
auto status = SetErrorMaybe(statement, error, "Missing statement object");
|
370
|
+
if (status != ADBC_STATUS_OK) {
|
371
|
+
return status;
|
372
|
+
}
|
373
|
+
|
374
|
+
status = SetErrorMaybe(statement->private_data, error, "Invalid statement object");
|
375
|
+
if (status != ADBC_STATUS_OK) {
|
376
|
+
return status;
|
377
|
+
}
|
378
|
+
|
303
379
|
auto wrapper = (DuckDBAdbcStatementWrapper *)statement->private_data;
|
304
380
|
|
305
381
|
// TODO: Set affected rows, careful with early return
|
@@ -314,7 +390,10 @@ AdbcStatusCode StatementExecuteQuery(struct AdbcStatement *statement, struct Arr
|
|
314
390
|
}
|
315
391
|
|
316
392
|
auto res = duckdb_execute_prepared_arrow(wrapper->statement, &wrapper->result);
|
317
|
-
|
393
|
+
if (res != DuckDBSuccess) {
|
394
|
+
SetError(error, duckdb_query_arrow_error(wrapper->result));
|
395
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
396
|
+
}
|
318
397
|
|
319
398
|
if (out) {
|
320
399
|
out->private_data = wrapper->result;
|
@@ -333,25 +412,45 @@ AdbcStatusCode StatementExecuteQuery(struct AdbcStatement *statement, struct Arr
|
|
333
412
|
|
334
413
|
// this is a nop for us
|
335
414
|
AdbcStatusCode StatementPrepare(struct AdbcStatement *statement, struct AdbcError *error) {
|
336
|
-
|
337
|
-
|
415
|
+
auto status = SetErrorMaybe(statement, error, "Missing statement object");
|
416
|
+
if (status != ADBC_STATUS_OK) {
|
417
|
+
return status;
|
418
|
+
}
|
419
|
+
|
420
|
+
status = SetErrorMaybe(statement->private_data, error, "Invalid statement object");
|
421
|
+
if (status != ADBC_STATUS_OK) {
|
422
|
+
return status;
|
423
|
+
}
|
424
|
+
|
338
425
|
return ADBC_STATUS_OK;
|
339
426
|
}
|
340
427
|
|
341
428
|
AdbcStatusCode StatementSetSqlQuery(struct AdbcStatement *statement, const char *query, struct AdbcError *error) {
|
342
|
-
|
343
|
-
|
429
|
+
auto status = SetErrorMaybe(statement, error, "Missing statement object");
|
430
|
+
if (status != ADBC_STATUS_OK) {
|
431
|
+
return status;
|
432
|
+
}
|
433
|
+
status = SetErrorMaybe(query, error, "Missing query");
|
434
|
+
if (status != ADBC_STATUS_OK) {
|
435
|
+
return status;
|
436
|
+
}
|
344
437
|
|
345
438
|
auto wrapper = (DuckDBAdbcStatementWrapper *)statement->private_data;
|
346
439
|
auto res = duckdb_prepare(wrapper->connection, query, &wrapper->statement);
|
347
|
-
|
348
|
-
|
440
|
+
auto error_msg = duckdb_prepare_error(wrapper->statement);
|
441
|
+
return CheckResult(res, error, error_msg);
|
349
442
|
}
|
350
443
|
|
351
444
|
AdbcStatusCode StatementBindStream(struct AdbcStatement *statement, struct ArrowArrayStream *values,
|
352
445
|
struct AdbcError *error) {
|
353
|
-
|
354
|
-
|
446
|
+
auto status = SetErrorMaybe(statement, error, "Missing statement object");
|
447
|
+
if (status != ADBC_STATUS_OK) {
|
448
|
+
return status;
|
449
|
+
}
|
450
|
+
status = SetErrorMaybe(values, error, "Missing stream object");
|
451
|
+
if (status != ADBC_STATUS_OK) {
|
452
|
+
return status;
|
453
|
+
}
|
355
454
|
auto wrapper = (DuckDBAdbcStatementWrapper *)statement->private_data;
|
356
455
|
wrapper->ingestion_stream = values;
|
357
456
|
return ADBC_STATUS_OK;
|
@@ -359,8 +458,14 @@ AdbcStatusCode StatementBindStream(struct AdbcStatement *statement, struct Arrow
|
|
359
458
|
|
360
459
|
AdbcStatusCode StatementSetOption(struct AdbcStatement *statement, const char *key, const char *value,
|
361
460
|
struct AdbcError *error) {
|
362
|
-
|
363
|
-
|
461
|
+
auto status = SetErrorMaybe(statement, error, "Missing statement object");
|
462
|
+
if (status != ADBC_STATUS_OK) {
|
463
|
+
return status;
|
464
|
+
}
|
465
|
+
status = SetErrorMaybe(key, error, "Missing key object");
|
466
|
+
if (status != ADBC_STATUS_OK) {
|
467
|
+
return status;
|
468
|
+
}
|
364
469
|
auto wrapper = (DuckDBAdbcStatementWrapper *)statement->private_data;
|
365
470
|
|
366
471
|
if (strcmp(key, ADBC_INGEST_OPTION_TARGET_TABLE) == 0) {
|
@@ -372,17 +477,23 @@ AdbcStatusCode StatementSetOption(struct AdbcStatement *statement, const char *k
|
|
372
477
|
|
373
478
|
static AdbcStatusCode QueryInternal(struct AdbcConnection *connection, struct ArrowArrayStream *out, const char *query,
|
374
479
|
struct AdbcError *error) {
|
375
|
-
AdbcStatusCode res;
|
376
480
|
AdbcStatement statement;
|
377
481
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
482
|
+
auto status = StatementNew(connection, &statement, error);
|
483
|
+
if (status != ADBC_STATUS_OK) {
|
484
|
+
SetError(error, "unable to initialize statement");
|
485
|
+
return status;
|
486
|
+
}
|
487
|
+
status = StatementSetSqlQuery(&statement, query, error);
|
488
|
+
if (status != ADBC_STATUS_OK) {
|
489
|
+
SetError(error, "unable to initialize statement");
|
490
|
+
return status;
|
491
|
+
}
|
492
|
+
status = StatementExecuteQuery(&statement, out, nullptr, error);
|
493
|
+
if (status != ADBC_STATUS_OK) {
|
494
|
+
SetError(error, "unable to initialize statement");
|
495
|
+
return status;
|
496
|
+
}
|
386
497
|
|
387
498
|
return ADBC_STATUS_OK;
|
388
499
|
}
|
@@ -390,8 +501,17 @@ static AdbcStatusCode QueryInternal(struct AdbcConnection *connection, struct Ar
|
|
390
501
|
AdbcStatusCode ConnectionGetObjects(struct AdbcConnection *connection, int depth, const char *catalog,
|
391
502
|
const char *db_schema, const char *table_name, const char **table_type,
|
392
503
|
const char *column_name, struct ArrowArrayStream *out, struct AdbcError *error) {
|
393
|
-
|
394
|
-
|
504
|
+
if (catalog != nullptr) {
|
505
|
+
if (strcmp(catalog, "duckdb") == 0) {
|
506
|
+
SetError(error, "catalog must be NULL or 'duckdb'");
|
507
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
508
|
+
}
|
509
|
+
}
|
510
|
+
|
511
|
+
if (table_type != nullptr) {
|
512
|
+
SetError(error, "Table types parameter not yet supported");
|
513
|
+
return ADBC_STATUS_NOT_IMPLEMENTED;
|
514
|
+
}
|
395
515
|
|
396
516
|
auto q = duckdb::StringUtil::Format(R"(
|
397
517
|
SELECT table_schema db_schema_name, LIST(table_schema_list) db_schema_tables FROM (
|
@@ -404,41 +524,10 @@ SELECT table_schema db_schema_name, LIST(table_schema_list) db_schema_tables FRO
|
|
404
524
|
return QueryInternal(connection, out, q.c_str(), error);
|
405
525
|
}
|
406
526
|
|
407
|
-
//
|
408
|
-
// AdbcStatusCode ConnectionGetCatalogs(struct AdbcConnection *connection, struct AdbcStatement *statement,
|
409
|
-
// struct AdbcError *error) {
|
410
|
-
// const char *q = "SELECT 'duckdb' catalog_name";
|
411
|
-
//
|
412
|
-
// return QueryInternal(connection, statement, q, error);
|
413
|
-
//}
|
414
|
-
//
|
415
|
-
// AdbcStatusCode ConnectionGetDbSchemas(struct AdbcConnection *connection, struct AdbcStatement *statement,
|
416
|
-
// struct AdbcError *error) {
|
417
|
-
// const char *q = "SELECT 'duckdb' catalog_name, schema_name db_schema_name FROM information_schema.schemata ORDER "
|
418
|
-
// "BY schema_name";
|
419
|
-
// return QueryInternal(connection, statement, q, error);
|
420
|
-
//}
|
421
527
|
AdbcStatusCode ConnectionGetTableTypes(struct AdbcConnection *connection, struct ArrowArrayStream *out,
|
422
528
|
struct AdbcError *error) {
|
423
529
|
const char *q = "SELECT DISTINCT table_type FROM information_schema.tables ORDER BY table_type";
|
424
530
|
return QueryInternal(connection, out, q, error);
|
425
531
|
}
|
426
|
-
//
|
427
|
-
// AdbcStatusCode ConnectionGetTables(struct AdbcConnection *connection, const char *catalog, const char *db_schema,
|
428
|
-
// const char *table_name, const char **table_types,
|
429
|
-
// struct AdbcStatement *statement, struct AdbcError *error) {
|
430
|
-
//
|
431
|
-
// CHECK_TRUE(catalog == nullptr || strcmp(catalog, "duckdb") == 0, error, "catalog must be NULL or 'duckdb'");
|
432
|
-
//
|
433
|
-
// // let's wait for https://github.com/lidavidm/arrow/issues/6
|
434
|
-
// CHECK_TRUE(table_types == nullptr, error, "table types parameter not yet supported");
|
435
|
-
// auto q = duckdb::StringUtil::Format(
|
436
|
-
// "SELECT 'duckdb' catalog_name, table_schema db_schema_name, table_name, table_type FROM "
|
437
|
-
// "information_schema.tables WHERE table_schema LIKE '%s' AND table_name LIKE '%s' ORDER BY table_schema, "
|
438
|
-
// "table_name",
|
439
|
-
// db_schema ? db_schema : "%", table_name ? table_name : "%");
|
440
|
-
//
|
441
|
-
// return QueryInternal(connection, statement, q.c_str(), error);
|
442
|
-
//}
|
443
532
|
|
444
533
|
} // namespace duckdb_adbc
|
@@ -61,16 +61,18 @@ void GetWinError(std::string *buffer) {
|
|
61
61
|
|
62
62
|
void ReleaseError(struct AdbcError *error) {
|
63
63
|
if (error) {
|
64
|
-
if (error->message)
|
64
|
+
if (error->message) {
|
65
65
|
delete[] error->message;
|
66
|
+
}
|
66
67
|
error->message = nullptr;
|
67
68
|
error->release = nullptr;
|
68
69
|
}
|
69
70
|
}
|
70
71
|
|
71
72
|
void SetError(struct AdbcError *error, const std::string &message) {
|
72
|
-
if (!error)
|
73
|
+
if (!error) {
|
73
74
|
return;
|
75
|
+
}
|
74
76
|
if (error->message) {
|
75
77
|
// Append
|
76
78
|
std::string buffer = error->message;
|
@@ -466,6 +468,9 @@ AdbcStatusCode AdbcStatementExecutePartitions(struct AdbcStatement *statement, A
|
|
466
468
|
|
467
469
|
AdbcStatusCode AdbcStatementExecuteQuery(struct AdbcStatement *statement, struct ArrowArrayStream *out,
|
468
470
|
int64_t *rows_affected, struct AdbcError *error) {
|
471
|
+
if (!statement) {
|
472
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
473
|
+
}
|
469
474
|
if (!statement->private_driver) {
|
470
475
|
return ADBC_STATUS_INVALID_STATE;
|
471
476
|
}
|
@@ -482,6 +487,9 @@ AdbcStatusCode AdbcStatementGetParameterSchema(struct AdbcStatement *statement,
|
|
482
487
|
|
483
488
|
AdbcStatusCode AdbcStatementNew(struct AdbcConnection *connection, struct AdbcStatement *statement,
|
484
489
|
struct AdbcError *error) {
|
490
|
+
if (!connection) {
|
491
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
492
|
+
}
|
485
493
|
if (!connection->private_driver) {
|
486
494
|
return ADBC_STATUS_INVALID_STATE;
|
487
495
|
}
|
@@ -114,9 +114,22 @@ string FileSystem::GetEnvVariable(const string &env) {
|
|
114
114
|
return WindowsUtil::UnicodeToUTF8(res_w);
|
115
115
|
}
|
116
116
|
|
117
|
+
static bool StartsWithSingleBackslash(const string &path) {
|
118
|
+
if (path.size() < 2) {
|
119
|
+
return false;
|
120
|
+
}
|
121
|
+
if (path[0] != '/' && path[0] != '\\') {
|
122
|
+
return false;
|
123
|
+
}
|
124
|
+
if (path[1] == '/' || path[1] == '\\') {
|
125
|
+
return false;
|
126
|
+
}
|
127
|
+
return true;
|
128
|
+
}
|
129
|
+
|
117
130
|
bool FileSystem::IsPathAbsolute(const string &path) {
|
118
131
|
// 1) A single backslash or forward-slash
|
119
|
-
if (
|
132
|
+
if (StartsWithSingleBackslash(path)) {
|
120
133
|
return true;
|
121
134
|
}
|
122
135
|
// 2) A disk designator with a backslash (e.g., C:\ or C:/)
|
@@ -131,7 +144,7 @@ bool FileSystem::IsPathAbsolute(const string &path) {
|
|
131
144
|
string FileSystem::NormalizeAbsolutePath(const string &path) {
|
132
145
|
D_ASSERT(IsPathAbsolute(path));
|
133
146
|
auto result = StringUtil::Lower(FileSystem::ConvertSeparators(path));
|
134
|
-
if (
|
147
|
+
if (StartsWithSingleBackslash(result)) {
|
135
148
|
// Path starts with a single backslash or forward slash
|
136
149
|
// prepend drive letter
|
137
150
|
return GetWorkingDirectory().substr(0, 2) + result;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "0.8.1-
|
2
|
+
#define DUCKDB_VERSION "0.8.1-dev65"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "a81a31a0af"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -10,6 +10,8 @@
|
|
10
10
|
|
11
11
|
#include "duckdb/common/adbc/adbc.h"
|
12
12
|
|
13
|
+
#include <string>
|
14
|
+
|
13
15
|
namespace duckdb_adbc {
|
14
16
|
|
15
17
|
AdbcStatusCode DatabaseNew(struct AdbcDatabase *database, struct AdbcError *error);
|
@@ -82,4 +84,7 @@ AdbcStatusCode StatementExecutePartitions(struct AdbcStatement *statement, struc
|
|
82
84
|
struct AdbcPartitions *partitions, int64_t *rows_affected,
|
83
85
|
struct AdbcError *error);
|
84
86
|
|
87
|
+
void SetError(struct AdbcError *error, const std::string &message);
|
88
|
+
|
89
|
+
void InitiliazeADBCError(AdbcError *error);
|
85
90
|
} // namespace duckdb_adbc
|
@@ -42,6 +42,7 @@ void ExpressionHeuristics::ReorderExpressions(vector<unique_ptr<Expression>> &ex
|
|
42
42
|
};
|
43
43
|
|
44
44
|
vector<ExpressionCosts> expression_costs;
|
45
|
+
expression_costs.reserve(expressions.size());
|
45
46
|
// iterate expressions, get cost for each one
|
46
47
|
for (idx_t i = 0; i < expressions.size(); i++) {
|
47
48
|
idx_t cost = Cost(*expressions[i]);
|
@@ -27,9 +27,7 @@ Index::Index(AttachedDatabase &db, IndexType type, TableIOManager &table_io_mana
|
|
27
27
|
}
|
28
28
|
|
29
29
|
// create the column id set
|
30
|
-
|
31
|
-
column_id_set.insert(column_id);
|
32
|
-
}
|
30
|
+
column_id_set.insert(column_ids.begin(), column_ids.end());
|
33
31
|
}
|
34
32
|
|
35
33
|
void Index::InitializeLock(IndexLock &state) {
|
@@ -29,6 +29,7 @@ LocalTableStorage::LocalTableStorage(DataTable &table)
|
|
29
29
|
if (art.constraint_type != IndexConstraintType::NONE) {
|
30
30
|
// unique index: create a local ART index that maintains the same unique constraint
|
31
31
|
vector<unique_ptr<Expression>> unbound_expressions;
|
32
|
+
unbound_expressions.reserve(art.unbound_expressions.size());
|
32
33
|
for (auto &expr : art.unbound_expressions) {
|
33
34
|
unbound_expressions.push_back(expr->Copy());
|
34
35
|
}
|
@@ -252,7 +253,7 @@ shared_ptr<LocalTableStorage> LocalTableManager::MoveEntry(DataTable &table) {
|
|
252
253
|
return nullptr;
|
253
254
|
}
|
254
255
|
auto storage_entry = std::move(entry->second);
|
255
|
-
table_storage.erase(
|
256
|
+
table_storage.erase(entry);
|
256
257
|
return storage_entry;
|
257
258
|
}
|
258
259
|
|
@@ -16,7 +16,7 @@ DataFileType MagicBytes::CheckMagicBytes(FileSystem *fs_p, const string &path) {
|
|
16
16
|
char buffer[MAGIC_BYTES_READ_SIZE];
|
17
17
|
|
18
18
|
handle->Read(buffer, MAGIC_BYTES_READ_SIZE);
|
19
|
-
if (memcmp(buffer, "SQLite format 3\0
|
19
|
+
if (memcmp(buffer, "SQLite format 3\0", 16) == 0) {
|
20
20
|
return DataFileType::SQLITE_FILE;
|
21
21
|
}
|
22
22
|
if (memcmp(buffer, "PAR1", 4) == 0) {
|