duckdb 0.3.3-dev1232.0 → 0.3.3-dev1251.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/duckdb.cpp +265 -106
- package/src/duckdb.hpp +5 -2
- package/src/parquet-amalgamation.cpp +36694 -36694
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -64051,14 +64051,15 @@ class DataTable;
|
|
|
64051
64051
|
class PhysicalDelete : public PhysicalOperator {
|
|
64052
64052
|
public:
|
|
64053
64053
|
PhysicalDelete(vector<LogicalType> types, TableCatalogEntry &tableref, DataTable &table, idx_t row_id_index,
|
|
64054
|
-
idx_t estimated_cardinality)
|
|
64054
|
+
idx_t estimated_cardinality, bool return_chunk)
|
|
64055
64055
|
: PhysicalOperator(PhysicalOperatorType::DELETE_OPERATOR, move(types), estimated_cardinality),
|
|
64056
|
-
tableref(tableref), table(table), row_id_index(row_id_index) {
|
|
64056
|
+
tableref(tableref), table(table), row_id_index(row_id_index), return_chunk(return_chunk) {
|
|
64057
64057
|
}
|
|
64058
64058
|
|
|
64059
64059
|
TableCatalogEntry &tableref;
|
|
64060
64060
|
DataTable &table;
|
|
64061
64061
|
idx_t row_id_index;
|
|
64062
|
+
bool return_chunk;
|
|
64062
64063
|
|
|
64063
64064
|
public:
|
|
64064
64065
|
// Source interface
|
|
@@ -64069,6 +64070,7 @@ public:
|
|
|
64069
64070
|
public:
|
|
64070
64071
|
// Sink interface
|
|
64071
64072
|
unique_ptr<GlobalSinkState> GetGlobalSinkState(ClientContext &context) const override;
|
|
64073
|
+
unique_ptr<LocalSinkState> GetLocalSinkState(ExecutionContext &context) const override;
|
|
64072
64074
|
SinkResultType Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
|
|
64073
64075
|
DataChunk &input) const override;
|
|
64074
64076
|
|
|
@@ -64088,6 +64090,7 @@ public:
|
|
|
64088
64090
|
|
|
64089
64091
|
|
|
64090
64092
|
|
|
64093
|
+
|
|
64091
64094
|
namespace duckdb {
|
|
64092
64095
|
|
|
64093
64096
|
//===--------------------------------------------------------------------===//
|
|
@@ -64095,21 +64098,46 @@ namespace duckdb {
|
|
|
64095
64098
|
//===--------------------------------------------------------------------===//
|
|
64096
64099
|
class DeleteGlobalState : public GlobalSinkState {
|
|
64097
64100
|
public:
|
|
64098
|
-
DeleteGlobalState() : deleted_count(0) {
|
|
64101
|
+
DeleteGlobalState() : deleted_count(0), returned_chunk_count(0) {
|
|
64099
64102
|
}
|
|
64100
64103
|
|
|
64101
64104
|
mutex delete_lock;
|
|
64102
64105
|
idx_t deleted_count;
|
|
64106
|
+
ChunkCollection return_chunk_collection;
|
|
64107
|
+
idx_t returned_chunk_count;
|
|
64108
|
+
};
|
|
64109
|
+
|
|
64110
|
+
class DeleteLocalState : public LocalSinkState {
|
|
64111
|
+
public:
|
|
64112
|
+
explicit DeleteLocalState(const vector<LogicalType> &table_types) {
|
|
64113
|
+
delete_chunk.Initialize(table_types);
|
|
64114
|
+
}
|
|
64115
|
+
DataChunk delete_chunk;
|
|
64103
64116
|
};
|
|
64104
64117
|
|
|
64105
64118
|
SinkResultType PhysicalDelete::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
|
|
64106
64119
|
DataChunk &input) const {
|
|
64107
64120
|
auto &gstate = (DeleteGlobalState &)state;
|
|
64121
|
+
auto &ustate = (DeleteLocalState &)lstate;
|
|
64122
|
+
|
|
64123
|
+
// get rows and
|
|
64124
|
+
auto &transaction = Transaction::GetTransaction(context.client);
|
|
64125
|
+
auto &row_identifiers = input.data[row_id_index];
|
|
64126
|
+
|
|
64127
|
+
vector<column_t> column_ids;
|
|
64128
|
+
for (idx_t i = 0; i < table.column_definitions.size(); i++) {
|
|
64129
|
+
column_ids.emplace_back(i);
|
|
64130
|
+
};
|
|
64131
|
+
auto cfs = ColumnFetchState();
|
|
64108
64132
|
|
|
64109
|
-
// delete data in the base table
|
|
64110
|
-
// the row ids are given to us as the last column of the child chunk
|
|
64111
64133
|
lock_guard<mutex> delete_guard(gstate.delete_lock);
|
|
64112
|
-
|
|
64134
|
+
if (return_chunk) {
|
|
64135
|
+
row_identifiers.Normalify(input.size());
|
|
64136
|
+
table.Fetch(transaction, ustate.delete_chunk, column_ids, row_identifiers, input.size(), cfs);
|
|
64137
|
+
gstate.return_chunk_collection.Append(ustate.delete_chunk);
|
|
64138
|
+
}
|
|
64139
|
+
gstate.deleted_count += table.Delete(tableref, context.client, row_identifiers, input.size());
|
|
64140
|
+
|
|
64113
64141
|
return SinkResultType::NEED_MORE_INPUT;
|
|
64114
64142
|
}
|
|
64115
64143
|
|
|
@@ -64117,6 +64145,10 @@ unique_ptr<GlobalSinkState> PhysicalDelete::GetGlobalSinkState(ClientContext &co
|
|
|
64117
64145
|
return make_unique<DeleteGlobalState>();
|
|
64118
64146
|
}
|
|
64119
64147
|
|
|
64148
|
+
unique_ptr<LocalSinkState> PhysicalDelete::GetLocalSinkState(ExecutionContext &context) const {
|
|
64149
|
+
return make_unique<DeleteLocalState>(table.GetTypes());
|
|
64150
|
+
}
|
|
64151
|
+
|
|
64120
64152
|
//===--------------------------------------------------------------------===//
|
|
64121
64153
|
// Source
|
|
64122
64154
|
//===--------------------------------------------------------------------===//
|
|
@@ -64140,9 +64172,22 @@ void PhysicalDelete::GetData(ExecutionContext &context, DataChunk &chunk, Global
|
|
|
64140
64172
|
return;
|
|
64141
64173
|
}
|
|
64142
64174
|
|
|
64143
|
-
|
|
64144
|
-
|
|
64145
|
-
|
|
64175
|
+
if (!return_chunk) {
|
|
64176
|
+
chunk.SetCardinality(1);
|
|
64177
|
+
chunk.SetValue(0, 0, Value::BIGINT(g.deleted_count));
|
|
64178
|
+
state.finished = true;
|
|
64179
|
+
}
|
|
64180
|
+
|
|
64181
|
+
idx_t chunk_return = g.returned_chunk_count;
|
|
64182
|
+
if (chunk_return >= g.return_chunk_collection.Chunks().size()) {
|
|
64183
|
+
return;
|
|
64184
|
+
}
|
|
64185
|
+
chunk.Reference(g.return_chunk_collection.GetChunk(chunk_return));
|
|
64186
|
+
chunk.SetCardinality((g.return_chunk_collection.GetChunk(chunk_return)).size());
|
|
64187
|
+
g.returned_chunk_count += 1;
|
|
64188
|
+
if (g.returned_chunk_count >= g.return_chunk_collection.Chunks().size()) {
|
|
64189
|
+
state.finished = true;
|
|
64190
|
+
}
|
|
64146
64191
|
}
|
|
64147
64192
|
|
|
64148
64193
|
} // namespace duckdb
|
|
@@ -64589,10 +64634,10 @@ class PhysicalUpdate : public PhysicalOperator {
|
|
|
64589
64634
|
public:
|
|
64590
64635
|
PhysicalUpdate(vector<LogicalType> types, TableCatalogEntry &tableref, DataTable &table, vector<column_t> columns,
|
|
64591
64636
|
vector<unique_ptr<Expression>> expressions, vector<unique_ptr<Expression>> bound_defaults,
|
|
64592
|
-
idx_t estimated_cardinality)
|
|
64637
|
+
idx_t estimated_cardinality, bool return_chunk)
|
|
64593
64638
|
: PhysicalOperator(PhysicalOperatorType::UPDATE, move(types), estimated_cardinality), tableref(tableref),
|
|
64594
64639
|
table(table), columns(std::move(columns)), expressions(move(expressions)),
|
|
64595
|
-
bound_defaults(move(bound_defaults)) {
|
|
64640
|
+
bound_defaults(move(bound_defaults)), return_chunk(return_chunk) {
|
|
64596
64641
|
}
|
|
64597
64642
|
|
|
64598
64643
|
TableCatalogEntry &tableref;
|
|
@@ -64601,6 +64646,8 @@ public:
|
|
|
64601
64646
|
vector<unique_ptr<Expression>> expressions;
|
|
64602
64647
|
vector<unique_ptr<Expression>> bound_defaults;
|
|
64603
64648
|
bool update_is_del_and_insert;
|
|
64649
|
+
//! If the returning statement is present, return the whole chunk
|
|
64650
|
+
bool return_chunk;
|
|
64604
64651
|
|
|
64605
64652
|
public:
|
|
64606
64653
|
// Source interface
|
|
@@ -64634,6 +64681,7 @@ public:
|
|
|
64634
64681
|
|
|
64635
64682
|
|
|
64636
64683
|
|
|
64684
|
+
|
|
64637
64685
|
namespace duckdb {
|
|
64638
64686
|
|
|
64639
64687
|
//===--------------------------------------------------------------------===//
|
|
@@ -64641,12 +64689,14 @@ namespace duckdb {
|
|
|
64641
64689
|
//===--------------------------------------------------------------------===//
|
|
64642
64690
|
class UpdateGlobalState : public GlobalSinkState {
|
|
64643
64691
|
public:
|
|
64644
|
-
UpdateGlobalState() : updated_count(0) {
|
|
64692
|
+
UpdateGlobalState() : updated_count(0), returned_chunk_count(0) {
|
|
64645
64693
|
}
|
|
64646
64694
|
|
|
64647
64695
|
mutex lock;
|
|
64648
64696
|
idx_t updated_count;
|
|
64649
64697
|
unordered_set<row_t> updated_columns;
|
|
64698
|
+
ChunkCollection return_chunk_collection;
|
|
64699
|
+
idx_t returned_chunk_count;
|
|
64650
64700
|
};
|
|
64651
64701
|
|
|
64652
64702
|
class UpdateLocalState : public LocalSinkState {
|
|
@@ -64726,9 +64776,21 @@ SinkResultType PhysicalUpdate::Sink(ExecutionContext &context, GlobalSinkState &
|
|
|
64726
64776
|
}
|
|
64727
64777
|
table.Append(tableref, context.client, mock_chunk);
|
|
64728
64778
|
} else {
|
|
64779
|
+
if (return_chunk) {
|
|
64780
|
+
mock_chunk.SetCardinality(update_chunk);
|
|
64781
|
+
for (idx_t i = 0; i < columns.size(); i++) {
|
|
64782
|
+
mock_chunk.data[columns[i]].Reference(update_chunk.data[i]);
|
|
64783
|
+
}
|
|
64784
|
+
}
|
|
64729
64785
|
table.Update(tableref, context.client, row_ids, columns, update_chunk);
|
|
64730
64786
|
}
|
|
64787
|
+
|
|
64788
|
+
if (return_chunk) {
|
|
64789
|
+
gstate.return_chunk_collection.Append(mock_chunk);
|
|
64790
|
+
}
|
|
64791
|
+
|
|
64731
64792
|
gstate.updated_count += chunk.size();
|
|
64793
|
+
|
|
64732
64794
|
return SinkResultType::NEED_MORE_INPUT;
|
|
64733
64795
|
}
|
|
64734
64796
|
|
|
@@ -64769,10 +64831,22 @@ void PhysicalUpdate::GetData(ExecutionContext &context, DataChunk &chunk, Global
|
|
|
64769
64831
|
if (state.finished) {
|
|
64770
64832
|
return;
|
|
64771
64833
|
}
|
|
64834
|
+
if (!return_chunk) {
|
|
64835
|
+
chunk.SetCardinality(1);
|
|
64836
|
+
chunk.SetValue(0, 0, Value::BIGINT(g.updated_count));
|
|
64837
|
+
state.finished = true;
|
|
64838
|
+
}
|
|
64772
64839
|
|
|
64773
|
-
|
|
64774
|
-
|
|
64775
|
-
|
|
64840
|
+
idx_t chunk_return = g.returned_chunk_count;
|
|
64841
|
+
if (chunk_return >= g.return_chunk_collection.Chunks().size()) {
|
|
64842
|
+
return;
|
|
64843
|
+
}
|
|
64844
|
+
chunk.Reference(g.return_chunk_collection.GetChunk(chunk_return));
|
|
64845
|
+
chunk.SetCardinality((g.return_chunk_collection.GetChunk(chunk_return)).size());
|
|
64846
|
+
g.returned_chunk_count += 1;
|
|
64847
|
+
if (g.returned_chunk_count >= g.return_chunk_collection.Chunks().size()) {
|
|
64848
|
+
state.finished = true;
|
|
64849
|
+
}
|
|
64776
64850
|
}
|
|
64777
64851
|
|
|
64778
64852
|
} // namespace duckdb
|
|
@@ -68395,14 +68469,27 @@ namespace duckdb {
|
|
|
68395
68469
|
class LogicalDelete : public LogicalOperator {
|
|
68396
68470
|
public:
|
|
68397
68471
|
explicit LogicalDelete(TableCatalogEntry *table)
|
|
68398
|
-
: LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table) {
|
|
68472
|
+
: LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table), table_index(0), return_chunk(false) {
|
|
68399
68473
|
}
|
|
68400
68474
|
|
|
68401
68475
|
TableCatalogEntry *table;
|
|
68476
|
+
idx_t table_index;
|
|
68477
|
+
bool return_chunk;
|
|
68402
68478
|
|
|
68403
68479
|
protected:
|
|
68480
|
+
vector<ColumnBinding> GetColumnBindings() override {
|
|
68481
|
+
if (return_chunk) {
|
|
68482
|
+
return GenerateColumnBindings(table_index, table->columns.size());
|
|
68483
|
+
}
|
|
68484
|
+
return {ColumnBinding(0, 0)};
|
|
68485
|
+
}
|
|
68486
|
+
|
|
68404
68487
|
void ResolveTypes() override {
|
|
68405
|
-
|
|
68488
|
+
if (return_chunk) {
|
|
68489
|
+
types = table->GetTypes();
|
|
68490
|
+
} else {
|
|
68491
|
+
types.emplace_back(LogicalType::BIGINT);
|
|
68492
|
+
}
|
|
68406
68493
|
}
|
|
68407
68494
|
};
|
|
68408
68495
|
} // namespace duckdb
|
|
@@ -68421,8 +68508,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalDelete &op
|
|
|
68421
68508
|
auto &bound_ref = (BoundReferenceExpression &)*op.expressions[0];
|
|
68422
68509
|
|
|
68423
68510
|
dependencies.insert(op.table);
|
|
68424
|
-
auto del =
|
|
68425
|
-
|
|
68511
|
+
auto del = make_unique<PhysicalDelete>(op.types, *op.table, *op.table->storage, bound_ref.index,
|
|
68512
|
+
op.estimated_cardinality, op.return_chunk);
|
|
68426
68513
|
del->children.push_back(move(plan));
|
|
68427
68514
|
return move(del);
|
|
68428
68515
|
}
|
|
@@ -70711,17 +70798,33 @@ namespace duckdb {
|
|
|
70711
70798
|
class LogicalUpdate : public LogicalOperator {
|
|
70712
70799
|
public:
|
|
70713
70800
|
explicit LogicalUpdate(TableCatalogEntry *table)
|
|
70714
|
-
: LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table) {
|
|
70801
|
+
: LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table), table_index(0), return_chunk(false) {
|
|
70715
70802
|
}
|
|
70716
70803
|
|
|
70804
|
+
//! The base table to update
|
|
70717
70805
|
TableCatalogEntry *table;
|
|
70806
|
+
//! table catalog index
|
|
70807
|
+
idx_t table_index;
|
|
70808
|
+
//! if returning option is used, return the update chunk
|
|
70809
|
+
bool return_chunk;
|
|
70718
70810
|
vector<column_t> columns;
|
|
70719
70811
|
vector<unique_ptr<Expression>> bound_defaults;
|
|
70720
70812
|
bool update_is_del_and_insert;
|
|
70721
70813
|
|
|
70722
70814
|
protected:
|
|
70815
|
+
vector<ColumnBinding> GetColumnBindings() override {
|
|
70816
|
+
if (return_chunk) {
|
|
70817
|
+
return GenerateColumnBindings(table_index, table->columns.size());
|
|
70818
|
+
}
|
|
70819
|
+
return {ColumnBinding(0, 0)};
|
|
70820
|
+
}
|
|
70821
|
+
|
|
70723
70822
|
void ResolveTypes() override {
|
|
70724
|
-
|
|
70823
|
+
if (return_chunk) {
|
|
70824
|
+
types = table->GetTypes();
|
|
70825
|
+
} else {
|
|
70826
|
+
types.emplace_back(LogicalType::BIGINT);
|
|
70827
|
+
}
|
|
70725
70828
|
}
|
|
70726
70829
|
};
|
|
70727
70830
|
} // namespace duckdb
|
|
@@ -70736,7 +70839,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalUpdate &op
|
|
|
70736
70839
|
|
|
70737
70840
|
dependencies.insert(op.table);
|
|
70738
70841
|
auto update = make_unique<PhysicalUpdate>(op.types, *op.table, *op.table->storage, op.columns, move(op.expressions),
|
|
70739
|
-
move(op.bound_defaults), op.estimated_cardinality);
|
|
70842
|
+
move(op.bound_defaults), op.estimated_cardinality, op.return_chunk);
|
|
70843
|
+
|
|
70740
70844
|
update->update_is_del_and_insert = op.update_is_del_and_insert;
|
|
70741
70845
|
update->children.push_back(move(plan));
|
|
70742
70846
|
return move(update);
|
|
@@ -119089,6 +119193,7 @@ public:
|
|
|
119089
119193
|
unique_ptr<ParsedExpression> condition;
|
|
119090
119194
|
unique_ptr<TableRef> table;
|
|
119091
119195
|
vector<unique_ptr<TableRef>> using_clauses;
|
|
119196
|
+
vector<unique_ptr<ParsedExpression>> returning_list;
|
|
119092
119197
|
|
|
119093
119198
|
protected:
|
|
119094
119199
|
DeleteStatement(const DeleteStatement &other);
|
|
@@ -120393,6 +120498,8 @@ public:
|
|
|
120393
120498
|
unique_ptr<TableRef> from_table;
|
|
120394
120499
|
vector<string> columns;
|
|
120395
120500
|
vector<unique_ptr<ParsedExpression>> expressions;
|
|
120501
|
+
//! keep track of optional returningList if statement contains a RETURNING keyword
|
|
120502
|
+
vector<unique_ptr<ParsedExpression>> returning_list;
|
|
120396
120503
|
|
|
120397
120504
|
protected:
|
|
120398
120505
|
UpdateStatement(const UpdateStatement &other);
|
|
@@ -127788,10 +127895,14 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
|
|
|
127788
127895
|
remove.VisitOperator(*op.children[0]);
|
|
127789
127896
|
return;
|
|
127790
127897
|
}
|
|
127791
|
-
case LogicalOperatorType::LOGICAL_INSERT:
|
|
127792
|
-
|
|
127793
|
-
|
|
127794
|
-
//!
|
|
127898
|
+
case LogicalOperatorType::LOGICAL_INSERT:
|
|
127899
|
+
case LogicalOperatorType::LOGICAL_UPDATE:
|
|
127900
|
+
case LogicalOperatorType::LOGICAL_DELETE: {
|
|
127901
|
+
//! When RETURNING is used, a PROJECTION is the top level operator for INSERTS, UPDATES, and DELETES
|
|
127902
|
+
//! We still need to project all values from these operators so the projection
|
|
127903
|
+
//! on top of them can select from only the table values being inserted.
|
|
127904
|
+
//! TODO: Push down the projections from the returning statement
|
|
127905
|
+
//! TODO: Be careful because you might be adding expressions when a user returns *
|
|
127795
127906
|
RemoveUnusedColumns remove(binder, context, true);
|
|
127796
127907
|
remove.VisitOperatorExpressions(op);
|
|
127797
127908
|
remove.VisitOperator(*op.children[0]);
|
|
@@ -149736,6 +149847,10 @@ unique_ptr<DeleteStatement> Transformer::TransformDelete(duckdb_libpgquery::PGNo
|
|
|
149736
149847
|
result->using_clauses.push_back(move(using_entry));
|
|
149737
149848
|
}
|
|
149738
149849
|
}
|
|
149850
|
+
|
|
149851
|
+
if (stmt->returningList) {
|
|
149852
|
+
Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
|
|
149853
|
+
}
|
|
149739
149854
|
return result;
|
|
149740
149855
|
}
|
|
149741
149856
|
|
|
@@ -150500,6 +150615,11 @@ unique_ptr<UpdateStatement> Transformer::TransformUpdate(duckdb_libpgquery::PGNo
|
|
|
150500
150615
|
result->expressions.push_back(TransformExpression(target->val));
|
|
150501
150616
|
}
|
|
150502
150617
|
|
|
150618
|
+
// Grab and transform the returning columns from the parser.
|
|
150619
|
+
if (stmt->returningList) {
|
|
150620
|
+
Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list);
|
|
150621
|
+
}
|
|
150622
|
+
|
|
150503
150623
|
result->condition = TransformExpression(stmt->whereClause);
|
|
150504
150624
|
return result;
|
|
150505
150625
|
}
|
|
@@ -155700,6 +155820,32 @@ unique_ptr<BoundCreateTableInfo> Binder::BindCreateTableInfo(unique_ptr<CreateIn
|
|
|
155700
155820
|
|
|
155701
155821
|
|
|
155702
155822
|
|
|
155823
|
+
//===----------------------------------------------------------------------===//
|
|
155824
|
+
// DuckDB
|
|
155825
|
+
//
|
|
155826
|
+
// duckdb/planner/expression_binder/returning_binder.hpp
|
|
155827
|
+
//
|
|
155828
|
+
//
|
|
155829
|
+
//===----------------------------------------------------------------------===//
|
|
155830
|
+
|
|
155831
|
+
|
|
155832
|
+
|
|
155833
|
+
|
|
155834
|
+
|
|
155835
|
+
namespace duckdb {
|
|
155836
|
+
|
|
155837
|
+
//! The RETURNING binder is responsible for binding expressions within the RETURNING statement
|
|
155838
|
+
class ReturningBinder : public ExpressionBinder {
|
|
155839
|
+
public:
|
|
155840
|
+
ReturningBinder(Binder &binder, ClientContext &context);
|
|
155841
|
+
|
|
155842
|
+
protected:
|
|
155843
|
+
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
155844
|
+
bool root_expression = false) override;
|
|
155845
|
+
};
|
|
155846
|
+
|
|
155847
|
+
} // namespace duckdb
|
|
155848
|
+
|
|
155703
155849
|
|
|
155704
155850
|
|
|
155705
155851
|
|
|
@@ -155774,10 +155920,21 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) {
|
|
|
155774
155920
|
LogicalType::ROW_TYPE, ColumnBinding(get.table_index, get.column_ids.size())));
|
|
155775
155921
|
get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
|
|
155776
155922
|
|
|
155777
|
-
|
|
155778
|
-
|
|
155779
|
-
|
|
155780
|
-
|
|
155923
|
+
if (!stmt.returning_list.empty()) {
|
|
155924
|
+
del->return_chunk = true;
|
|
155925
|
+
|
|
155926
|
+
auto update_table_index = GenerateTableIndex();
|
|
155927
|
+
del->table_index = update_table_index;
|
|
155928
|
+
|
|
155929
|
+
unique_ptr<LogicalOperator> del_as_logicaloperator = move(del);
|
|
155930
|
+
return BindReturning(move(stmt.returning_list), table, update_table_index, move(del_as_logicaloperator),
|
|
155931
|
+
move(result));
|
|
155932
|
+
} else {
|
|
155933
|
+
result.plan = move(del);
|
|
155934
|
+
result.names = {"Count"};
|
|
155935
|
+
result.types = {LogicalType::BIGINT};
|
|
155936
|
+
this->allow_stream_result = false;
|
|
155937
|
+
}
|
|
155781
155938
|
return result;
|
|
155782
155939
|
}
|
|
155783
155940
|
|
|
@@ -156100,31 +156257,6 @@ protected:
|
|
|
156100
156257
|
|
|
156101
156258
|
|
|
156102
156259
|
|
|
156103
|
-
//===----------------------------------------------------------------------===//
|
|
156104
|
-
// DuckDB
|
|
156105
|
-
//
|
|
156106
|
-
// duckdb/planner/expression_binder/returning_binder.hpp
|
|
156107
|
-
//
|
|
156108
|
-
//
|
|
156109
|
-
//===----------------------------------------------------------------------===//
|
|
156110
|
-
|
|
156111
|
-
|
|
156112
|
-
|
|
156113
|
-
|
|
156114
|
-
|
|
156115
|
-
namespace duckdb {
|
|
156116
|
-
|
|
156117
|
-
//! The RETURNING binder is responsible for binding expressions within the RETURNING statement
|
|
156118
|
-
class ReturningBinder : public ExpressionBinder {
|
|
156119
|
-
public:
|
|
156120
|
-
ReturningBinder(Binder &binder, ClientContext &context);
|
|
156121
|
-
|
|
156122
|
-
protected:
|
|
156123
|
-
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
156124
|
-
bool root_expression = false) override;
|
|
156125
|
-
};
|
|
156126
|
-
|
|
156127
|
-
} // namespace duckdb
|
|
156128
156260
|
|
|
156129
156261
|
|
|
156130
156262
|
namespace duckdb {
|
|
@@ -156245,57 +156377,15 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
|
|
|
156245
156377
|
|
|
156246
156378
|
if (!stmt.returning_list.empty()) {
|
|
156247
156379
|
insert->return_chunk = true;
|
|
156248
|
-
// clear result type and names because returning list will update them
|
|
156249
156380
|
result.types.clear();
|
|
156250
156381
|
result.names.clear();
|
|
156251
|
-
|
|
156252
156382
|
auto insert_table_index = GenerateTableIndex();
|
|
156253
156383
|
insert->table_index = insert_table_index;
|
|
156384
|
+
unique_ptr<LogicalOperator> index_as_logicaloperator = move(insert);
|
|
156254
156385
|
|
|
156255
|
-
|
|
156256
|
-
|
|
156257
|
-
vector<std::string> names;
|
|
156258
|
-
for (auto &col : table->columns) {
|
|
156259
|
-
names.push_back(col.name);
|
|
156260
|
-
}
|
|
156261
|
-
|
|
156262
|
-
binder->bind_context.AddGenericBinding(insert->table_index, stmt.table, names, types);
|
|
156263
|
-
ReturningBinder returning_binder(*binder, context);
|
|
156264
|
-
|
|
156265
|
-
unique_ptr<LogicalOperator> insert_as_logicaloperator = move(insert);
|
|
156266
|
-
|
|
156267
|
-
vector<unique_ptr<Expression>> projection_expressions;
|
|
156268
|
-
LogicalType result_type;
|
|
156269
|
-
for (auto &returning_expr : stmt.returning_list) {
|
|
156270
|
-
auto expr_type = returning_expr->GetExpressionType();
|
|
156271
|
-
if (expr_type == ExpressionType::STAR) {
|
|
156272
|
-
auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
|
|
156273
|
-
binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr,
|
|
156274
|
-
generated_star_list);
|
|
156275
|
-
|
|
156276
|
-
for (auto &star_column : generated_star_list) {
|
|
156277
|
-
auto star_expr = returning_binder.Bind(star_column, &result_type);
|
|
156278
|
-
result.types.push_back(result_type);
|
|
156279
|
-
result.names.push_back(star_expr->GetName());
|
|
156280
|
-
projection_expressions.push_back(move(star_expr));
|
|
156281
|
-
}
|
|
156282
|
-
} else {
|
|
156283
|
-
auto expr = returning_binder.Bind(returning_expr, &result_type);
|
|
156284
|
-
result.names.push_back(expr->GetName());
|
|
156285
|
-
result.types.push_back(result_type);
|
|
156286
|
-
projection_expressions.push_back(move(expr));
|
|
156287
|
-
}
|
|
156288
|
-
}
|
|
156289
|
-
|
|
156290
|
-
auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
|
|
156291
|
-
projection->AddChild(move(insert_as_logicaloperator));
|
|
156292
|
-
result.plan = move(projection);
|
|
156293
|
-
D_ASSERT(result.types.size() == result.names.size());
|
|
156294
|
-
this->allow_stream_result = true;
|
|
156295
|
-
return result;
|
|
156386
|
+
return BindReturning(move(stmt.returning_list), table, insert_table_index, move(index_as_logicaloperator),
|
|
156387
|
+
move(result));
|
|
156296
156388
|
} else {
|
|
156297
|
-
insert->table_index = 0;
|
|
156298
|
-
insert->return_chunk = false;
|
|
156299
156389
|
D_ASSERT(result.types.size() == result.names.size());
|
|
156300
156390
|
result.plan = move(insert);
|
|
156301
156391
|
this->allow_stream_result = false;
|
|
@@ -156750,6 +156840,8 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log
|
|
|
156750
156840
|
}
|
|
156751
156841
|
// for index updates we always turn any update into an insert and a delete
|
|
156752
156842
|
// we thus need all the columns to be available, hence we check if the update touches any index columns
|
|
156843
|
+
// If the returning keyword is used, we need access to the whole row in case the user requests it.
|
|
156844
|
+
// Therefore switch the update to a delete and insert.
|
|
156753
156845
|
update.update_is_del_and_insert = false;
|
|
156754
156846
|
table.storage->info->indexes.Scan([&](Index &index) {
|
|
156755
156847
|
if (index.IndexIsUpdated(update.columns)) {
|
|
@@ -156767,8 +156859,9 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log
|
|
|
156767
156859
|
}
|
|
156768
156860
|
}
|
|
156769
156861
|
|
|
156770
|
-
if (update.update_is_del_and_insert) {
|
|
156771
|
-
// the update updates a column required by an index
|
|
156862
|
+
if (update.update_is_del_and_insert || update.return_chunk) {
|
|
156863
|
+
// the update updates a column required by an index or requires returning the updated rows,
|
|
156864
|
+
// push projections for all columns
|
|
156772
156865
|
unordered_set<column_t> all_columns;
|
|
156773
156866
|
for (idx_t i = 0; i < table.storage->column_definitions.size(); i++) {
|
|
156774
156867
|
all_columns.insert(i);
|
|
@@ -156806,6 +156899,11 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
|
|
|
156806
156899
|
this->read_only = false;
|
|
156807
156900
|
}
|
|
156808
156901
|
auto update = make_unique<LogicalUpdate>(table);
|
|
156902
|
+
|
|
156903
|
+
// set return_chunk boolean early because it needs uses update_is_del_and_insert logic
|
|
156904
|
+
if (!stmt.returning_list.empty()) {
|
|
156905
|
+
update->return_chunk = true;
|
|
156906
|
+
}
|
|
156809
156907
|
// bind the default values
|
|
156810
156908
|
BindDefaultValues(table->columns, update->bound_defaults);
|
|
156811
156909
|
|
|
@@ -156824,6 +156922,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
|
|
|
156824
156922
|
|
|
156825
156923
|
auto proj_index = GenerateTableIndex();
|
|
156826
156924
|
vector<unique_ptr<Expression>> projection_expressions;
|
|
156925
|
+
|
|
156827
156926
|
for (idx_t i = 0; i < stmt.columns.size(); i++) {
|
|
156828
156927
|
auto &colname = stmt.columns[i];
|
|
156829
156928
|
auto &expr = stmt.expressions[i];
|
|
@@ -156849,6 +156948,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
|
|
|
156849
156948
|
projection_expressions.push_back(move(bound_expr));
|
|
156850
156949
|
}
|
|
156851
156950
|
}
|
|
156951
|
+
|
|
156852
156952
|
// now create the projection
|
|
156853
156953
|
auto proj = make_unique<LogicalProjection>(proj_index, move(projection_expressions));
|
|
156854
156954
|
proj->AddChild(move(root));
|
|
@@ -156864,10 +156964,21 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
|
|
|
156864
156964
|
// set the projection as child of the update node and finalize the result
|
|
156865
156965
|
update->AddChild(move(proj));
|
|
156866
156966
|
|
|
156867
|
-
|
|
156868
|
-
|
|
156869
|
-
|
|
156870
|
-
|
|
156967
|
+
if (!stmt.returning_list.empty()) {
|
|
156968
|
+
auto update_table_index = GenerateTableIndex();
|
|
156969
|
+
update->table_index = update_table_index;
|
|
156970
|
+
unique_ptr<LogicalOperator> update_as_logicaloperator = move(update);
|
|
156971
|
+
|
|
156972
|
+
return BindReturning(move(stmt.returning_list), table, update_table_index, move(update_as_logicaloperator),
|
|
156973
|
+
move(result));
|
|
156974
|
+
|
|
156975
|
+
} else {
|
|
156976
|
+
update->table_index = 0;
|
|
156977
|
+
result.names = {"Count"};
|
|
156978
|
+
result.types = {LogicalType::BIGINT};
|
|
156979
|
+
result.plan = move(update);
|
|
156980
|
+
this->allow_stream_result = false;
|
|
156981
|
+
}
|
|
156871
156982
|
return result;
|
|
156872
156983
|
}
|
|
156873
156984
|
|
|
@@ -158130,6 +158241,7 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
|
|
|
158130
158241
|
|
|
158131
158242
|
|
|
158132
158243
|
|
|
158244
|
+
|
|
158133
158245
|
#include <algorithm>
|
|
158134
158246
|
|
|
158135
158247
|
|
|
@@ -158498,6 +158610,53 @@ string Binder::FormatErrorRecursive(idx_t query_location, const string &message,
|
|
|
158498
158610
|
return context.FormatErrorRecursive(message, values);
|
|
158499
158611
|
}
|
|
158500
158612
|
|
|
158613
|
+
BoundStatement Binder::BindReturning(vector<unique_ptr<ParsedExpression>> returning_list, TableCatalogEntry *table,
|
|
158614
|
+
idx_t update_table_index, unique_ptr<LogicalOperator> child_operator,
|
|
158615
|
+
BoundStatement result) {
|
|
158616
|
+
|
|
158617
|
+
vector<LogicalType> types;
|
|
158618
|
+
vector<std::string> names;
|
|
158619
|
+
|
|
158620
|
+
auto binder = Binder::CreateBinder(context);
|
|
158621
|
+
|
|
158622
|
+
for (auto &col : table->columns) {
|
|
158623
|
+
names.push_back(col.name);
|
|
158624
|
+
types.push_back(col.type);
|
|
158625
|
+
}
|
|
158626
|
+
|
|
158627
|
+
binder->bind_context.AddGenericBinding(update_table_index, table->name, names, types);
|
|
158628
|
+
ReturningBinder returning_binder(*binder, context);
|
|
158629
|
+
|
|
158630
|
+
vector<unique_ptr<Expression>> projection_expressions;
|
|
158631
|
+
LogicalType result_type;
|
|
158632
|
+
for (auto &returning_expr : returning_list) {
|
|
158633
|
+
auto expr_type = returning_expr->GetExpressionType();
|
|
158634
|
+
if (expr_type == ExpressionType::STAR) {
|
|
158635
|
+
auto generated_star_list = vector<unique_ptr<ParsedExpression>>();
|
|
158636
|
+
binder->bind_context.GenerateAllColumnExpressions((StarExpression &)*returning_expr, generated_star_list);
|
|
158637
|
+
|
|
158638
|
+
for (auto &star_column : generated_star_list) {
|
|
158639
|
+
auto star_expr = returning_binder.Bind(star_column, &result_type);
|
|
158640
|
+
result.types.push_back(result_type);
|
|
158641
|
+
result.names.push_back(star_expr->GetName());
|
|
158642
|
+
projection_expressions.push_back(move(star_expr));
|
|
158643
|
+
}
|
|
158644
|
+
} else {
|
|
158645
|
+
auto expr = returning_binder.Bind(returning_expr, &result_type);
|
|
158646
|
+
result.names.push_back(expr->GetName());
|
|
158647
|
+
result.types.push_back(result_type);
|
|
158648
|
+
projection_expressions.push_back(move(expr));
|
|
158649
|
+
}
|
|
158650
|
+
}
|
|
158651
|
+
|
|
158652
|
+
auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(projection_expressions));
|
|
158653
|
+
projection->AddChild(move(child_operator));
|
|
158654
|
+
D_ASSERT(result.types.size() == result.names.size());
|
|
158655
|
+
result.plan = move(projection);
|
|
158656
|
+
this->allow_stream_result = true;
|
|
158657
|
+
return result;
|
|
158658
|
+
}
|
|
158659
|
+
|
|
158501
158660
|
} // namespace duckdb
|
|
158502
158661
|
|
|
158503
158662
|
|
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.3.3-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "a8cf83273"
|
|
15
|
+
#define DUCKDB_VERSION "v0.3.3-dev1251"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -13542,6 +13542,9 @@ private:
|
|
|
13542
13542
|
BoundStatement Bind(ExportStatement &stmt);
|
|
13543
13543
|
BoundStatement Bind(SetStatement &stmt);
|
|
13544
13544
|
BoundStatement Bind(LoadStatement &stmt);
|
|
13545
|
+
BoundStatement BindReturning(vector<unique_ptr<ParsedExpression>> returning_list, TableCatalogEntry *table,
|
|
13546
|
+
idx_t update_table_index, unique_ptr<LogicalOperator> child_operator,
|
|
13547
|
+
BoundStatement result);
|
|
13545
13548
|
|
|
13546
13549
|
unique_ptr<QueryNode> BindTableMacro(FunctionExpression &function, TableMacroCatalogEntry *macro_func, idx_t depth);
|
|
13547
13550
|
|