duckdb 0.3.3-dev865.0 → 0.3.3-dev918.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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.3.3-dev865.0",
4
+ "version": "0.3.3-dev918.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -53208,7 +53208,7 @@ private:
53208
53208
  };
53209
53209
 
53210
53210
  template <typename T, typename OP>
53211
- struct OperationCompare : public std::binary_function<T, T, bool> {
53211
+ struct OperationCompare : public std::function<bool(T, T)> {
53212
53212
  inline bool operator()(const T &lhs, const T &val) const {
53213
53213
  return OP::template Operation(lhs, val);
53214
53214
  }
@@ -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
 
@@ -120942,6 +120993,8 @@ private:
120942
120993
  unique_ptr<LogicalOperator> PushdownSetOperation(unique_ptr<LogicalOperator> op);
120943
120994
  //! Push down a LogicalGet op
120944
120995
  unique_ptr<LogicalOperator> PushdownGet(unique_ptr<LogicalOperator> op);
120996
+ //! Push down a LogicalLimit op
120997
+ unique_ptr<LogicalOperator> PushdownLimit(unique_ptr<LogicalOperator> op);
120945
120998
  // Pushdown an inner join
120946
120999
  unique_ptr<LogicalOperator> PushdownInnerJoin(unique_ptr<LogicalOperator> op, unordered_set<idx_t> &left_bindings,
120947
121000
  unordered_set<idx_t> &right_bindings);
@@ -121007,6 +121060,8 @@ unique_ptr<LogicalOperator> FilterPushdown::Rewrite(unique_ptr<LogicalOperator>
121007
121060
  }
121008
121061
  case LogicalOperatorType::LOGICAL_GET:
121009
121062
  return PushdownGet(move(op));
121063
+ case LogicalOperatorType::LOGICAL_LIMIT:
121064
+ return PushdownLimit(move(op));
121010
121065
  default:
121011
121066
  return FinishPushdown(move(op));
121012
121067
  }
@@ -123937,6 +123992,25 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownLeftJoin(unique_ptr<LogicalO
123937
123992
 
123938
123993
 
123939
123994
 
123995
+
123996
+
123997
+ namespace duckdb {
123998
+
123999
+ unique_ptr<LogicalOperator> FilterPushdown::PushdownLimit(unique_ptr<LogicalOperator> op) {
124000
+ auto &limit = (LogicalLimit &)*op;
124001
+
124002
+ if (!limit.limit && limit.limit_val == 0) {
124003
+ return make_unique<LogicalEmptyResult>(move(op));
124004
+ }
124005
+
124006
+ return FinishPushdown(move(op));
124007
+ }
124008
+
124009
+ } // namespace duckdb
124010
+
124011
+
124012
+
124013
+
123940
124014
  namespace duckdb {
123941
124015
 
123942
124016
  using Filter = FilterPushdown::Filter;
@@ -124445,6 +124519,15 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
124445
124519
  remove.VisitOperator(*op.children[0]);
124446
124520
  return;
124447
124521
  }
124522
+ case LogicalOperatorType::LOGICAL_INSERT: {
124523
+ //! When RETURNING is used, a PROJECTION is the top level operator
124524
+ //! We still need to project all values from the insert so the projection
124525
+ //! on top of the INSERT can select from only that table values being inserted
124526
+ RemoveUnusedColumns remove(binder, context, true);
124527
+ remove.VisitOperatorExpressions(op);
124528
+ remove.VisitOperator(*op.children[0]);
124529
+ return;
124530
+ }
124448
124531
  case LogicalOperatorType::LOGICAL_GET:
124449
124532
  LogicalOperatorVisitor::VisitOperatorExpressions(op);
124450
124533
  if (!everything_referenced) {
@@ -146299,6 +146382,11 @@ unique_ptr<InsertStatement> Transformer::TransformInsert(duckdb_libpgquery::PGNo
146299
146382
  result->columns.emplace_back(target->name);
146300
146383
  }
146301
146384
  }
146385
+
146386
+ // Grab and transform the returning columns from the parser.
146387
+ if (stmt->returningList) {
146388
+ Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
146389
+ }
146302
146390
  result->select_statement = TransformSelect(stmt->selectStmt, false);
146303
146391
 
146304
146392
  auto qname = TransformQualifiedName(stmt->relation);
@@ -152271,6 +152359,35 @@ protected:
152271
152359
 
152272
152360
 
152273
152361
 
152362
+
152363
+
152364
+ //===----------------------------------------------------------------------===//
152365
+ // DuckDB
152366
+ //
152367
+ // duckdb/planner/expression_binder/returning_binder.hpp
152368
+ //
152369
+ //
152370
+ //===----------------------------------------------------------------------===//
152371
+
152372
+
152373
+
152374
+
152375
+
152376
+ namespace duckdb {
152377
+
152378
+ //! The RETURNING binder is responsible for binding expressions within the RETURNING statement
152379
+ class ReturningBinder : public ExpressionBinder {
152380
+ public:
152381
+ ReturningBinder(Binder &binder, ClientContext &context);
152382
+
152383
+ protected:
152384
+ BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
152385
+ bool root_expression = false) override;
152386
+ };
152387
+
152388
+ } // namespace duckdb
152389
+
152390
+
152274
152391
  namespace duckdb {
152275
152392
 
152276
152393
  static void CheckInsertColumnCountMismatch(int64_t expected_columns, int64_t result_columns, bool columns_provided,
@@ -152378,18 +152495,73 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
152378
152495
  }
152379
152496
  }
152380
152497
 
152381
- // insert from select statement
152382
152498
  // parse select statement and add to logical plan
152383
152499
  auto root_select = Bind(*stmt.select_statement);
152384
152500
  CheckInsertColumnCountMismatch(expected_columns, root_select.types.size(), !stmt.columns.empty(),
152385
152501
  table->name.c_str());
152386
152502
 
152387
152503
  auto root = CastLogicalOperatorToTypes(root_select.types, insert->expected_types, move(root_select.plan));
152504
+
152388
152505
  insert->AddChild(move(root));
152389
152506
 
152390
- result.plan = move(insert);
152391
- this->allow_stream_result = false;
152392
- return result;
152507
+ if (!stmt.returning_list.empty()) {
152508
+ insert->return_chunk = true;
152509
+ // clear result type and names because returning list will update them
152510
+ result.types.clear();
152511
+ result.names.clear();
152512
+
152513
+ auto insert_table_index = GenerateTableIndex();
152514
+ insert->table_index = insert_table_index;
152515
+
152516
+ auto binder = Binder::CreateBinder(context);
152517
+ auto types = table->GetTypes();
152518
+ vector<std::string> names;
152519
+ for (auto &col : table->columns) {
152520
+ names.push_back(col.name);
152521
+ }
152522
+
152523
+ binder->bind_context.AddGenericBinding(insert->table_index, stmt.table, names, types);
152524
+ ReturningBinder returning_binder(*binder, context);
152525
+
152526
+ unique_ptr<LogicalOperator> insert_as_logicaloperator = move(insert);
152527
+
152528
+ vector<unique_ptr<Expression>> projection_expressions;
152529
+ LogicalType result_type;
152530
+ for (auto &returning_expr : stmt.returning_list) {
152531
+ auto expr_type = returning_expr->GetExpressionType();
152532
+ if (expr_type == ExpressionType::STAR) {
152533
+ auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
152534
+ binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr,
152535
+ generated_star_list);
152536
+
152537
+ for (auto &star_column : generated_star_list) {
152538
+ auto star_expr = returning_binder.Bind(star_column, &result_type);
152539
+ result.types.push_back(result_type);
152540
+ result.names.push_back(star_expr->GetName());
152541
+ projection_expressions.push_back(move(star_expr));
152542
+ }
152543
+ } else {
152544
+ auto expr = returning_binder.Bind(returning_expr, &result_type);
152545
+ result.names.push_back(expr->GetName());
152546
+ result.types.push_back(result_type);
152547
+ projection_expressions.push_back(move(expr));
152548
+ }
152549
+ }
152550
+
152551
+ auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
152552
+ projection->AddChild(move(insert_as_logicaloperator));
152553
+ result.plan = move(projection);
152554
+ D_ASSERT(result.types.size() == result.names.size());
152555
+ this->allow_stream_result = true;
152556
+ return result;
152557
+ } else {
152558
+ insert->table_index = 0;
152559
+ insert->return_chunk = false;
152560
+ D_ASSERT(result.types.size() == result.names.size());
152561
+ result.plan = move(insert);
152562
+ this->allow_stream_result = false;
152563
+ return result;
152564
+ }
152393
152565
  }
