duckdb 0.8.1-dev152.0 → 0.8.1-dev180.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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.1-dev152.0",
5
+ "version": "0.8.1-dev180.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -5,10 +5,13 @@
5
5
  #include "duckdb/common/string_util.hpp"
6
6
 
7
7
  #include "duckdb.h"
8
- #include "duckdb/main/connection.hpp"
9
8
  #include "duckdb/common/arrow/arrow_wrapper.hpp"
10
9
  #include "duckdb/common/arrow/arrow.hpp"
11
10
 
11
+ #ifndef DUCKDB_AMALGAMATION
12
+ #include "duckdb/main/connection.hpp"
13
+ #endif
14
+
12
15
  #include <string.h>
13
16
  #include <stdlib.h>
14
17
 
@@ -37,6 +40,10 @@ duckdb_adbc::AdbcStatusCode duckdb_adbc_init(size_t count, struct duckdb_adbc::A
37
40
  driver->StatementSetOption = duckdb_adbc::StatementSetOption;
38
41
  driver->StatementSetSqlQuery = duckdb_adbc::StatementSetSqlQuery;
39
42
  driver->ConnectionGetObjects = duckdb_adbc::ConnectionGetObjects;
43
+ driver->ConnectionCommit = duckdb_adbc::ConnectionCommit;
44
+ driver->ConnectionRollback = duckdb_adbc::ConnectionRollback;
45
+ driver->ConnectionReadPartition = duckdb_adbc::ConnectionReadPartition;
46
+ driver->StatementExecutePartitions = duckdb_adbc::StatementExecutePartitions;
40
47
  return ADBC_STATUS_OK;
41
48
  }
42
49
 
@@ -162,10 +169,104 @@ AdbcStatusCode ConnectionNew(struct AdbcConnection *connection, struct AdbcError
162
169
  return ADBC_STATUS_OK;
163
170
  }
164
171
 
