duckdb 0.3.3-dev849.0 → 0.3.3-dev901.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.
@@ -1,6 +1,8 @@
1
+ var os = require('os');
1
2
  var binary = require('@mapbox/node-pre-gyp');
2
3
  var path = require('path');
3
4
  var binding_path = binary.find(path.resolve(path.join(__dirname,'../package.json')));
4
- var binding = require(binding_path);
5
5
 
6
- module.exports = exports = binding;
6
+ // // dlopen is used because we need to specify the RTLD_GLOBAL flag to be able to resolve duckdb symbols
7
+ // on linux where RTLD_LOCAL is the default.
8
+ process.dlopen(module, binding_path, os.constants.dlopen.RTLD_NOW | os.constants.dlopen.RTLD_GLOBAL)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.3.3-dev849.0",
4
+ "version": "0.3.3-dev901.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -62217,7 +62217,7 @@ namespace duckdb {
62217
62217
  class PhysicalInsert : public PhysicalOperator {
62218
62218
  public:
62219
62219
  PhysicalInsert(vector<LogicalType> types, TableCatalogEntry *table, vector<idx_t> column_index_map,
62220
- vector<unique_ptr<Expression>> bound_defaults, idx_t estimated_cardinality);
62220
+ vector<unique_ptr<Expression>> bound_defaults, idx_t estimated_cardinality, bool return_chunk);
62221
62221
 
62222
62222
  //! The map from insert column index to table column index
62223
62223
  vector<idx_t> column_index_map;
@@ -62225,6 +62225,8 @@ public:
62225
62225
  TableCatalogEntry *table;
62226
62226
  //! The default expressions of the columns for which no value is provided
62227
62227
  vector<unique_ptr<Expression>> bound_defaults;
62228
+ //! If the returning statement is present, return the whole chunk
62229
+ bool return_chunk;
62228
62230
 
62229
62231
  public:
62230
62232
  // Source interface
