44#include " duckdb/parser/parser.hpp"
55#include " duckdb/parser/parsed_data/drop_info.hpp"
66#include " duckdb/parser/expression/cast_expression.hpp"
7+ #include " duckdb/common/types/value.hpp"
8+ #include " duckdb/main/relation/table_function_relation.hpp"
9+
10+
711#include < iostream>
812#include < thread>
913
@@ -451,6 +455,27 @@ Napi::Value Connection::Exec(const Napi::CallbackInfo &info) {
451455 return Value ();
452456}
453457
458+ struct CreateArrowViewTask : public Task {
459+ CreateArrowViewTask (Connection &connection, duckdb::vector<duckdb::Value>& parameters, std::string &view_name)
460+ : Task(connection), parameters(parameters), view_name(view_name) {
461+ }
462+
463+ void DoWork () override {
464+ auto &connection = Get<Connection>();
465+ auto &con = *connection.connection ;
466+ // Now we create a table function relation
467+ auto table_function_relation = duckdb::make_shared_ptr<duckdb::TableFunctionRelation>(con.context ," scan_arrow_ipc" ,parameters);
468+ // Creates a relation for a temporary view that does replace
469+ auto view_relation = table_function_relation->CreateView (view_name,true ,true );
470+
471+ view_relation->Execute ();
472+
473+ }
474+
475+ duckdb::vector<duckdb::Value> parameters;
476+ std::string view_name;
477+ };
478+
454479// Register Arrow IPC buffers for scanning from DuckDB
455480Napi::Value Connection::RegisterBuffer (const Napi::CallbackInfo &info) {
456481 auto env = info.Env ();
@@ -475,9 +500,10 @@ Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
475500 }
476501
477502 array_references[name] = Napi::Persistent (array);
503+ auto &db = *connection->context ->db ;
478504
479- std::string arrow_scan_function = " scan_arrow_ipc([ " ;
480-
505+ vector<duckdb::Value> values ;
506+
481507 for (uint64_t ipc_idx = 0 ; ipc_idx < array.Length (); ipc_idx++) {
482508 Napi::Value v = array[ipc_idx];
483509 if (!v.IsObject ()) {
@@ -486,19 +512,20 @@ Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
486512 Napi::Uint8Array arr = v.As <Napi::Uint8Array>();
487513 auto raw_ptr = reinterpret_cast <uint64_t >(arr.ArrayBuffer ().Data ());
488514 auto length = (uint64_t )arr.ElementLength ();
489-
490- arrow_scan_function += " {'ptr': " + std::to_string (raw_ptr) + " ::UBIGINT, 'size': " + std::to_string (length) + " ::UBIGINT}," ;
491- }
492- arrow_scan_function += " ])" ;
493-
494- std::string final_query = " CREATE OR REPLACE TEMPORARY VIEW " + name + " AS SELECT * FROM " + arrow_scan_function;
495-
496- Napi::Function callback;
497- if (info.Length () > 3 && info[3 ].IsFunction ()) {
498- callback = info[3 ].As <Napi::Function>();
499- }
500-
501- database_ref->Schedule (info.Env (), duckdb::make_uniq<ExecTask>(*this , final_query, callback));
515+ duckdb::child_list_t <duckdb::Value> buffer_values;
516+ // This is a little bit evil, but allows us to support both libraries in between 1.2 and 1.3
517+ if (db.ExtensionIsLoaded (" nanoarrow" )){
518+ buffer_values.push_back ({" ptr" , duckdb::Value::POINTER (raw_ptr)});
519+ } else {
520+ buffer_values.push_back ({" ptr" , duckdb::Value::UBIGINT (raw_ptr)});
521+ }
522+ buffer_values.push_back ({" size" , duckdb::Value::UBIGINT (length)});
523+ values.push_back (duckdb::Value::STRUCT (buffer_values));
524+ }
525+ duckdb::vector<duckdb::Value> list_value;
526+ list_value.push_back (duckdb::Value::LIST (values));
527+
528+ database_ref->Schedule (info.Env (), duckdb::make_uniq<CreateArrowViewTask>(*this , list_value, name));
502529
503530 return Value ();
504531}
0 commit comments