172
+ AdbcStatusCode ExecuteQuery(duckdb::Connection *conn, const char *query, struct AdbcError *error) {
173
+ auto res = conn->Query(query);
174
+ if (res->HasError()) {
175
+ auto error_message = "Failed to execute query \"" + std::string(query) + "\": " + res->GetError();
176
+ SetError(error, error_message);
177
+ return ADBC_STATUS_INTERNAL;
178
+ }
179
+ return ADBC_STATUS_OK;
180
+ }
181
+
165
182
  AdbcStatusCode ConnectionSetOption(struct AdbcConnection *connection, const char *key, const char *value,
166
183
  struct AdbcError *error) {
167
- // there are no connection-level options that need to be set before connecting
168
- return ADBC_STATUS_OK;
184
+ if (!connection) {
185
+ SetError(error, "Connection is not set");
186
+ return ADBC_STATUS_INVALID_ARGUMENT;
187
+ }
188
+ auto conn = (duckdb::Connection *)connection->private_data;
189
+ if (strcmp(key, ADBC_CONNECTION_OPTION_AUTOCOMMIT) == 0) {
190
+ if (strcmp(value, ADBC_OPTION_VALUE_ENABLED) == 0) {
191
+ if (conn->HasActiveTransaction()) {
192
+ AdbcStatusCode status = ExecuteQuery(conn, "COMMIT", error);
193
+ if (status != ADBC_STATUS_OK) {
194
+ return status;
195
+ }
196
+ } else {
197
+ // no-op
198
+ }
199
+ } else if (strcmp(value, ADBC_OPTION_VALUE_DISABLED) == 0) {
200
+ if (conn->HasActiveTransaction()) {
201
+ // no-op
202
+ } else {
203
+ // begin
204
+ AdbcStatusCode status = ExecuteQuery(conn, "START TRANSACTION", error);
205
+ if (status != ADBC_STATUS_OK) {
206
+ return status;
207
+ }
208
+ }
209
+ } else {
210
+ auto error_message = "Invalid connection option value " + std::string(key) + "=" + std::string(value);
211
+ SetError(error, error_message);
212
+ return ADBC_STATUS_INVALID_ARGUMENT;
213
+ }
214
+ return ADBC_STATUS_OK;
215
+ }
216
+ auto error_message =
217
+ "Unknown connection option " + std::string(key) + "=" + (value ? std::string(value) : "(NULL)");
218
+ SetError(error, error_message);
219
+ return ADBC_STATUS_NOT_IMPLEMENTED;
220
+ }
221
+
222
+ AdbcStatusCode ConnectionReadPartition(struct AdbcConnection *connection, const uint8_t *serialized_partition,
223
+ size_t serialized_length, struct ArrowArrayStream *out,
224
+ struct AdbcError *error) {
225
+ SetError(error, "Read Partitions are not supported in DuckDB");
226
+ return ADBC_STATUS_NOT_IMPLEMENTED;
227
+ }
228
+
229
+ AdbcStatusCode StatementExecutePartitions(struct AdbcStatement *statement, struct ArrowSchema *schema,
230
+ struct AdbcPartitions *partitions, int64_t *rows_affected,
231
+ struct AdbcError *error) {
232
+ SetError(error, "Execute Partitions are not supported in DuckDB");
233
+ return ADBC_STATUS_NOT_IMPLEMENTED;
234
+ }
235
+
236
+ AdbcStatusCode ConnectionCommit(struct AdbcConnection *connection, struct AdbcError *error) {
237
+ if (!connection) {
238
+ SetError(error, "Connection is not set");
239
+ return ADBC_STATUS_INVALID_ARGUMENT;
240
+ }
241
+ auto conn = (duckdb::Connection *)connection->private_data;
242
+ if (!conn->HasActiveTransaction()) {
243
+ SetError(error, "No active transaction, cannot commit");
244
+ return ADBC_STATUS_INVALID_STATE;
245
+ }
246
+
247
+ AdbcStatusCode status = ExecuteQuery(conn, "COMMIT", error);
248
+ if (status != ADBC_STATUS_OK) {
249
+ return status;
250
+ }
251
+ return ExecuteQuery(conn, "START TRANSACTION", error);
252
+ }
253
+
254
+ AdbcStatusCode ConnectionRollback(struct AdbcConnection *connection, struct AdbcError *error) {
255
+ if (!connection) {
256
+ SetError(error, "Connection is not set");
257
+ return ADBC_STATUS_INVALID_ARGUMENT;
258
+ }
259
+ auto conn = (duckdb::Connection *)connection->private_data;
260
+ if (!conn->HasActiveTransaction()) {
261
+ SetError(error, "No active transaction, cannot rollback");
262
+ return ADBC_STATUS_INVALID_STATE;
263
+ }
264
+
265
+ AdbcStatusCode status = ExecuteQuery(conn, "ROLLBACK", error);
266
+ if (status != ADBC_STATUS_OK) {
267
+ return status;
268
+ }
269
+ return ExecuteQuery(conn, "START TRANSACTION", error);
169
270
  }
170
271
 