152394
152566
 
152395
152567
  } // namespace duckdb
@@ -156138,6 +156310,28 @@ string RelationBinder::UnsupportedAggregateMessage() {
156138
156310
 
156139
156311
 
156140
156312
 
156313
+ namespace duckdb {
156314
+
156315
+ ReturningBinder::ReturningBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) {
156316
+ }
156317
+
156318
+ BindResult ReturningBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
156319
+ auto &expr = **expr_ptr;
156320
+ switch (expr.GetExpressionClass()) {
156321
+ case ExpressionClass::SUBQUERY:
156322
+ return BindResult("SUBQUERY is not supported in returning statements");
156323
+ case ExpressionClass::BOUND_SUBQUERY:
156324
+ return BindResult("BOUND SUBQUERY is not supported in returning statements");
156325
+ default:
156326
+ return ExpressionBinder::BindExpression(expr_ptr, depth);
156327
+ }
156328
+ }
156329
+
156330
+ } // namespace duckdb
156331
+
156332
+
156333
+
156334
+
156141
156335
 
156142
156336
 
156143
156337
 
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 "a004ed237"
15
- #define DUCKDB_VERSION "v0.3.3-dev865"
14
+ #define DUCKDB_SOURCE_ID "3111480a9"
15
+ #define DUCKDB_VERSION "v0.3.3-dev918"
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
  //