@@ -62266,11 +62268,13 @@ namespace duckdb {
62266
62268
  //===--------------------------------------------------------------------===//
62267
62269
  class InsertGlobalState : public GlobalSinkState {
62268
62270
  public:
62269
- InsertGlobalState() : insert_count(0) {
62271
+ InsertGlobalState() : insert_count(0), returned_chunk_count(0) {
62270
62272
  }
62271
62273
 
62272
62274
  mutex lock;
62273
62275
  idx_t insert_count;
62276
+ ChunkCollection return_chunk_collection;
62277
+ idx_t returned_chunk_count;
62274
62278
  };
62275
62279
 
62276
62280
  class InsertLocalState : public LocalSinkState {
@@ -62285,9 +62289,11 @@ public:
62285
62289
  };
62286
62290
 
62287
62291
  PhysicalInsert::PhysicalInsert(vector<LogicalType> types, TableCatalogEntry *table, vector<idx_t> column_index_map,
62288
- vector<unique_ptr<Expression>> bound_defaults, idx_t estimated_cardinality)
62292
+ vector<unique_ptr<Expression>> bound_defaults, idx_t estimated_cardinality,
62293
+ bool return_chunk)
62289
62294
  : PhysicalOperator(PhysicalOperatorType::INSERT, move(types), estimated_cardinality),
62290
- column_index_map(std::move(column_index_map)), table(table), bound_defaults(move(bound_defaults)) {
62295
+ column_index_map(std::move(column_index_map)), table(table), bound_defaults(move(bound_defaults)),
62296
+ return_chunk(return_chunk) {
62291
62297
  }
62292
62298
 
62293
62299
  SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
@@ -62300,6 +62306,7 @@ SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState &
62300
62306
 
62301
62307
  istate.insert_chunk.Reset();
62302
62308
  istate.insert_chunk.SetCardinality(chunk);
62309
+
62303
62310
  if (!column_index_map.empty()) {
62304
62311
  // columns specified by the user, use column_index_map
62305
62312
  for (idx_t i = 0; i < table->columns.size(); i++) {
@@ -62323,6 +62330,11 @@ SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState &
62323
62330
 
62324
62331
  lock_guard<mutex> glock(gstate.lock);
62325
62332
  table->storage->Append(*table, context.client, istate.insert_chunk);
62333
+
62334
+ if (return_chunk) {
62335
+ gstate.return_chunk_collection.Append(istate.insert_chunk);
62336
+ }
62337
+
62326
62338
  gstate.insert_count += chunk.size();
62327
62339
  return SinkResultType::NEED_MORE_INPUT;
62328
62340
  }
@@ -62360,14 +62372,27 @@ unique_ptr<GlobalSourceState> PhysicalInsert::GetGlobalSourceState(ClientContext
62360
62372
  void PhysicalInsert::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
62361
62373
  LocalSourceState &lstate) const {
62362
62374
  auto &state = (InsertSourceState &)gstate;
62363
- auto &g = (InsertGlobalState &)*sink_state;
62375
+ auto &insert_gstate = (InsertGlobalState &)*sink_state;
62364
62376
  if (state.finished) {
62365
62377
  return;
62366
62378
  }
62379
+ if (!return_chunk) {
62380
+ chunk.SetCardinality(1);
62381
+ chunk.SetValue(0, 0, Value::BIGINT(insert_gstate.insert_count));
62382
+ state.finished = true;
62383
+ }
62367
62384
 
62368
- chunk.SetCardinality(1);
62369
- chunk.SetValue(0, 0, Value::BIGINT(g.insert_count));
62370
- state.finished = true;
62385
+ idx_t chunk_return = insert_gstate.returned_chunk_count;
62386
+ if (chunk_return >= insert_gstate.return_chunk_collection.Chunks().size()) {
62387
+ return;
62388
+ }
62389
+
62390
+ chunk.Reference(insert_gstate.return_chunk_collection.GetChunk(chunk_return));
62391
+ chunk.SetCardinality((insert_gstate.return_chunk_collection.GetChunk(chunk_return)).size());
62392
+ insert_gstate.returned_chunk_count += 1;
62393
+ if (insert_gstate.returned_chunk_count >= insert_gstate.return_chunk_collection.Chunks().size()) {
62394
+ state.finished = true;
62395
+ }
62371
62396
  }
62372
62397
 
62373
62398
  } // namespace duckdb
@@ -67549,7 +67574,7 @@ namespace duckdb {
67549
67574
  class LogicalInsert : public LogicalOperator {
67550
67575
  public:
67551
67576
  explicit LogicalInsert(TableCatalogEntry *table)
67552
- : LogicalOperator(LogicalOperatorType::LOGICAL_INSERT), table(table) {
67577
+ : LogicalOperator(LogicalOperatorType::LOGICAL_INSERT), table(table), table_index(0), return_chunk(false) {
67553
67578
  }
67554
67579
 
67555
67580
  vector<vector<unique_ptr<Expression>>> insert_values;
@@ -67559,12 +67584,26 @@ public:
67559
67584
  vector<LogicalType> expected_types;
67560
67585
  //! The base table to insert into
67561
67586
  TableCatalogEntry *table;
67587
+ idx_t table_index;
67588
+ //! if returning option is used, return actual chunk to projection
67589
+ bool return_chunk;
67562
67590
  //! The default statements used by the table
67563
67591
  vector<unique_ptr<Expression>> bound_defaults;
67564
67592
 
67565
67593
  protected:
67594
+ vector<ColumnBinding> GetColumnBindings() override {
67595
+ if (return_chunk) {
67596
+ return GenerateColumnBindings(table_index, table->columns.size());
67597
+ }
67598
+ return {ColumnBinding(0, 0)};
67599
+ }
67600
+
67566
67601
  void ResolveTypes() override {
67567
- types.emplace_back(LogicalType::BIGINT);
67602
+ if (return_chunk) {
67603
+ types = table->GetTypes();
67604
+ } else {
67605
+ types.emplace_back(LogicalType::BIGINT);
67606
+ }
67568
67607
  }
67569
67608
  };
67570
67609
  } // namespace duckdb
@@ -67581,7 +67620,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalInsert &op
67581
67620
 
67582
67621
  dependencies.insert(op.table);
67583
67622
  auto insert = make_unique<PhysicalInsert>(op.types, op.table, op.column_index_map, move(op.bound_defaults),
67584
- op.estimated_cardinality);
67623
+ op.estimated_cardinality, op.return_chunk);
67585
67624
  if (plan) {
67586
67625
  insert->children.push_back(move(plan));
67587
67626
  }
@@ -104935,21 +104974,26 @@ public:
104935
104974
 
104936
104975
  void AddConnection(ClientContext &context) {
104937
104976
  lock_guard<mutex> lock(connections_lock);
104938
- connections.push_back(weak_ptr<ClientContext>(context.shared_from_this()));
104977
+ connections.insert(make_pair(&context, weak_ptr<ClientContext>(context.shared_from_this())));
104978
+ }
104979
+
104980
+ void RemoveConnection(ClientContext &context) {
104981
+ lock_guard<mutex> lock(connections_lock);
104982
+ connections.erase(&context);
104939
104983
  }
104940
104984
 
104941
104985
  vector<shared_ptr<ClientContext>> GetConnectionList() {
104942
104986
  vector<shared_ptr<ClientContext>> result;
104943
- for (size_t i = 0; i < connections.size(); i++) {
104944
- auto connection = connections[i].lock();
104987
+ for (auto &it : connections) {
104988
+ auto connection = it.second.lock();
104945
104989
  if (!connection) {
104946
- connections.erase(connections.begin() + i);
104947
- i--;
104990
+ connections.erase(it.first);
104948
104991
  continue;
104949
104992
  } else {
104950
104993
  result.push_back(move(connection));
104951
104994
  }
104952
104995
  }
104996
+
104953
104997
  return result;
104954
104998
  }
104955
104999
 
@@ -104958,7 +105002,7 @@ public:
104958
105002
 
104959
105003
  public:
104960
105004
  mutex connections_lock;
104961
- vector<weak_ptr<ClientContext>> connections;
105005
+ unordered_map<ClientContext *, weak_ptr<ClientContext>> connections;
104962
105006
  };
104963
105007
 
104964
105008
  } // namespace duckdb
@@ -104977,6 +105021,10 @@ Connection::Connection(DatabaseInstance &database) : context(make_shared<ClientC
104977
105021
  Connection::Connection(DuckDB &database) : Connection(*database.instance) {
104978
105022
  }
104979
105023
 
105024
+ Connection::~Connection() {
105025
+ ConnectionManager::Get(*context->db).RemoveConnection(*context);
105026
+ }
105027
+
104980
105028
  string Connection::GetProfilingInformation(ProfilerPrintFormat format) {
104981
105029
  auto &profiler = QueryProfiler::Get(*context);
104982
105030
  if (format == ProfilerPrintFormat::JSON) {
@@ -116169,6 +116217,9 @@ public:
116169
116217
  //! Schema name to insert to
116170
116218
  string schema;
116171
116219
 
116220
+ //! keep track of optional returningList if statement contains a RETURNING keyword
116221
+ vector<unique_ptr<ParsedExpression>> returning_list;
116222
+
116172
116223
  protected:
116173
116224
  InsertStatement(const InsertStatement &other);
116174
116225
 
@@ -124445,6 +124496,15 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
124445
124496
  remove.VisitOperator(*op.children[0]);
124446
124497
  return;
124447
124498
  }
124499
+ case LogicalOperatorType::LOGICAL_INSERT: {
124500
+ //! When RETURNING is used, a PROJECTION is the top level operator
124501
+ //! We still need to project all values from the insert so the projection
124502
+ //! on top of the INSERT can select from only that table values being inserted
124503
+ RemoveUnusedColumns remove(binder, context, true);
124504
+ remove.VisitOperatorExpressions(op);
124505
+ remove.VisitOperator(*op.children[0]);
124506
+ return;
124507
+ }
124448
124508
  case LogicalOperatorType::LOGICAL_GET:
124449
124509
  LogicalOperatorVisitor::VisitOperatorExpressions(op);
124450
124510
  if (!everything_referenced) {
@@ -146299,6 +146359,11 @@ unique_ptr<InsertStatement> Transformer::TransformInsert(duckdb_libpgquery::PGNo
146299
146359
  result->columns.emplace_back(target->name);
146300
146360
  }
146301
146361
  }
146362
+
146363
+ // Grab and transform the returning columns from the parser.
146364
+ if (stmt->returningList) {
146365
+ Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
146366
+ }
146302
146367
  result->select_statement = TransformSelect(stmt->selectStmt, false);
146303
146368
 
146304
146369
  auto qname = TransformQualifiedName(stmt->relation);
@@ -152271,6 +152336,35 @@ protected:
152271
152336
 
152272
152337
 
152273
152338
 
152339
+
152340
+
152341
+ //===----------------------------------------------------------------------===//
152342
+ // DuckDB
152343
+ //
152344
+ // duckdb/planner/expression_binder/returning_binder.hpp
152345
+ //
152346
+ //
152347
+ //===----------------------------------------------------------------------===//
152348
+
152349
+
152350
+
152351
+
152352
+
152353
+ namespace duckdb {
152354
+
152355
+ //! The RETURNING binder is responsible for binding expressions within the RETURNING statement
152356
+ class ReturningBinder : public ExpressionBinder {
152357
+ public:
152358
+ ReturningBinder(Binder &binder, ClientContext &context);
152359
+
152360
+ protected:
152361
+ BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
152362
+ bool root_expression = false) override;
152363
+ };
152364
+
152365
+ } // namespace duckdb
152366
+
152367
+
152274
152368
  namespace duckdb {
152275
152369
 
152276
152370
  static void CheckInsertColumnCountMismatch(int64_t expected_columns, int64_t result_columns, bool columns_provided,
@@ -152378,18 +152472,73 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
152378
152472
  }
152379
152473
  }
152380
152474
 
152381
- // insert from select statement
152382
152475
  // parse select statement and add to logical plan
152383
152476
  auto root_select = Bind(*stmt.select_statement);
152384
152477
  CheckInsertColumnCountMismatch(expected_columns, root_select.types.size(), !stmt.columns.empty(),
152385
152478
  table->name.c_str());
152386
152479
 
152387
152480
  auto root = CastLogicalOperatorToTypes(root_select.types, insert->expected_types, move(root_select.plan));
152481
+
152388
152482
  insert->AddChild(move(root));
152389
152483
 
152390
- result.plan = move(insert);
152391
- this->allow_stream_result = false;
152392
- return result;
152484
+ if (!stmt.returning_list.empty()) {
152485
+ insert->return_chunk = true;
152486
+ // clear result type and names because returning list will update them
152487
+ result.types.clear();
152488
+ result.names.clear();
152489
+
152490
+ auto insert_table_index = GenerateTableIndex();
152491
+ insert->table_index = insert_table_index;
152492
+
152493
+ auto binder = Binder::CreateBinder(context);
152494
+ auto types = table->GetTypes();
152495
+ vector<std::string> names;
152496
+ for (auto &col : table->columns) {
152497
+ names.push_back(col.name);
152498
+ }
152499
+
152500
+ binder->bind_context.AddGenericBinding(insert->table_index, stmt.table, names, types);
152501
+ ReturningBinder returning_binder(*binder, context);
152502
+
152503
+ unique_ptr<LogicalOperator> insert_as_logicaloperator = move(insert);
152504
+
152505
+ vector<unique_ptr<Expression>> projection_expressions;
152506
+ LogicalType result_type;
152507
+ for (auto &returning_expr : stmt.returning_list) {
152508
+ auto expr_type = returning_expr->GetExpressionType();
152509
+ if (expr_type == ExpressionType::STAR) {
152510
+ auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
152511
+ binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr,
152512
+ generated_star_list);
152513
+
152514
+ for (auto &star_column : generated_star_list) {
152515
+ auto star_expr = returning_binder.Bind(star_column, &result_type);
152516
+ result.types.push_back(result_type);
152517
+ result.names.push_back(star_expr->GetName());
152518
+ projection_expressions.push_back(move(star_expr));
152519
+ }
152520
+ } else {
152521
+ auto expr = returning_binder.Bind(returning_expr, &result_type);
152522
+ result.names.push_back(expr->GetName());
152523
+ result.types.push_back(result_type);
152524
+ projection_expressions.push_back(move(expr));
152525
+ }
152526
+ }
152527
+
152528
+ auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
152529
+ projection->AddChild(move(insert_as_logicaloperator));
152530
+ result.plan = move(projection);
152531
+ D_ASSERT(result.types.size() == result.names.size());
152532
+ this->allow_stream_result = true;
152533
+ return result;
152534
+ } else {
152535
+ insert->table_index = 0;
152536
+ insert->return_chunk = false;
152537
+ D_ASSERT(result.types.size() == result.names.size());
152538
+ result.plan = move(insert);
152539
+ this->allow_stream_result = false;
152540
+ return result;
152541
+ }
152393
152542
  }
