duckdb 0.7.2-dev402.0 → 0.7.2-dev586.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/binding.gyp +9 -9
- package/package.json +1 -1
- package/src/duckdb/extension/parquet/include/parquet_timestamp.hpp +0 -1
- package/src/duckdb/extension/parquet/parquet-extension.cpp +1 -0
- package/src/duckdb/extension/parquet/parquet_timestamp.cpp +8 -6
- package/src/duckdb/src/catalog/catalog.cpp +13 -0
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +2 -21
- package/src/duckdb/src/catalog/catalog_entry/type_catalog_entry.cpp +8 -2
- package/src/duckdb/src/catalog/catalog_set.cpp +1 -0
- package/src/duckdb/src/common/arrow/arrow_appender.cpp +48 -4
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +1 -1
- package/src/duckdb/src/common/field_writer.cpp +1 -0
- package/src/duckdb/src/common/serializer/buffered_deserializer.cpp +4 -0
- package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +15 -2
- package/src/duckdb/src/common/types.cpp +136 -53
- package/src/duckdb/src/execution/operator/schema/physical_create_type.cpp +20 -40
- package/src/duckdb/src/execution/physical_plan/plan_aggregate.cpp +9 -1
- package/src/duckdb/src/execution/physical_plan/plan_distinct.cpp +5 -8
- package/src/duckdb/src/function/aggregate/distributive/bool.cpp +2 -0
- package/src/duckdb/src/function/aggregate/distributive/count.cpp +1 -0
- package/src/duckdb/src/function/aggregate/distributive/minmax.cpp +2 -0
- package/src/duckdb/src/function/aggregate/distributive/sum.cpp +8 -0
- package/src/duckdb/src/function/aggregate/holistic/quantile.cpp +15 -0
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +42 -11
- package/src/duckdb/src/function/function_binder.cpp +1 -8
- package/src/duckdb/src/function/scalar/date/current.cpp +0 -2
- package/src/duckdb/src/function/table/arrow.cpp +3 -0
- package/src/duckdb/src/function/table/arrow_conversion.cpp +18 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/function/table_function.cpp +11 -11
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +3 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/field_writer.hpp +12 -4
- package/src/duckdb/src/include/duckdb/common/{http_stats.hpp → http_state.hpp} +18 -4
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_deserializer.hpp +4 -2
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +8 -2
- package/src/duckdb/src/include/duckdb/common/serializer.hpp +13 -0
- package/src/duckdb/src/include/duckdb/common/types.hpp +27 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_file_handle.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/physical_plan_generator.hpp +0 -3
- package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +6 -3
- package/src/duckdb/src/include/duckdb/function/function_binder.hpp +3 -6
- package/src/duckdb/src/include/duckdb/function/table/arrow.hpp +12 -1
- package/src/duckdb/src/include/duckdb/function/table_function.hpp +8 -0
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +3 -3
- package/src/duckdb/src/include/duckdb/main/connection_manager.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +1 -0
- package/src/duckdb/src/include/duckdb/optimizer/rule/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/optimizer/rule/ordered_aggregate_optimizer.hpp +24 -0
- package/src/duckdb/src/include/duckdb/parser/expression/function_expression.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/expression/star_expression.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp +6 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -3
- package/src/duckdb/src/include/duckdb/planner/bound_result_modifier.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_aggregate_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp +4 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_distinct.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/checkpoint_manager.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +7 -0
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +1 -1
- package/src/duckdb/src/main/client_context.cpp +30 -32
- package/src/duckdb/src/main/client_data.cpp +7 -6
- package/src/duckdb/src/main/database.cpp +9 -0
- package/src/duckdb/src/main/query_profiler.cpp +17 -15
- package/src/duckdb/src/optimizer/optimizer.cpp +1 -0
- package/src/duckdb/src/optimizer/rule/ordered_aggregate_optimizer.cpp +30 -0
- package/src/duckdb/src/optimizer/rule/regex_optimizations.cpp +9 -2
- package/src/duckdb/src/parser/expression/star_expression.cpp +6 -6
- package/src/duckdb/src/parser/parsed_expression_iterator.cpp +7 -1
- package/src/duckdb/src/parser/transform/expression/transform_columnref.cpp +17 -2
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +45 -40
- package/src/duckdb/src/parser/transform/helpers/transform_groupby.cpp +7 -0
- package/src/duckdb/src/parser/transform/helpers/transform_orderby.cpp +0 -7
- package/src/duckdb/src/parser/transform/statement/transform_rename.cpp +3 -4
- package/src/duckdb/src/planner/bind_context.cpp +2 -25
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +6 -4
- package/src/duckdb/src/planner/binder/expression/bind_lambda.cpp +3 -2
- package/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp +176 -0
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +57 -82
- package/src/duckdb/src/planner/binder/query_node/plan_query_node.cpp +11 -0
- package/src/duckdb/src/planner/binder/statement/bind_delete.cpp +1 -1
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +2 -2
- package/src/duckdb/src/planner/binder/statement/bind_update.cpp +1 -1
- package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +11 -1
- package/src/duckdb/src/planner/binder.cpp +12 -23
- package/src/duckdb/src/planner/bound_result_modifier.cpp +26 -0
- package/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +9 -2
- package/src/duckdb/src/planner/expression_iterator.cpp +5 -0
- package/src/duckdb/src/planner/logical_operator.cpp +4 -2
- package/src/duckdb/src/planner/logical_operator_visitor.cpp +5 -0
- package/src/duckdb/src/planner/operator/logical_distinct.cpp +3 -0
- package/src/duckdb/src/planner/planner.cpp +2 -1
- package/src/duckdb/src/storage/checkpoint_manager.cpp +8 -3
- package/src/duckdb/src/storage/meta_block_reader.cpp +22 -0
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/src/storage/wal_replay.cpp +8 -5
- package/src/duckdb/src/storage/write_ahead_log.cpp +2 -2
- package/src/duckdb/src/transaction/commit_state.cpp +11 -7
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +1 -1
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +8145 -8317
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_optimizer_rule.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_expression.cpp +2 -0
@@ -19,8 +19,7 @@
|
|
19
19
|
#include "duckdb/planner/expression_binder/select_binder.hpp"
|
20
20
|
#include "duckdb/planner/expression_binder/where_binder.hpp"
|
21
21
|
#include "duckdb/planner/query_node/bound_select_node.hpp"
|
22
|
-
#include "duckdb/
|
23
|
-
#include "duckdb/parser/parsed_expression_iterator.hpp"
|
22
|
+
#include "duckdb/parser/expression/conjunction_expression.hpp"
|
24
23
|
|
25
24
|
namespace duckdb {
|
26
25
|
|
@@ -136,31 +135,39 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun
|
|
136
135
|
auto bound_order = make_unique<BoundOrderModifier>();
|
137
136
|
auto &config = DBConfig::GetConfig(context);
|
138
137
|
D_ASSERT(!order.orders.empty());
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
new_orders
|
149
|
-
|
138
|
+
auto &order_binders = order_binder.GetBinders();
|
139
|
+
if (order.orders.size() == 1 && order.orders[0].expression->type == ExpressionType::STAR) {
|
140
|
+
auto star = (StarExpression *)order.orders[0].expression.get();
|
141
|
+
if (star->exclude_list.empty() && star->replace_list.empty() && !star->expr) {
|
142
|
+
// ORDER BY ALL
|
143
|
+
// replace the order list with the all elements in the SELECT list
|
144
|
+
auto order_type = order.orders[0].type;
|
145
|
+
auto null_order = order.orders[0].null_order;
|
146
|
+
|
147
|
+
vector<OrderByNode> new_orders;
|
148
|
+
for (idx_t i = 0; i < order_binder.MaxCount(); i++) {
|
149
|
+
new_orders.emplace_back(order_type, null_order,
|
150
|
+
make_unique<ConstantExpression>(Value::INTEGER(i + 1)));
|
151
|
+
}
|
152
|
+
order.orders = std::move(new_orders);
|
150
153
|
}
|
151
|
-
order.orders = std::move(new_orders);
|
152
154
|
}
|
153
155
|
for (auto &order_node : order.orders) {
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
}
|
156
|
+
vector<unique_ptr<ParsedExpression>> order_list;
|
157
|
+
order_binders[0]->ExpandStarExpression(std::move(order_node.expression), order_list);
|
158
|
+
|
158
159
|
auto type =
|
159
160
|
order_node.type == OrderType::ORDER_DEFAULT ? config.options.default_order_type : order_node.type;
|
160
161
|
auto null_order = order_node.null_order == OrderByNullType::ORDER_DEFAULT
|
161
162
|
? config.options.default_null_order
|
162
163
|
: order_node.null_order;
|
163
|
-
|
164
|
+
for (auto &order_expr : order_list) {
|
165
|
+
auto bound_expr = BindOrderExpression(order_binder, std::move(order_expr));
|
166
|
+
if (!bound_expr) {
|
167
|
+
continue;
|
168
|
+
}
|
169
|
+
bound_order->orders.emplace_back(type, null_order, std::move(bound_expr));
|
170
|
+
}
|
164
171
|
}
|
165
172
|
if (!bound_order->orders.empty()) {
|
166
173
|
bound_modifier = std::move(bound_order);
|
@@ -264,69 +271,6 @@ void Binder::BindModifierTypes(BoundQueryNode &result, const vector<LogicalType>
|
|
264
271
|
}
|
265
272
|
}
|
266
273
|
|
267
|
-
bool Binder::FindStarExpression(ParsedExpression &expr, StarExpression **star) {
|
268
|
-
if (expr.GetExpressionClass() == ExpressionClass::STAR) {
|
269
|
-
auto current_star = (StarExpression *)&expr;
|
270
|
-
if (*star) {
|
271
|
-
// we can have multiple
|
272
|
-
if (!StarExpression::Equal(*star, current_star)) {
|
273
|
-
throw BinderException(
|
274
|
-
FormatError(expr, "Multiple different STAR/COLUMNS in the same expression are not supported"));
|
275
|
-
}
|
276
|
-
return true;
|
277
|
-
}
|
278
|
-
*star = current_star;
|
279
|
-
return true;
|
280
|
-
}
|
281
|
-
bool has_star = false;
|
282
|
-
ParsedExpressionIterator::EnumerateChildren(expr, [&](ParsedExpression &child_expr) {
|
283
|
-
if (FindStarExpression(child_expr, star)) {
|
284
|
-
has_star = true;
|
285
|
-
}
|
286
|
-
});
|
287
|
-
return has_star;
|
288
|
-
}
|
289
|
-
|
290
|
-
void Binder::ReplaceStarExpression(unique_ptr<ParsedExpression> &expr, unique_ptr<ParsedExpression> &replacement) {
|
291
|
-
D_ASSERT(expr);
|
292
|
-
if (expr->GetExpressionClass() == ExpressionClass::STAR) {
|
293
|
-
D_ASSERT(replacement);
|
294
|
-
expr = replacement->Copy();
|
295
|
-
return;
|
296
|
-
}
|
297
|
-
ParsedExpressionIterator::EnumerateChildren(
|
298
|
-
*expr, [&](unique_ptr<ParsedExpression> &child_expr) { ReplaceStarExpression(child_expr, replacement); });
|
299
|
-
}
|
300
|
-
|
301
|
-
void Binder::ExpandStarExpression(unique_ptr<ParsedExpression> expr,
|
302
|
-
vector<unique_ptr<ParsedExpression>> &new_select_list) {
|
303
|
-
StarExpression *star = nullptr;
|
304
|
-
if (!FindStarExpression(*expr, &star)) {
|
305
|
-
// no star expression: add it as-is
|
306
|
-
D_ASSERT(!star);
|
307
|
-
new_select_list.push_back(std::move(expr));
|
308
|
-
return;
|
309
|
-
}
|
310
|
-
D_ASSERT(star);
|
311
|
-
vector<unique_ptr<ParsedExpression>> star_list;
|
312
|
-
// we have star expressions! expand the list of star expressions
|
313
|
-
bind_context.GenerateAllColumnExpressions(*star, star_list);
|
314
|
-
|
315
|
-
// now perform the replacement
|
316
|
-
for (idx_t i = 0; i < star_list.size(); i++) {
|
317
|
-
auto new_expr = expr->Copy();
|
318
|
-
ReplaceStarExpression(new_expr, star_list[i]);
|
319
|
-
new_select_list.push_back(std::move(new_expr));
|
320
|
-
}
|
321
|
-
}
|
322
|
-
|
323
|
-
void Binder::ExpandStarExpressions(vector<unique_ptr<ParsedExpression>> &select_list,
|
324
|
-
vector<unique_ptr<ParsedExpression>> &new_select_list) {
|
325
|
-
for (auto &select_element : select_list) {
|
326
|
-
ExpandStarExpression(std::move(select_element), new_select_list);
|
327
|
-
}
|
328
|
-
}
|
329
|
-
|
330
274
|
unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
331
275
|
D_ASSERT(statement.from_table);
|
332
276
|
// first bind the FROM table statement
|
@@ -335,6 +279,34 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
335
279
|
return BindSelectNode(statement, std::move(from_table));
|
336
280
|
}
|
337
281
|
|
282
|
+
void Binder::BindWhereStarExpression(unique_ptr<ParsedExpression> &expr) {
|
283
|
+
// expand any expressions in the upper AND recursively
|
284
|
+
if (expr->type == ExpressionType::CONJUNCTION_AND) {
|
285
|
+
auto &conj = (ConjunctionExpression &)*expr;
|
286
|
+
for (auto &child : conj.children) {
|
287
|
+
BindWhereStarExpression(child);
|
288
|
+
}
|
289
|
+
return;
|
290
|
+
}
|
291
|
+
if (expr->type == ExpressionType::STAR) {
|
292
|
+
auto &star = (StarExpression &)*expr;
|
293
|
+
if (!star.columns) {
|
294
|
+
throw ParserException("STAR expression is not allowed in the WHERE clause. Use COLUMNS(*) instead.");
|
295
|
+
}
|
296
|
+
}
|
297
|
+
// expand the stars for this expression
|
298
|
+
vector<unique_ptr<ParsedExpression>> new_conditions;
|
299
|
+
ExpandStarExpression(std::move(expr), new_conditions);
|
300
|
+
|
301
|
+
// set up an AND conjunction between the expanded conditions
|
302
|
+
expr = std::move(new_conditions[0]);
|
303
|
+
for (idx_t i = 1; i < new_conditions.size(); i++) {
|
304
|
+
auto and_conj = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_AND, std::move(expr),
|
305
|
+
std::move(new_conditions[i]));
|
306
|
+
expr = std::move(and_conj);
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
338
310
|
unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_ptr<BoundTableRef> from_table) {
|
339
311
|
D_ASSERT(from_table);
|
340
312
|
D_ASSERT(!statement.from_table);
|
@@ -381,6 +353,9 @@ unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_
|
|
381
353
|
// first visit the WHERE clause
|
382
354
|
// the WHERE clause happens before the GROUP BY, PROJECTION or HAVING clauses
|
383
355
|
if (statement.where_clause) {
|
356
|
+
// bind any star expressions in the WHERE clause
|
357
|
+
BindWhereStarExpression(statement.where_clause);
|
358
|
+
|
384
359
|
ColumnAliasBinder alias_binder(*result, alias_map);
|
385
360
|
WhereBinder where_binder(*this, context, &alias_binder);
|
386
361
|
unique_ptr<ParsedExpression> condition = std::move(statement.where_clause);
|
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "duckdb/planner/operator/logical_limit.hpp"
|
5
5
|
#include "duckdb/planner/operator/logical_limit_percent.hpp"
|
6
6
|
#include "duckdb/planner/operator/logical_order.hpp"
|
7
|
+
#include "duckdb/planner/bound_result_modifier.hpp"
|
7
8
|
|
8
9
|
namespace duckdb {
|
9
10
|
|
@@ -20,6 +21,16 @@ unique_ptr<LogicalOperator> Binder::VisitQueryNode(BoundQueryNode &node, unique_
|
|
20
21
|
}
|
21
22
|
case ResultModifierType::ORDER_MODIFIER: {
|
22
23
|
auto &bound = (BoundOrderModifier &)*mod;
|
24
|
+
if (root->type == LogicalOperatorType::LOGICAL_DISTINCT) {
|
25
|
+
auto &distinct = (LogicalDistinct &)*root;
|
26
|
+
if (!distinct.distinct_targets.empty()) {
|
27
|
+
auto order_by = make_unique<BoundOrderModifier>();
|
28
|
+
for (auto &order_node : bound.orders) {
|
29
|
+
order_by->orders.push_back(order_node.Copy());
|
30
|
+
}
|
31
|
+
distinct.order_by = std::move(order_by);
|
32
|
+
}
|
33
|
+
}
|
23
34
|
auto order = make_unique<LogicalOrder>(std::move(bound.orders));
|
24
35
|
order->AddChild(std::move(root));
|
25
36
|
root = std::move(order);
|
@@ -83,7 +83,7 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) {
|
|
83
83
|
del->table_index = update_table_index;
|
84
84
|
|
85
85
|
unique_ptr<LogicalOperator> del_as_logicaloperator = std::move(del);
|
86
|
-
return BindReturning(std::move(stmt.returning_list), table, update_table_index,
|
86
|
+
return BindReturning(std::move(stmt.returning_list), table, stmt.table->alias, update_table_index,
|
87
87
|
std::move(del_as_logicaloperator), std::move(result));
|
88
88
|
}
|
89
89
|
result.plan = std::move(del);
|
@@ -505,8 +505,8 @@ BoundStatement Binder::Bind(InsertStatement &stmt) {
|
|
505
505
|
insert->table_index = insert_table_index;
|
506
506
|
unique_ptr<LogicalOperator> index_as_logicaloperator = std::move(insert);
|
507
507
|
|
508
|
-
return BindReturning(std::move(stmt.returning_list), table,
|
509
|
-
std::move(index_as_logicaloperator), std::move(result));
|
508
|
+
return BindReturning(std::move(stmt.returning_list), table, stmt.table_ref ? stmt.table_ref->alias : string(),
|
509
|
+
insert_table_index, std::move(index_as_logicaloperator), std::move(result));
|
510
510
|
}
|
511
511
|
|
512
512
|
D_ASSERT(result.types.size() == result.names.size());
|
@@ -251,7 +251,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
|
|
251
251
|
if (!stmt.returning_list.empty()) {
|
252
252
|
unique_ptr<LogicalOperator> update_as_logicaloperator = std::move(update);
|
253
253
|
|
254
|
-
return BindReturning(std::move(stmt.returning_list), table, update_table_index,
|
254
|
+
return BindReturning(std::move(stmt.returning_list), table, stmt.table->alias, update_table_index,
|
255
255
|
std::move(update_as_logicaloperator), std::move(result));
|
256
256
|
}
|
257
257
|
|
@@ -126,9 +126,18 @@ Binder::BindTableFunctionInternal(TableFunction &table_function, const string &f
|
|
126
126
|
unique_ptr<FunctionData> bind_data;
|
127
127
|
vector<LogicalType> return_types;
|
128
128
|
vector<string> return_names;
|
129
|
-
if (table_function.bind) {
|
129
|
+
if (table_function.bind || table_function.bind_replace) {
|
130
130
|
TableFunctionBindInput bind_input(parameters, named_parameters, input_table_types, input_table_names,
|
131
131
|
table_function.function_info.get());
|
132
|
+
if (table_function.bind_replace) {
|
133
|
+
auto new_plan = table_function.bind_replace(context, bind_input);
|
134
|
+
if (new_plan != nullptr) {
|
135
|
+
return CreatePlan(*Bind(*new_plan));
|
136
|
+
} else if (!table_function.bind) {
|
137
|
+
throw BinderException("Failed to bind \"%s\": nullptr returned from bind_replace without bind function",
|
138
|
+
table_function.name);
|
139
|
+
}
|
140
|
+
}
|
132
141
|
bind_data = table_function.bind(context, bind_input, return_types, return_names);
|
133
142
|
if (table_function.name == "pandas_scan" || table_function.name == "arrow_scan") {
|
134
143
|
auto arrow_bind = (PyTableFunctionData *)bind_data.get();
|
@@ -153,6 +162,7 @@ Binder::BindTableFunctionInternal(TableFunction &table_function, const string &f
|
|
153
162
|
return_names[i] = "C" + to_string(i);
|
154
163
|
}
|
155
164
|
}
|
165
|
+
|
156
166
|
auto get = make_unique<LogicalGet>(bind_index, table_function, std::move(bind_data), return_types, return_names);
|
157
167
|
get->parameters = parameters;
|
158
168
|
get->named_parameters = named_parameters;
|
@@ -438,8 +438,8 @@ void VerifyNotExcluded(ParsedExpression &expr) {
|
|
438
438
|
}
|
439
439
|
|
440
440
|
BoundStatement Binder::BindReturning(vector<unique_ptr<ParsedExpression>> returning_list, TableCatalogEntry *table,
|
441
|
-
|
442
|
-
BoundStatement result) {
|
441
|
+
const string &alias, idx_t update_table_index,
|
442
|
+
unique_ptr<LogicalOperator> child_operator, BoundStatement result) {
|
443
443
|
|
444
444
|
vector<LogicalType> types;
|
445
445
|
vector<std::string> names;
|
@@ -457,31 +457,20 @@ BoundStatement Binder::BindReturning(vector<unique_ptr<ParsedExpression>> return
|
|
457
457
|
column_count++;
|
458
458
|
}
|
459
459
|
|
460
|
-
binder->bind_context.AddBaseTable(update_table_index, table->name, names, types,
|
460
|
+
binder->bind_context.AddBaseTable(update_table_index, alias.empty() ? table->name : alias, names, types,
|
461
|
+
bound_columns, table, false);
|
461
462
|
ReturningBinder returning_binder(*binder, context);
|
462
463
|
|
463
464
|
vector<unique_ptr<Expression>> projection_expressions;
|
464
465
|
LogicalType result_type;
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
result.types.push_back(result_type);
|
474
|
-
result.names.push_back(star_expr->GetName());
|
475
|
-
projection_expressions.push_back(std::move(star_expr));
|
476
|
-
}
|
477
|
-
} else {
|
478
|
-
// TODO: accept 'excluded' in the RETURNING clause
|
479
|
-
VerifyNotExcluded(*returning_expr);
|
480
|
-
auto expr = returning_binder.Bind(returning_expr, &result_type);
|
481
|
-
result.names.push_back(expr->GetName());
|
482
|
-
result.types.push_back(result_type);
|
483
|
-
projection_expressions.push_back(std::move(expr));
|
484
|
-
}
|
466
|
+
vector<unique_ptr<ParsedExpression>> new_returning_list;
|
467
|
+
binder->ExpandStarExpressions(returning_list, new_returning_list);
|
468
|
+
for (auto &returning_expr : new_returning_list) {
|
469
|
+
VerifyNotExcluded(*returning_expr);
|
470
|
+
auto expr = returning_binder.Bind(returning_expr, &result_type);
|
471
|
+
result.names.push_back(expr->GetName());
|
472
|
+
result.types.push_back(result_type);
|
473
|
+
projection_expressions.push_back(std::move(expr));
|
485
474
|
}
|
486
475
|
|
487
476
|
auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), std::move(projection_expressions));
|
@@ -80,6 +80,32 @@ BoundOrderByNode BoundOrderByNode::Deserialize(Deserializer &source, PlanDeseria
|
|
80
80
|
return BoundOrderByNode(type, null_order, std::move(expression));
|
81
81
|
}
|
82
82
|
|
83
|
+
unique_ptr<BoundOrderModifier> BoundOrderModifier::Copy() const {
|
84
|
+
auto result = make_unique<BoundOrderModifier>();
|
85
|
+
for (auto &order : orders) {
|
86
|
+
result->orders.push_back(order.Copy());
|
87
|
+
}
|
88
|
+
return result;
|
89
|
+
}
|
90
|
+
|
91
|
+
bool BoundOrderModifier::Equals(const BoundOrderModifier *left, const BoundOrderModifier *right) {
|
92
|
+
if (left == right) {
|
93
|
+
return true;
|
94
|
+
}
|
95
|
+
if (!left || !right) {
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
if (left->orders.size() != right->orders.size()) {
|
99
|
+
return false;
|
100
|
+
}
|
101
|
+
for (idx_t i = 0; i < left->orders.size(); i++) {
|
102
|
+
if (!left->orders[i].Equals(right->orders[i])) {
|
103
|
+
return false;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
return true;
|
107
|
+
}
|
108
|
+
|
83
109
|
BoundLimitModifier::BoundLimitModifier() : BoundResultModifier(ResultModifierType::LIMIT_MODIFIER) {
|
84
110
|
}
|
85
111
|
|
@@ -19,8 +19,8 @@ BoundAggregateExpression::BoundAggregateExpression(AggregateFunction function, v
|
|
19
19
|
}
|
20
20
|
|
21
21
|
string BoundAggregateExpression::ToString() const {
|
22
|
-
return FunctionExpression::ToString<BoundAggregateExpression, Expression
|
23
|
-
|
22
|
+
return FunctionExpression::ToString<BoundAggregateExpression, Expression, BoundOrderModifier>(
|
23
|
+
*this, string(), function.name, false, IsDistinct(), filter.get(), order_bys.get());
|
24
24
|
}
|
25
25
|
|
26
26
|
hash_t BoundAggregateExpression::Hash() const {
|
@@ -55,6 +55,9 @@ bool BoundAggregateExpression::Equals(const BaseExpression *other_p) const {
|
|
55
55
|
if (!FunctionData::Equals(bind_info.get(), other->bind_info.get())) {
|
56
56
|
return false;
|
57
57
|
}
|
58
|
+
if (!BoundOrderModifier::Equals(order_bys.get(), other->order_bys.get())) {
|
59
|
+
return false;
|
60
|
+
}
|
58
61
|
return true;
|
59
62
|
}
|
60
63
|
|
@@ -74,12 +77,16 @@ unique_ptr<Expression> BoundAggregateExpression::Copy() {
|
|
74
77
|
auto copy = make_unique<BoundAggregateExpression>(function, std::move(new_children), std::move(new_filter),
|
75
78
|
std::move(new_bind_info), aggr_type);
|
76
79
|
copy->CopyProperties(*this);
|
80
|
+
copy->order_bys = order_bys ? order_bys->Copy() : nullptr;
|
77
81
|
return std::move(copy);
|
78
82
|
}
|
79
83
|
|
80
84
|
void BoundAggregateExpression::Serialize(FieldWriter &writer) const {
|
81
85
|
writer.WriteField(IsDistinct());
|
82
86
|
writer.WriteOptional(filter);
|
87
|
+
if (order_bys) {
|
88
|
+
throw NotImplementedException("Serialization of ORDER BY aggregate not yet supported");
|
89
|
+
}
|
83
90
|
FunctionSerializer::Serialize<AggregateFunction>(writer, function, return_type, children, bind_info.get());
|
84
91
|
}
|
85
92
|
|
@@ -29,6 +29,11 @@ void ExpressionIterator::EnumerateChildren(Expression &expr,
|
|
29
29
|
if (aggr_expr.filter) {
|
30
30
|
callback(aggr_expr.filter);
|
31
31
|
}
|
32
|
+
if (aggr_expr.order_bys) {
|
33
|
+
for (auto &order : aggr_expr.order_bys->orders) {
|
34
|
+
callback(order.expression);
|
35
|
+
}
|
36
|
+
}
|
32
37
|
break;
|
33
38
|
}
|
34
39
|
case ExpressionClass::BOUND_BETWEEN: {
|
@@ -128,6 +128,8 @@ void LogicalOperator::Verify(ClientContext &context) {
|
|
128
128
|
continue;
|
129
129
|
}
|
130
130
|
BufferedSerializer serializer;
|
131
|
+
// We are serializing a query plan
|
132
|
+
serializer.is_query_plan = true;
|
131
133
|
try {
|
132
134
|
expressions[expr_idx]->Serialize(serializer);
|
133
135
|
} catch (NotImplementedException &ex) {
|
@@ -136,7 +138,7 @@ void LogicalOperator::Verify(ClientContext &context) {
|
|
136
138
|
}
|
137
139
|
|
138
140
|
auto data = serializer.GetData();
|
139
|
-
auto deserializer =
|
141
|
+
auto deserializer = BufferedContextDeserializer(context, data.data.get(), data.size);
|
140
142
|
|
141
143
|
PlanDeserializationState state(context);
|
142
144
|
auto deserialized_expression = Expression::Deserialize(deserializer, state);
|
@@ -371,7 +373,7 @@ unique_ptr<LogicalOperator> LogicalOperator::Copy(ClientContext &context) const
|
|
371
373
|
std::string(ex.what()));
|
372
374
|
}
|
373
375
|
auto data = logical_op_serializer.GetData();
|
374
|
-
auto logical_op_deserializer =
|
376
|
+
auto logical_op_deserializer = BufferedContextDeserializer(context, data.data.get(), data.size);
|
375
377
|
PlanDeserializationState state(context);
|
376
378
|
auto op_copy = LogicalOperator::Deserialize(logical_op_deserializer, state);
|
377
379
|
return op_copy;
|
@@ -48,6 +48,11 @@ void LogicalOperatorVisitor::EnumerateExpressions(LogicalOperator &op,
|
|
48
48
|
for (auto &target : distinct.distinct_targets) {
|
49
49
|
callback(&target);
|
50
50
|
}
|
51
|
+
if (distinct.order_by) {
|
52
|
+
for (auto &order : distinct.order_by->orders) {
|
53
|
+
callback(&order.expression);
|
54
|
+
}
|
55
|
+
}
|
51
56
|
break;
|
52
57
|
}
|
53
58
|
case LogicalOperatorType::LOGICAL_INSERT: {
|
@@ -15,6 +15,9 @@ string LogicalDistinct::ParamsToString() const {
|
|
15
15
|
}
|
16
16
|
void LogicalDistinct::Serialize(FieldWriter &writer) const {
|
17
17
|
writer.WriteSerializableList(distinct_targets);
|
18
|
+
if (order_by) {
|
19
|
+
throw NotImplementedException("Serializing ORDER BY not yet supported");
|
20
|
+
}
|
18
21
|
}
|
19
22
|
|
20
23
|
unique_ptr<LogicalOperator> LogicalDistinct::Deserialize(LogicalDeserializationState &state, FieldReader &reader) {
|
@@ -184,6 +184,7 @@ void Planner::VerifyPlan(ClientContext &context, unique_ptr<LogicalOperator> &op
|
|
184
184
|
}
|
185
185
|
|
186
186
|
BufferedSerializer serializer;
|
187
|
+
serializer.is_query_plan = true;
|
187
188
|
try {
|
188
189
|
op->Serialize(serializer);
|
189
190
|
} catch (NotImplementedException &ex) {
|
@@ -191,7 +192,7 @@ void Planner::VerifyPlan(ClientContext &context, unique_ptr<LogicalOperator> &op
|
|
191
192
|
return;
|
192
193
|
}
|
193
194
|
auto data = serializer.GetData();
|
194
|
-
auto deserializer =
|
195
|
+
auto deserializer = BufferedContextDeserializer(context, data.data.get(), data.size);
|
195
196
|
|
196
197
|
PlanDeserializationState state(context);
|
197
198
|
auto new_plan = LogicalOperator::Deserialize(deserializer, state);
|
@@ -128,6 +128,8 @@ void SingleFileCheckpointReader::LoadFromStorage() {
|
|
128
128
|
con.BeginTransaction();
|
129
129
|
// create the MetaBlockReader to read from the storage
|
130
130
|
MetaBlockReader reader(block_manager, meta_block);
|
131
|
+
reader.SetCatalog(&catalog.GetAttached().GetCatalog());
|
132
|
+
reader.SetContext(con.context.get());
|
131
133
|
LoadCheckpoint(*con.context, reader);
|
132
134
|
con.Commit();
|
133
135
|
}
|
@@ -395,13 +397,16 @@ void CheckpointReader::ReadIndex(ClientContext &context, MetaBlockReader &reader
|
|
395
397
|
//===--------------------------------------------------------------------===//
|
396
398
|
// Custom Types
|
397
399
|
//===--------------------------------------------------------------------===//
|
398
|
-
void CheckpointWriter::WriteType(TypeCatalogEntry &
|
399
|
-
|
400
|
+
void CheckpointWriter::WriteType(TypeCatalogEntry &type) {
|
401
|
+
type.Serialize(GetMetaBlockWriter());
|
400
402
|
}
|
401
403
|
|
402
404
|
void CheckpointReader::ReadType(ClientContext &context, MetaBlockReader &reader) {
|
403
405
|
auto info = TypeCatalogEntry::Deserialize(reader);
|
404
|
-
catalog.CreateType(context, info.get());
|
406
|
+
auto catalog_entry = (TypeCatalogEntry *)catalog.CreateType(context, info.get());
|
407
|
+
if (info->type.id() == LogicalTypeId::ENUM) {
|
408
|
+
EnumType::SetCatalog(info->type, catalog_entry);
|
409
|
+
}
|
405
410
|
}
|
406
411
|
|
407
412
|
//===--------------------------------------------------------------------===//
|
@@ -1,5 +1,7 @@
|
|
1
1
|
#include "duckdb/storage/meta_block_reader.hpp"
|
2
2
|
#include "duckdb/storage/buffer_manager.hpp"
|
3
|
+
#include "duckdb/main/connection_manager.hpp"
|
4
|
+
#include "duckdb/main/database.hpp"
|
3
5
|
|
4
6
|
#include <cstring>
|
5
7
|
|
@@ -34,6 +36,16 @@ void MetaBlockReader::ReadData(data_ptr_t buffer, idx_t read_size) {
|
|
34
36
|
offset += read_size;
|
35
37
|
}
|
36
38
|
|
39
|
+
ClientContext &MetaBlockReader::GetContext() {
|
40
|
+
if (!context) {
|
41
|
+
throw InternalException("Meta Block Reader is missing context");
|
42
|
+
}
|
43
|
+
return *context;
|
44
|
+
}
|
45
|
+
Catalog *MetaBlockReader::GetCatalog() {
|
46
|
+
return catalog;
|
47
|
+
}
|
48
|
+
|
37
49
|
void MetaBlockReader::ReadNewBlock(block_id_t id) {
|
38
50
|
auto &buffer_manager = block_manager.buffer_manager;
|
39
51
|
|
@@ -52,4 +64,14 @@ void MetaBlockReader::ReadNewBlock(block_id_t id) {
|
|
52
64
|
offset = sizeof(block_id_t);
|
53
65
|
}
|
54
66
|
|
67
|
+
void MetaBlockReader::SetCatalog(Catalog *catalog_p) {
|
68
|
+
D_ASSERT(!catalog);
|
69
|
+
catalog = catalog_p;
|
70
|
+
}
|
71
|
+
|
72
|
+
void MetaBlockReader::SetContext(ClientContext *context_p) {
|
73
|
+
D_ASSERT(!context);
|
74
|
+
context = context_p;
|
75
|
+
}
|
76
|
+
|
55
77
|
} // namespace duckdb
|
@@ -24,17 +24,19 @@
|
|
24
24
|
namespace duckdb {
|
25
25
|
|
26
26
|
bool WriteAheadLog::Replay(AttachedDatabase &database, string &path) {
|
27
|
-
|
27
|
+
Connection con(database.GetDatabase());
|
28
|
+
auto initial_reader = make_unique<BufferedFileReader>(FileSystem::Get(database), path.c_str(), con.context.get());
|
28
29
|
if (initial_reader->Finished()) {
|
29
30
|
// WAL is empty
|
30
31
|
return false;
|
31
32
|
}
|
32
|
-
|
33
|
+
|
33
34
|
con.BeginTransaction();
|
34
35
|
|
35
36
|
// first deserialize the WAL to look for a checkpoint flag
|
36
37
|
// if there is a checkpoint flag, we might have already flushed the contents of the WAL to disk
|
37
38
|
ReplayState checkpoint_state(database, *con.context, *initial_reader);
|
39
|
+
initial_reader->catalog = &checkpoint_state.catalog;
|
38
40
|
checkpoint_state.deserialize_only = true;
|
39
41
|
try {
|
40
42
|
while (true) {
|
@@ -70,7 +72,8 @@ bool WriteAheadLog::Replay(AttachedDatabase &database, string &path) {
|
|
70
72
|
}
|
71
73
|
|
72
74
|
// we need to recover from the WAL: actually set up the replay state
|
73
|
-
BufferedFileReader reader(FileSystem::Get(database), path.c_str());
|
75
|
+
BufferedFileReader reader(FileSystem::Get(database), path.c_str(), con.context.get());
|
76
|
+
reader.catalog = &checkpoint_state.catalog;
|
74
77
|
ReplayState state(database, *con.context, reader);
|
75
78
|
|
76
79
|
// replay the WAL
|
@@ -192,6 +195,7 @@ void ReplayState::ReplayEntry(WALType entry_type) {
|
|
192
195
|
// Replay Table
|
193
196
|
//===--------------------------------------------------------------------===//
|
194
197
|
void ReplayState::ReplayCreateTable() {
|
198
|
+
|
195
199
|
auto info = TableCatalogEntry::Deserialize(source, context);
|
196
200
|
if (deserialize_only) {
|
197
201
|
return;
|
@@ -278,10 +282,9 @@ void ReplayState::ReplayDropSchema() {
|
|
278
282
|
//===--------------------------------------------------------------------===//
|
279
283
|
void ReplayState::ReplayCreateType() {
|
280
284
|
auto info = TypeCatalogEntry::Deserialize(source);
|
281
|
-
if (
|
285
|
+
if (Catalog::TypeExists(context, info->catalog, info->schema, info->name)) {
|
282
286
|
return;
|
283
287
|
}
|
284
|
-
|
285
288
|
catalog.CreateType(context, info.get());
|
286
289
|
}
|
287
290
|
|
@@ -281,12 +281,12 @@ void WriteAheadLog::WriteUpdate(DataChunk &chunk, const vector<column_t> &column
|
|
281
281
|
//===--------------------------------------------------------------------===//
|
282
282
|
// Write ALTER Statement
|
283
283
|
//===--------------------------------------------------------------------===//
|
284
|
-
void WriteAheadLog::WriteAlter(
|
284
|
+
void WriteAheadLog::WriteAlter(data_ptr_t ptr, idx_t data_size) {
|
285
285
|
if (skip_writing) {
|
286
286
|
return;
|
287
287
|
}
|
288
288
|
writer->Write<WALType>(WALType::ALTER_INFO);
|
289
|
-
|
289
|
+
writer->WriteData(ptr, data_size);
|
290
290
|
}
|
291
291
|
|
292
292
|
//===--------------------------------------------------------------------===//
|
@@ -46,12 +46,16 @@ void CommitState::WriteCatalogEntry(CatalogEntry *entry, data_ptr_t dataptr) {
|
|
46
46
|
// ALTER TABLE statement, read the extra data after the entry
|
47
47
|
auto extra_data_size = Load<idx_t>(dataptr);
|
48
48
|
auto extra_data = (data_ptr_t)(dataptr + sizeof(idx_t));
|
49
|
-
|
49
|
+
|
50
50
|
BufferedDeserializer source(extra_data, extra_data_size);
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
string column_name = source.Read<string>();
|
52
|
+
|
53
|
+
if (!column_name.empty()) {
|
54
|
+
// write the alter table in the log
|
55
|
+
table_entry->CommitAlter(column_name);
|
56
|
+
}
|
57
|
+
|
58
|
+
log->WriteAlter(source.ptr, source.endptr - source.ptr);
|
55
59
|
} else {
|
56
60
|
// CREATE TABLE statement
|
57
61
|
log->WriteCreateTable((TableCatalogEntry *)parent);
|
@@ -71,9 +75,9 @@ void CommitState::WriteCatalogEntry(CatalogEntry *entry, data_ptr_t dataptr) {
|
|
71
75
|
auto extra_data = (data_ptr_t)(dataptr + sizeof(idx_t));
|
72
76
|
// deserialize it
|
73
77
|
BufferedDeserializer source(extra_data, extra_data_size);
|
74
|
-
|
78
|
+
string column_name = source.Read<string>();
|
75
79
|
// write the alter table in the log
|
76
|
-
log->WriteAlter(
|
80
|
+
log->WriteAlter(source.ptr, source.endptr - source.ptr);
|
77
81
|
} else {
|
78
82
|
log->WriteCreateView((ViewCatalogEntry *)parent);
|
79
83
|
}
|