171
272
  AdbcStatusCode ConnectionInit(struct AdbcConnection *connection, struct AdbcDatabase *database,
@@ -219,11 +320,11 @@ void release(struct ArrowArrayStream *stream) {
219
320
  if (!stream || !stream->release) {
220
321
  return;
221
322
  }
222
- stream->release = nullptr;
223
323
  if (stream->private_data) {
224
324
  duckdb_destroy_arrow((duckdb_arrow *)&stream->private_data);
225
325
  stream->private_data = nullptr;
226
326
  }
327
+ stream->release = nullptr;
227
328
  }
228
329
 
229
330
  const char *get_last_error(struct ArrowArrayStream *stream) {
@@ -270,16 +371,21 @@ AdbcStatusCode Ingest(duckdb_connection connection, const char *table_name, stru
270
371
  if (status != ADBC_STATUS_OK) {
271
372
  return status;
272
373
  }
374
+ auto cconn = (duckdb::Connection *)connection;
273
375
 
376
+ auto has_table = cconn->TableInfo(table_name);
377
+ auto arrow_scan = cconn->TableFunction("arrow_scan", {duckdb::Value::POINTER((uintptr_t)input),
378
+ duckdb::Value::POINTER((uintptr_t)stream_produce),
379
+ duckdb::Value::POINTER((uintptr_t)get_schema)});
274
380
  try {
275
- // TODO evil cast, do we need a way to do this from the C api?
276
- auto cconn = (duckdb::Connection *)connection;
277
- cconn
278
- ->TableFunction("arrow_scan",
279
- {duckdb::Value::POINTER((uintptr_t)input),
280
- duckdb::Value::POINTER((uintptr_t)stream_produce),
281
- duckdb::Value::POINTER((uintptr_t)get_schema)}) // TODO make this a parameter somewhere
282
- ->Create(table_name); // TODO this should probably be a temp table
381
+ if (!has_table) {
382
+ // We create the table based on an Arrow Scanner
383
+ arrow_scan->Create(table_name);
384
+ } else {
385
+ arrow_scan->CreateView("temp_adbc_view", true, true);
386
+ auto query = "insert into " + std::string(table_name) + " select * from temp_adbc_view";
387
+ auto result = cconn->Query(query);
388
+ }
283
389
  // After creating a table, the arrow array stream is released. Hence we must set it as released to avoid
284
390
  // double-releasing it
285
391
  input->release = nullptr;
@@ -133,10 +133,6 @@ static AdbcStatusCode ReleaseDriver(struct AdbcDriver *driver, struct AdbcError
133
133
 
134
134
  // Default stubs
135
135
 
136
- AdbcStatusCode ConnectionCommit(struct AdbcConnection *, struct AdbcError *error) {
137
- return ADBC_STATUS_NOT_IMPLEMENTED;
138
- }
139
-
140
136
  AdbcStatusCode ConnectionGetInfo(struct AdbcConnection *connection, uint32_t *info_codes, size_t info_codes_length,
141
137
  struct ArrowArrayStream *out, struct AdbcError *error) {
142
138
  return ADBC_STATUS_NOT_IMPLEMENTED;
@@ -147,27 +143,11 @@ AdbcStatusCode ConnectionGetTableSchema(struct AdbcConnection *, const char *, c
147
143
  return ADBC_STATUS_NOT_IMPLEMENTED;
148
144
  }
149
145
 
150
- AdbcStatusCode ConnectionReadPartition(struct AdbcConnection *connection, const uint8_t *serialized_partition,
151
- size_t serialized_length, struct ArrowArrayStream *out,
152
- struct AdbcError *error) {
153
- return ADBC_STATUS_NOT_IMPLEMENTED;
154
- }
155
-
156
- AdbcStatusCode ConnectionRollback(struct AdbcConnection *, struct AdbcError *error) {
157
- return ADBC_STATUS_NOT_IMPLEMENTED;
158
- }
159
-
160
146
  AdbcStatusCode StatementBind(struct AdbcStatement *, struct ArrowArray *, struct ArrowSchema *,
161
147
  struct AdbcError *error) {
162
148
  return ADBC_STATUS_NOT_IMPLEMENTED;
163
149
  }
164
150
 
165
- AdbcStatusCode StatementExecutePartitions(struct AdbcStatement *statement, struct ArrowSchema *schema,
166
- struct AdbcPartitions *partitions, int64_t *rows_affected,
167
- struct AdbcError *error) {
168
- return ADBC_STATUS_NOT_IMPLEMENTED;
169
- }
170
-
171
151
  AdbcStatusCode StatementGetParameterSchema(struct AdbcStatement *statement, struct ArrowSchema *schema,
172
152
  struct AdbcError *error) {
173
153
  return ADBC_STATUS_NOT_IMPLEMENTED;
@@ -206,8 +206,8 @@ unique_ptr<FunctionData> ArrowTableFunction::ArrowScanBind(ClientContext &contex
206
206
  throw InvalidInputException("arrow_scan: released schema passed");
207
207
  }
208
208
  if (schema.dictionary) {
209
- res->arrow_convert_data[col_idx] =
210
- make_uniq<ArrowConvertData>(GetArrowLogicalType(schema, res->arrow_convert_data, col_idx));
209
+ auto logical_type = GetArrowLogicalType(schema, res->arrow_convert_data, col_idx);
210
+ res->arrow_convert_data[col_idx] = make_uniq<ArrowConvertData>(std::move(logical_type));
211
211
  return_types.emplace_back(GetArrowLogicalType(*schema.dictionary, res->arrow_convert_data, col_idx));
212
212
  } else {
213
213
  return_types.emplace_back(GetArrowLogicalType(schema, res->arrow_convert_data, col_idx));
@@ -378,8 +378,8 @@ private:
378
378
  //! Current File Number
379
379
  idx_t file_number = 0;
380
380
  idx_t max_tuple_end = 0;
381
- //! the vector stores positions where threads ended the last line they read in the CSV File, and the set stores
382
- //! positions where they started reading the first line.
381
+ //! The vector stores positions where threads ended the last line they read in the CSV File, and the set stores
382
+ //! Positions where they started reading the first line.
383
383
  vector<vector<idx_t>> tuple_end;
384
384
  vector<set<idx_t>> tuple_start;
385
385
  //! Tuple end to batch
@@ -559,15 +559,13 @@ bool ParallelCSVGlobalState::Next(ClientContext &context, const ReadCSVData &bin
559
559
  }
560
560
  void ParallelCSVGlobalState::UpdateVerification(VerificationPositions positions, idx_t file_number_p, idx_t batch_idx) {
561
561
  lock_guard<mutex> parallel_lock(main_mutex);
562
- if (positions.beginning_of_first_line < positions.end_of_last_line) {
563
- if (positions.end_of_last_line > max_tuple_end) {
564
- max_tuple_end = positions.end_of_last_line;
565
- }
566
- tuple_end_to_batch[file_number_p][positions.end_of_last_line] = batch_idx;
567
- batch_to_tuple_end[file_number_p][batch_idx] = tuple_end[file_number_p].size();
568
- tuple_start[file_number_p].insert(positions.beginning_of_first_line);
569
- tuple_end[file_number_p].push_back(positions.end_of_last_line);
562
+ if (positions.end_of_last_line > max_tuple_end) {
563
+ max_tuple_end = positions.end_of_last_line;
570
564
  }
565
+ tuple_end_to_batch[file_number_p][positions.end_of_last_line] = batch_idx;
566
+ batch_to_tuple_end[file_number_p][batch_idx] = tuple_end[file_number_p].size();
567
+ tuple_start[file_number_p].insert(positions.beginning_of_first_line);
568
+ tuple_end[file_number_p].push_back(positions.end_of_last_line);
571
569
  }
572
570
 
573
571
  void ParallelCSVGlobalState::UpdateLinesRead(CSVBufferRead &buffer_read, idx_t file_idx) {
@@ -690,17 +688,14 @@ static void ParallelReadCSVFunction(ClientContext &context, TableFunctionInput &
690
688
  }
691
689
  if (csv_local_state.csv_reader->finished) {
692
690
  auto verification_updates = csv_local_state.csv_reader->GetVerificationPositions();
693
- if (verification_updates.beginning_of_first_line != verification_updates.end_of_last_line) {
694
- csv_global_state.UpdateVerification(verification_updates,
695
- csv_local_state.csv_reader->buffer->buffer->GetFileNumber(),
696
- csv_local_state.csv_reader->buffer->local_batch_index);
697
- }
691
+ csv_global_state.UpdateVerification(verification_updates,
692
+ csv_local_state.csv_reader->buffer->buffer->GetFileNumber(),
693
+ csv_local_state.csv_reader->buffer->local_batch_index);
698
694
  csv_global_state.UpdateLinesRead(*csv_local_state.csv_reader->buffer, csv_local_state.csv_reader->file_idx);
699
695
  auto has_next = csv_global_state.Next(context, bind_data, csv_local_state.csv_reader);
700
696
  if (csv_local_state.csv_reader) {
701
697
  csv_local_state.csv_reader->linenr = 0;
702
698
  }
703
-
704
699
  if (!has_next) {
705
700
  csv_global_state.DecrementThread();
706
701
  break;
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.1-dev152"
2
+ #define DUCKDB_VERSION "0.8.1-dev180"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "d636ce2d59"
5
+ #define DUCKDB_SOURCE_ID "e9f6ba553a"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -25,8 +25,10 @@ public:
25
25
  bool serialize = function.serialize;
26
26
  writer.WriteField(serialize);
27
27
  if (serialize) {
28
- D_ASSERT(function.deserialize);
29
28
  function.serialize(writer, bind_info, function);
29
+ // First check if serialize throws a NotImplementedException, in which case it doesn't require a deserialize
30
+ // function
31
+ D_ASSERT(function.deserialize);
30
32
  }
31
33
  }
32
34