152394
152543
 
152395
152544
  } // namespace duckdb
@@ -156138,6 +156287,28 @@ string RelationBinder::UnsupportedAggregateMessage() {
156138
156287
 
156139
156288
 
156140
156289
 
156290
+ namespace duckdb {
156291
+
156292
+ ReturningBinder::ReturningBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
156293
+ }
156294
+
156295
+ BindResult ReturningBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
156296
+ auto &expr = **expr_ptr;
156297
+ switch (expr.GetExpressionClass()) {
156298
+ case ExpressionClass::SUBQUERY:
156299
+ return BindResult("SUBQUERY is not supported in returning statements");
156300
+ case ExpressionClass::BOUND_SUBQUERY:
156301
+ return BindResult("BOUND SUBQUERY is not supported in returning statements");
156302
+ default:
156303
+ return ExpressionBinder::BindExpression(expr_ptr, depth);
156304
+ }
156305
+ }
156306
+
156307
+ } // namespace duckdb
156308
+
156309
+
156310
+
156311
+
156141
156312
 
156142
156313
 
156143
156314
 
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 "b65122828"
15
- #define DUCKDB_VERSION "v0.3.3-dev849"
14
+ #define DUCKDB_SOURCE_ID "9c88ae129"
15
+ #define DUCKDB_VERSION "v0.3.3-dev901"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -16647,6 +16647,7 @@ class Connection {
16647
16647
  public:
16648
16648
  DUCKDB_API explicit Connection(DuckDB &database);
16649
16649
  DUCKDB_API explicit Connection(DatabaseInstance &database);
16650
+ DUCKDB_API ~Connection();
16650
16651
 
16651
16652
  shared_ptr<ClientContext> context;
16652
16653
  warning_callback warning_cb;
@@ -16828,6 +16829,7 @@ private:
16828
16829
  };
16829
16830
 
16830
16831
  } // namespace duckdb
16832
+
16831
16833
  //===----------------------------------------------------------------------===//
16832
16834
  // DuckDB
16833
16835
  //