duckdb 0.6.1-dev131.0 → 0.6.1-dev140.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/connection.cpp +100 -99
- package/src/duckdb.cpp +64 -1
- package/src/duckdb.hpp +2 -2
- package/src/duckdb_node.hpp +0 -1
- package/src/parquet-amalgamation.cpp +37740 -37740
- package/test/arrow.test.js +36 -45
package/package.json
CHANGED
package/src/connection.cpp
CHANGED
|
@@ -63,41 +63,6 @@ struct NodeReplacementScanData : duckdb::ReplacementScanData {
|
|
|
63
63
|
Connection *connection_ref;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
static duckdb::unique_ptr<duckdb::TableFunctionRef>
|
|
67
|
-
ScanReplacement(duckdb::ClientContext &context, const std::string &table_name, duckdb::ReplacementScanData *data) {
|
|
68
|
-
auto &buffers = ((NodeReplacementScanData *)data)->connection_ref->buffers;
|
|
69
|
-
// Lookup buffer
|
|
70
|
-
auto lookup = buffers.find(table_name);
|
|
71
|
-
if (lookup == buffers.end()) {
|
|
72
|
-
return nullptr;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Create table scan on ipc buffers
|
|
76
|
-
auto name = lookup->first;
|
|
77
|
-
auto ipc_buffer_array = lookup->second;
|
|
78
|
-
|
|
79
|
-
auto table_function = duckdb::make_unique<duckdb::TableFunctionRef>();
|
|
80
|
-
std::vector<duckdb::unique_ptr<duckdb::ParsedExpression>> table_fun_children;
|
|
81
|
-
|
|
82
|
-
duckdb::vector<duckdb::Value> list_children;
|
|
83
|
-
|
|
84
|
-
for (uint64_t ipc_idx = 0; ipc_idx < ipc_buffer_array.size(); ipc_idx++) {
|
|
85
|
-
auto &v = ipc_buffer_array[ipc_idx];
|
|
86
|
-
duckdb::child_list_t<duckdb::Value> struct_children;
|
|
87
|
-
struct_children.push_back(make_pair("ptr", duckdb::Value::UBIGINT(v.first)));
|
|
88
|
-
struct_children.push_back(make_pair("size", duckdb::Value::UBIGINT(v.second)));
|
|
89
|
-
|
|
90
|
-
// Push struct into table fun
|
|
91
|
-
list_children.push_back(duckdb::Value::STRUCT(move(struct_children)));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
table_fun_children.push_back(
|
|
95
|
-
duckdb::make_unique<duckdb::ConstantExpression>(duckdb::Value::LIST(move(list_children))));
|
|
96
|
-
table_function->function =
|
|
97
|
-
duckdb::make_unique<duckdb::FunctionExpression>("scan_arrow_ipc", move(table_fun_children));
|
|
98
|
-
return table_function;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
66
|
Connection::Connection(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Connection>(info) {
|
|
102
67
|
Napi::Env env = info.Env();
|
|
103
68
|
int length = info.Length();
|
|
@@ -339,70 +304,6 @@ Napi::Value Connection::RegisterUdf(const Napi::CallbackInfo &info) {
|
|
|
339
304
|
return Value();
|
|
340
305
|
}
|
|
341
306
|
|
|
342
|
-
// Register Arrow IPC buffers for scanning from DuckDB
|
|
343
|
-
Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
|
|
344
|
-
auto env = info.Env();
|
|
345
|
-
|
|
346
|
-
Napi::TypeError::New(env, "Register buffer currently not implemented").ThrowAsJavaScriptException();
|
|
347
|
-
return env.Null();
|
|
348
|
-
|
|
349
|
-
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsObject()) {
|
|
350
|
-
Napi::TypeError::New(env, "Incorrect params").ThrowAsJavaScriptException();
|
|
351
|
-
return env.Null();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
std::string name = info[0].As<Napi::String>();
|
|
355
|
-
Napi::Array array = info[1].As<Napi::Array>();
|
|
356
|
-
bool force_register = false;
|
|
357
|
-
|
|
358
|
-
if (info.Length() > 2) {
|
|
359
|
-
if (!info[2].IsBoolean()) {
|
|
360
|
-
Napi::TypeError::New(env, "Incorrect params").ThrowAsJavaScriptException();
|
|
361
|
-
return env.Null();
|
|
362
|
-
}
|
|
363
|
-
force_register = info[2].As<Napi::Boolean>().Value();
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
array_references[name] = Napi::Persistent(array);
|
|
367
|
-
|
|
368
|
-
if (!force_register && buffers.find(name) != buffers.end()) {
|
|
369
|
-
Napi::TypeError::New(env, "Buffer with this name already exists").ThrowAsJavaScriptException();
|
|
370
|
-
return env.Null();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
buffers[name] = std::vector<std::pair<uint64_t, uint64_t>>();
|
|
374
|
-
|
|
375
|
-
for (uint64_t ipc_idx = 0; ipc_idx < array.Length(); ipc_idx++) {
|
|
376
|
-
Napi::Value v = array[ipc_idx];
|
|
377
|
-
if (!v.IsObject()) {
|
|
378
|
-
Napi::TypeError::New(env, "Incorrect params").ThrowAsJavaScriptException();
|
|
379
|
-
return env.Null();
|
|
380
|
-
}
|
|
381
|
-
Napi::Uint8Array arr = v.As<Napi::Uint8Array>();
|
|
382
|
-
auto raw_ptr = reinterpret_cast<uint64_t>(arr.ArrayBuffer().Data());
|
|
383
|
-
auto length = (uint64_t)arr.ElementLength();
|
|
384
|
-
|
|
385
|
-
buffers[name].push_back(std::pair<uint64_t, uint64_t>({raw_ptr, length}));
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
return Value();
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
Napi::Value Connection::UnRegisterBuffer(const Napi::CallbackInfo &info) {
|
|
392
|
-
auto env = info.Env();
|
|
393
|
-
|
|
394
|
-
Napi::TypeError::New(env, "Register buffer currently not implemented").ThrowAsJavaScriptException();
|
|
395
|
-
return env.Null();
|
|
396
|
-
|
|
397
|
-
if (info.Length() != 1 || !info[0].IsString()) {
|
|
398
|
-
Napi::TypeError::New(env, "Holding it wrong").ThrowAsJavaScriptException();
|
|
399
|
-
return env.Null();
|
|
400
|
-
}
|
|
401
|
-
std::string name = info[0].As<Napi::String>();
|
|
402
|
-
buffers.erase(name);
|
|
403
|
-
return Value();
|
|
404
|
-
}
|
|
405
|
-
|
|
406
307
|
struct UnregisterUdfTask : public Task {
|
|
407
308
|
UnregisterUdfTask(Connection &connection, std::string name, Napi::Function callback)
|
|
408
309
|
: Task(connection, callback), name(std::move(name)) {
|
|
@@ -487,6 +388,20 @@ struct ExecTask : public Task {
|
|
|
487
388
|
duckdb::PreservedError error;
|
|
488
389
|
};
|
|
489
390
|
|
|
391
|
+
struct ExecTaskWithCallback : public ExecTask {
|
|
392
|
+
ExecTaskWithCallback(Connection &connection, std::string sql, Napi::Function js_callback,
|
|
393
|
+
std::function<void(void)> cpp_callback)
|
|
394
|
+
: ExecTask(connection, sql, js_callback), cpp_callback(cpp_callback) {
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
void Callback() override {
|
|
398
|
+
cpp_callback();
|
|
399
|
+
ExecTask::Callback();
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
std::function<void(void)> cpp_callback;
|
|
403
|
+
};
|
|
404
|
+
|
|
490
405
|
Napi::Value Connection::Exec(const Napi::CallbackInfo &info) {
|
|
491
406
|
auto env = info.Env();
|
|
492
407
|
|
|
@@ -506,4 +421,90 @@ Napi::Value Connection::Exec(const Napi::CallbackInfo &info) {
|
|
|
506
421
|
return Value();
|
|
507
422
|
}
|
|
508
423
|
|
|
424
|
+
// Register Arrow IPC buffers for scanning from DuckDB
|
|
425
|
+
Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
|
|
426
|
+
auto env = info.Env();
|
|
427
|
+
|
|
428
|
+
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsObject()) {
|
|
429
|
+
Napi::TypeError::New(env, "Incorrect params").ThrowAsJavaScriptException();
|
|
430
|
+
return env.Null();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
std::string name = info[0].As<Napi::String>();
|
|
434
|
+
Napi::Array array = info[1].As<Napi::Array>();
|
|
435
|
+
bool force_register = false;
|
|
436
|
+
|
|
437
|
+
if (info.Length() > 2) {
|
|
438
|
+
if (!info[2].IsBoolean()) {
|
|
439
|
+
Napi::TypeError::New(env, "Parameter 3 is of unexpected type. Expected boolean")
|
|
440
|
+
.ThrowAsJavaScriptException();
|
|
441
|
+
return env.Null();
|
|
442
|
+
}
|
|
443
|
+
force_register = info[2].As<Napi::Boolean>().Value();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (!force_register && array_references.find(name) != array_references.end()) {
|
|
447
|
+
Napi::TypeError::New(env, "Buffer with this name already exists and force_register is not enabled")
|
|
448
|
+
.ThrowAsJavaScriptException();
|
|
449
|
+
return env.Null();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
array_references[name] = Napi::Persistent(array);
|
|
453
|
+
|
|
454
|
+
std::string arrow_scan_function = "scan_arrow_ipc([";
|
|
455
|
+
|
|
456
|
+
for (uint64_t ipc_idx = 0; ipc_idx < array.Length(); ipc_idx++) {
|
|
457
|
+
Napi::Value v = array[ipc_idx];
|
|
458
|
+
if (!v.IsObject()) {
|
|
459
|
+
Napi::TypeError::New(env, "Parameter 2 contains unexpected type at index " + std::to_string(ipc_idx))
|
|
460
|
+
.ThrowAsJavaScriptException();
|
|
461
|
+
return env.Null();
|
|
462
|
+
}
|
|
463
|
+
Napi::Uint8Array arr = v.As<Napi::Uint8Array>();
|
|
464
|
+
auto raw_ptr = reinterpret_cast<uint64_t>(arr.ArrayBuffer().Data());
|
|
465
|
+
auto length = (uint64_t)arr.ElementLength();
|
|
466
|
+
|
|
467
|
+
arrow_scan_function += "{'ptr': " + std::to_string(raw_ptr) + ", 'size': " + std::to_string(length) + "},";
|
|
468
|
+
}
|
|
469
|
+
arrow_scan_function += "])";
|
|
470
|
+
|
|
471
|
+
std::string final_query = "CREATE OR REPLACE TEMPORARY VIEW " + name + " AS SELECT * FROM " + arrow_scan_function;
|
|
472
|
+
|
|
473
|
+
Napi::Function callback;
|
|
474
|
+
if (info.Length() > 3 && info[3].IsFunction()) {
|
|
475
|
+
callback = info[3].As<Napi::Function>();
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
database_ref->Schedule(info.Env(), duckdb::make_unique<ExecTask>(*this, final_query, callback));
|
|
479
|
+
|
|
480
|
+
return Value();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
Napi::Value Connection::UnRegisterBuffer(const Napi::CallbackInfo &info) {
|
|
484
|
+
auto env = info.Env();
|
|
485
|
+
|
|
486
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
487
|
+
Napi::TypeError::New(env, "Incorrect params").ThrowAsJavaScriptException();
|
|
488
|
+
return env.Null();
|
|
489
|
+
}
|
|
490
|
+
std::string name = info[0].As<Napi::String>();
|
|
491
|
+
|
|
492
|
+
std::string final_query = "DROP VIEW IF EXISTS " + name;
|
|
493
|
+
|
|
494
|
+
Napi::Function callback;
|
|
495
|
+
if (info.Length() > 1 && info[1].IsFunction()) {
|
|
496
|
+
callback = info[1].As<Napi::Function>();
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// When query succeeds we can safely delete the ref
|
|
500
|
+
std::function<void(void)> cpp_callback = [&, name]() {
|
|
501
|
+
array_references.erase(name);
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
database_ref->Schedule(info.Env(),
|
|
505
|
+
duckdb::make_unique<ExecTaskWithCallback>(*this, final_query, callback, cpp_callback));
|
|
506
|
+
|
|
507
|
+
return Value();
|
|
508
|
+
}
|
|
509
|
+
|
|
509
510
|
} // namespace node_duckdb
|
package/src/duckdb.cpp
CHANGED
|
@@ -193749,6 +193749,33 @@ unique_ptr<BoundTableRef> Binder::Bind(SubqueryRef &ref, CommonTableExpressionIn
|
|
|
193749
193749
|
|
|
193750
193750
|
|
|
193751
193751
|
|
|
193752
|
+
//===----------------------------------------------------------------------===//
|
|
193753
|
+
// DuckDB
|
|
193754
|
+
//
|
|
193755
|
+
// duckdb/planner/expression_binder/table_function_binder.hpp
|
|
193756
|
+
//
|
|
193757
|
+
//
|
|
193758
|
+
//===----------------------------------------------------------------------===//
|
|
193759
|
+
|
|
193760
|
+
|
|
193761
|
+
|
|
193762
|
+
|
|
193763
|
+
|
|
193764
|
+
namespace duckdb {
|
|
193765
|
+
|
|
193766
|
+
//! The Table function binder can bind standard table function parameters (i.e. non-table-in-out functions)
|
|
193767
|
+
class TableFunctionBinder : public ExpressionBinder {
|
|
193768
|
+
public:
|
|
193769
|
+
TableFunctionBinder(Binder &binder, ClientContext &context);
|
|
193770
|
+
|
|
193771
|
+
protected:
|
|
193772
|
+
BindResult BindColumnReference(ColumnRefExpression &expr);
|
|
193773
|
+
BindResult BindExpression(unique_ptr<ParsedExpression> *expr, idx_t depth, bool root_expression = false) override;
|
|
193774
|
+
|
|
193775
|
+
string UnsupportedAggregateMessage() override;
|
|
193776
|
+
};
|
|
193777
|
+
|
|
193778
|
+
} // namespace duckdb
|
|
193752
193779
|
|
|
193753
193780
|
|
|
193754
193781
|
|
|
@@ -193825,7 +193852,7 @@ bool Binder::BindTableFunctionParameters(TableFunctionCatalogEntry &table_functi
|
|
|
193825
193852
|
continue;
|
|
193826
193853
|
}
|
|
193827
193854
|
|
|
193828
|
-
|
|
193855
|
+
TableFunctionBinder binder(*this, context);
|
|
193829
193856
|
LogicalType sql_type;
|
|
193830
193857
|
auto expr = binder.Bind(child, &sql_type);
|
|
193831
193858
|
if (expr->HasParameter()) {
|
|
@@ -197291,6 +197318,42 @@ BindResult SelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t gr
|
|
|
197291
197318
|
} // namespace duckdb
|
|
197292
197319
|
|
|
197293
197320
|
|
|
197321
|
+
|
|
197322
|
+
|
|
197323
|
+
namespace duckdb {
|
|
197324
|
+
|
|
197325
|
+
TableFunctionBinder::TableFunctionBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
|
|
197326
|
+
}
|
|
197327
|
+
|
|
197328
|
+
BindResult TableFunctionBinder::BindColumnReference(ColumnRefExpression &expr) {
|
|
197329
|
+
auto result_name = StringUtil::Join(expr.column_names, ".");
|
|
197330
|
+
return BindResult(make_unique<BoundConstantExpression>(Value(result_name)));
|
|
197331
|
+
}
|
|
197332
|
+
|
|
197333
|
+
BindResult TableFunctionBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
197334
|
+
bool root_expression) {
|
|
197335
|
+
auto &expr = **expr_ptr;
|
|
197336
|
+
switch (expr.GetExpressionClass()) {
|
|
197337
|
+
case ExpressionClass::COLUMN_REF:
|
|
197338
|
+
return BindColumnReference((ColumnRefExpression &)expr);
|
|
197339
|
+
case ExpressionClass::SUBQUERY:
|
|
197340
|
+
throw BinderException("Table function cannot contain subqueries");
|
|
197341
|
+
case ExpressionClass::DEFAULT:
|
|
197342
|
+
return BindResult("Table function cannot contain DEFAULT clause");
|
|
197343
|
+
case ExpressionClass::WINDOW:
|
|
197344
|
+
return BindResult("Table function cannot contain window functions!");
|
|
197345
|
+
default:
|
|
197346
|
+
return ExpressionBinder::BindExpression(expr_ptr, depth);
|
|
197347
|
+
}
|
|
197348
|
+
}
|
|
197349
|
+
|
|
197350
|
+
string TableFunctionBinder::UnsupportedAggregateMessage() {
|
|
197351
|
+
return "Table function cannot contain aggregates!";
|
|
197352
|
+
}
|
|
197353
|
+
|
|
197354
|
+
} // namespace duckdb
|
|
197355
|
+
|
|
197356
|
+
|
|
197294
197357
|
namespace duckdb {
|
|
197295
197358
|
|
|
197296
197359
|
UpdateBinder::UpdateBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.6.1-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "dd5dcd5722"
|
|
15
|
+
#define DUCKDB_VERSION "v0.6.1-dev140"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
package/src/duckdb_node.hpp
CHANGED
|
@@ -133,7 +133,6 @@ public:
|
|
|
133
133
|
std::unique_ptr<duckdb::Connection> connection;
|
|
134
134
|
Database *database_ref;
|
|
135
135
|
std::unordered_map<std::string, duckdb_node_udf_function_t> udfs;
|
|
136
|
-
std::unordered_map<std::string, std::vector<std::pair<uint64_t, uint64_t>>> buffers;
|
|
137
136
|
std::unordered_map<std::string, Napi::Reference<Napi::Array>> array_references;
|
|
138
137
|
};
|
|
139
138
|
|