duckdb 0.7.2-dev586.0 → 0.7.2-dev654.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/extension/icu/icu-table-range.cpp +7 -7
- package/src/duckdb/extension/parquet/parquet_reader.cpp +1 -1
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +3 -3
- package/src/duckdb/src/catalog/dependency_list.cpp +12 -0
- package/src/duckdb/src/common/string_util.cpp +4 -1
- package/src/duckdb/src/common/types/blob.cpp +1 -1
- package/src/duckdb/src/common/types/chunk_collection.cpp +2 -2
- package/src/duckdb/src/common/types/data_chunk.cpp +1 -1
- package/src/duckdb/src/common/types/value.cpp +8 -8
- package/src/duckdb/src/common/types.cpp +11 -11
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +15 -3
- package/src/duckdb/src/execution/operator/helper/physical_vacuum.cpp +3 -0
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +2 -2
- package/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp +6 -11
- package/src/duckdb/src/execution/operator/join/physical_range_join.cpp +1 -1
- package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +2 -2
- package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +3 -0
- package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +22 -7
- package/src/duckdb/src/function/aggregate/distributive/first.cpp +1 -0
- package/src/duckdb/src/function/aggregate/holistic/approximate_quantile.cpp +5 -2
- package/src/duckdb/src/function/aggregate/holistic/quantile.cpp +1 -1
- package/src/duckdb/src/function/aggregate/nested/list.cpp +8 -8
- package/src/duckdb/src/function/cast/struct_cast.cpp +1 -1
- package/src/duckdb/src/function/scalar/date/date_part.cpp +1 -1
- package/src/duckdb/src/function/scalar/list/list_concat.cpp +5 -4
- package/src/duckdb/src/function/scalar/list/list_lambdas.cpp +3 -3
- package/src/duckdb/src/function/scalar/list/list_value.cpp +1 -1
- package/src/duckdb/src/function/scalar/map/map_entries.cpp +1 -1
- package/src/duckdb/src/function/scalar/struct/struct_insert.cpp +1 -1
- package/src/duckdb/src/function/scalar/struct/struct_pack.cpp +1 -1
- package/src/duckdb/src/function/table/arrow.cpp +2 -2
- package/src/duckdb/src/function/table/checkpoint.cpp +5 -1
- package/src/duckdb/src/function/table/system/duckdb_constraints.cpp +2 -2
- package/src/duckdb/src/function/table/system/test_all_types.cpp +2 -2
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/types.hpp +3 -3
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +0 -1
- package/src/duckdb/src/main/config.cpp +4 -0
- package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +3 -4
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +5 -3
- package/src/duckdb/src/optimizer/pushdown/pushdown_aggregate.cpp +33 -5
- package/src/duckdb/src/optimizer/rule/move_constants.cpp +8 -2
- package/src/duckdb/src/optimizer/unnest_rewriter.cpp +2 -2
- package/src/duckdb/src/parser/expression/conjunction_expression.cpp +2 -0
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +17 -1
- package/src/duckdb/src/parser/transform/helpers/transform_typename.cpp +3 -2
- package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -2
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +1 -1
- package/src/duckdb/src/planner/binder/expression/bind_columnref_expression.cpp +4 -3
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +25 -13
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +2 -2
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +2 -1
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +9 -1
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +10 -6
- package/src/duckdb/src/planner/binder/statement/bind_update.cpp +3 -1
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +1 -0
- package/src/duckdb/src/planner/binder/tableref/plan_cteref.cpp +1 -0
- package/src/duckdb/src/planner/expression_binder/having_binder.cpp +3 -0
- package/src/duckdb/src/planner/expression_binder.cpp +1 -1
- package/src/duckdb/src/storage/statistics/column_statistics.cpp +1 -2
- package/src/duckdb/src/storage/statistics/distinct_statistics.cpp +4 -0
- package/src/duckdb/src/storage/statistics/list_stats.cpp +6 -2
- package/src/duckdb/src/storage/statistics/struct_stats.cpp +3 -1
- package/src/duckdb/src/storage/table/row_group.cpp +6 -1
- package/src/duckdb/src/storage/table/update_segment.cpp +11 -7
@@ -74,7 +74,7 @@ static unique_ptr<FunctionData> StructInsertBind(ClientContext &context, ScalarF
|
|
74
74
|
}
|
75
75
|
|
76
76
|
// this is more for completeness reasons
|
77
|
-
bound_function.return_type = LogicalType::STRUCT(
|
77
|
+
bound_function.return_type = LogicalType::STRUCT(new_struct_children);
|
78
78
|
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
79
79
|
}
|
80
80
|
|
@@ -54,7 +54,7 @@ static unique_ptr<FunctionData> StructPackBind(ClientContext &context, ScalarFun
|
|
54
54
|
}
|
55
55
|
|
56
56
|
// this is more for completeness reasons
|
57
|
-
bound_function.return_type = LogicalType::STRUCT(
|
57
|
+
bound_function.return_type = LogicalType::STRUCT(struct_children);
|
58
58
|
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
59
59
|
}
|
60
60
|
|
@@ -117,14 +117,14 @@ LogicalType ArrowTableFunction::GetArrowLogicalType(
|
|
117
117
|
idx_t fixed_size = std::stoi(parameters);
|
118
118
|
arrow_convert_data[col_idx]->variable_sz_type.emplace_back(ArrowVariableSizeType::FIXED_SIZE, fixed_size);
|
119
119
|
auto child_type = GetArrowLogicalType(*schema.children[0], arrow_convert_data, col_idx);
|
120
|
-
return LogicalType::LIST(
|
120
|
+
return LogicalType::LIST(child_type);
|
121
121
|
} else if (format == "+s") {
|
122
122
|
child_list_t<LogicalType> child_types;
|
123
123
|
for (idx_t type_idx = 0; type_idx < (idx_t)schema.n_children; type_idx++) {
|
124
124
|
auto child_type = GetArrowLogicalType(*schema.children[type_idx], arrow_convert_data, col_idx);
|
125
125
|
child_types.push_back({schema.children[type_idx]->name, child_type});
|
126
126
|
}
|
127
|
-
return LogicalType::STRUCT(
|
127
|
+
return LogicalType::STRUCT(child_types);
|
128
128
|
|
129
129
|
} else if (format == "+m") {
|
130
130
|
arrow_convert_data[col_idx]->variable_sz_type.emplace_back(ArrowVariableSizeType::NORMAL, 0);
|
@@ -32,7 +32,11 @@ static unique_ptr<FunctionData> CheckpointBind(ClientContext &context, TableFunc
|
|
32
32
|
AttachedDatabase *db;
|
33
33
|
auto &db_manager = DatabaseManager::Get(context);
|
34
34
|
if (!input.inputs.empty()) {
|
35
|
-
|
35
|
+
auto &db_name = StringValue::Get(input.inputs[0]);
|
36
|
+
db = db_manager.GetDatabase(context, db_name);
|
37
|
+
if (!db) {
|
38
|
+
throw BinderException("Database \"%s\" not found", db_name);
|
39
|
+
}
|
36
40
|
} else {
|
37
41
|
db = db_manager.GetDatabase(context, DatabaseManager::GetDefaultDatabase(context));
|
38
42
|
}
|
@@ -204,8 +204,8 @@ void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_
|
|
204
204
|
const auto &bound_foreign_key = (const BoundForeignKeyConstraint &)bound_constraint;
|
205
205
|
const auto &info = bound_foreign_key.info;
|
206
206
|
// find the other table
|
207
|
-
auto table_entry =
|
208
|
-
|
207
|
+
auto table_entry = Catalog::GetEntry<TableCatalogEntry>(context, table.catalog->GetName(),
|
208
|
+
info.schema, info.table, true);
|
209
209
|
if (!table_entry) {
|
210
210
|
throw InternalException("dukdb_constraints: entry %s.%s referenced in foreign key not found",
|
211
211
|
info.schema, info.table);
|
@@ -138,7 +138,7 @@ vector<TestType> TestAllTypesFun::GetTestTypes() {
|
|
138
138
|
child_list_t<LogicalType> struct_type_list;
|
139
139
|
struct_type_list.push_back(make_pair("a", LogicalType::INTEGER));
|
140
140
|
struct_type_list.push_back(make_pair("b", LogicalType::VARCHAR));
|
141
|
-
auto struct_type = LogicalType::STRUCT(
|
141
|
+
auto struct_type = LogicalType::STRUCT(struct_type_list);
|
142
142
|
|
143
143
|
child_list_t<Value> min_struct_list;
|
144
144
|
min_struct_list.push_back(make_pair("a", Value(LogicalType::INTEGER)));
|
@@ -156,7 +156,7 @@ vector<TestType> TestAllTypesFun::GetTestTypes() {
|
|
156
156
|
child_list_t<LogicalType> struct_list_type_list;
|
157
157
|
struct_list_type_list.push_back(make_pair("a", int_list_type));
|
158
158
|
struct_list_type_list.push_back(make_pair("b", varchar_list_type));
|
159
|
-
auto struct_list_type = LogicalType::STRUCT(
|
159
|
+
auto struct_list_type = LogicalType::STRUCT(struct_list_type_list);
|
160
160
|
|
161
161
|
child_list_t<Value> min_struct_vl_list;
|
162
162
|
min_struct_vl_list.push_back(make_pair("a", Value(int_list_type)));
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "0.7.2-
|
2
|
+
#define DUCKDB_VERSION "0.7.2-dev654"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "6525767cf1"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -12,6 +12,7 @@
|
|
12
12
|
#include "duckdb/common/unordered_set.hpp"
|
13
13
|
|
14
14
|
namespace duckdb {
|
15
|
+
class Catalog;
|
15
16
|
class CatalogEntry;
|
16
17
|
|
17
18
|
//! The DependencyList
|
@@ -21,6 +22,8 @@ class DependencyList {
|
|
21
22
|
public:
|
22
23
|
DUCKDB_API void AddDependency(CatalogEntry *entry);
|
23
24
|
|
25
|
+
DUCKDB_API void VerifyDependencies(Catalog *catalog, const string &name);
|
26
|
+
|
24
27
|
private:
|
25
28
|
unordered_set<CatalogEntry *> set;
|
26
29
|
};
|
@@ -151,11 +151,11 @@ public:
|
|
151
151
|
//! Cannot be called with an empty list, use either EMPTYLIST or LIST with a type instead
|
152
152
|
DUCKDB_API static Value LIST(vector<Value> values);
|
153
153
|
//! Create a list value with the given entries
|
154
|
-
DUCKDB_API static Value LIST(LogicalType child_type, vector<Value> values);
|
154
|
+
DUCKDB_API static Value LIST(const LogicalType &child_type, vector<Value> values);
|
155
155
|
//! Create an empty list with the specified child-type
|
156
|
-
DUCKDB_API static Value EMPTYLIST(LogicalType child_type);
|
156
|
+
DUCKDB_API static Value EMPTYLIST(const LogicalType &child_type);
|
157
157
|
//! Create a map value with the given entries
|
158
|
-
DUCKDB_API static Value MAP(LogicalType child_type, vector<Value> values);
|
158
|
+
DUCKDB_API static Value MAP(const LogicalType &child_type, vector<Value> values);
|
159
159
|
//! Create a union value from a selected value and a tag from a set of alternatives.
|
160
160
|
DUCKDB_API static Value UNION(child_list_t<LogicalType> members, uint8_t tag, Value value);
|
161
161
|
|
@@ -427,10 +427,10 @@ public:
|
|
427
427
|
// explicitly allowing these functions to be capitalized to be in-line with the remaining functions
|
428
428
|
DUCKDB_API static LogicalType DECIMAL(int width, int scale); // NOLINT
|
429
429
|
DUCKDB_API static LogicalType VARCHAR_COLLATION(string collation); // NOLINT
|
430
|
-
DUCKDB_API static LogicalType LIST( LogicalType child); // NOLINT
|
431
|
-
DUCKDB_API static LogicalType STRUCT( child_list_t<LogicalType> children); // NOLINT
|
430
|
+
DUCKDB_API static LogicalType LIST(const LogicalType &child); // NOLINT
|
431
|
+
DUCKDB_API static LogicalType STRUCT(const child_list_t<LogicalType> &children); // NOLINT
|
432
432
|
DUCKDB_API static LogicalType AGGREGATE_STATE(aggregate_state_t state_type); // NOLINT
|
433
|
-
DUCKDB_API static LogicalType MAP(LogicalType child); // NOLINT
|
433
|
+
DUCKDB_API static LogicalType MAP(const LogicalType &child); // NOLINT
|
434
434
|
DUCKDB_API static LogicalType MAP( child_list_t<LogicalType> children); // NOLINT
|
435
435
|
DUCKDB_API static LogicalType MAP(LogicalType key, LogicalType value); // NOLINT
|
436
436
|
DUCKDB_API static LogicalType UNION( child_list_t<LogicalType> members); // NOLINT
|
@@ -71,8 +71,11 @@ private:
|
|
71
71
|
vector<unique_ptr<CreatePivotEntry>> pivot_entries;
|
72
72
|
//! Sets of stored CTEs, if any
|
73
73
|
vector<CommonTableExpressionMap *> stored_cte_map;
|
74
|
+
//! Whether or not we are currently binding a window definition
|
75
|
+
bool in_window_definition = false;
|
74
76
|
|
75
77
|
void Clear();
|
78
|
+
bool InWindowDefinition();
|
76
79
|
|
77
80
|
void SetParamCount(idx_t new_count) {
|
78
81
|
if (parent) {
|
@@ -46,6 +46,8 @@ public:
|
|
46
46
|
string ToString() const;
|
47
47
|
idx_t GetCount() const;
|
48
48
|
|
49
|
+
static bool TypeIsSupported(const LogicalType &type);
|
50
|
+
|
49
51
|
private:
|
50
52
|
//! For distinct statistics we sample the input to speed up insertions
|
51
53
|
static constexpr const double SAMPLE_RATE = 0.1;
|
@@ -34,7 +34,6 @@ public:
|
|
34
34
|
bool HasUncommittedUpdates(idx_t vector_index);
|
35
35
|
bool HasUpdates(idx_t vector_index) const;
|
36
36
|
bool HasUpdates(idx_t start_row_idx, idx_t end_row_idx);
|
37
|
-
void ClearUpdates();
|
38
37
|
|
39
38
|
void FetchUpdates(TransactionData transaction, idx_t vector_index, Vector &result);
|
40
39
|
void FetchCommitted(idx_t vector_index, Vector &result);
|
@@ -270,6 +270,7 @@ idx_t CGroupBandwidthQuota(idx_t physical_cores, FileSystem &fs) {
|
|
270
270
|
}
|
271
271
|
|
272
272
|
idx_t GetSystemMaxThreadsInternal(FileSystem &fs) {
|
273
|
+
#ifndef DUCKDB_NO_THREADS
|
273
274
|
idx_t physical_cores = std::thread::hardware_concurrency();
|
274
275
|
#ifdef __linux__
|
275
276
|
auto cores_available_per_period = CGroupBandwidthQuota(physical_cores, fs);
|
@@ -277,6 +278,9 @@ idx_t GetSystemMaxThreadsInternal(FileSystem &fs) {
|
|
277
278
|
#else
|
278
279
|
return physical_cores;
|
279
280
|
#endif
|
281
|
+
#else
|
282
|
+
return 1;
|
283
|
+
#endif
|
280
284
|
}
|
281
285
|
|
282
286
|
void DBConfig::SetDefaultMaxThreads() {
|
@@ -39,8 +39,7 @@ void CardinalityEstimator::AddRelationTdom(FilterInfo *filter_info) {
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
auto key = ColumnBinding(filter_info->left_binding.table_index, filter_info->left_binding.column_index);
|
42
|
-
column_binding_set_t
|
43
|
-
relations_to_tdoms.emplace_back(RelationsToTDom(tmp));
|
42
|
+
relations_to_tdoms.emplace_back(column_binding_set_t({key}));
|
44
43
|
}
|
45
44
|
|
46
45
|
bool CardinalityEstimator::SingleColumnFilter(FilterInfo *filter_info) {
|
@@ -93,7 +92,7 @@ void CardinalityEstimator::AddToEquivalenceSets(FilterInfo *filter_info, vector<
|
|
93
92
|
column_binding_set_t tmp;
|
94
93
|
tmp.insert(filter_info->left_binding);
|
95
94
|
tmp.insert(filter_info->right_binding);
|
96
|
-
relations_to_tdoms.emplace_back(
|
95
|
+
relations_to_tdoms.emplace_back(tmp);
|
97
96
|
relations_to_tdoms.back().filters.push_back(filter_info);
|
98
97
|
}
|
99
98
|
}
|
@@ -259,7 +258,7 @@ double CardinalityEstimator::EstimateCardinalityWithSet(JoinRelationSet *new_set
|
|
259
258
|
// connection to any subgraph in subgraphs. Add a new subgraph, and maybe later there will be
|
260
259
|
// a connection.
|
261
260
|
if (!found_match) {
|
262
|
-
subgraphs.emplace_back(
|
261
|
+
subgraphs.emplace_back();
|
263
262
|
auto subgraph = &subgraphs.back();
|
264
263
|
subgraph->relations.insert(filter->left_binding.table_index);
|
265
264
|
subgraph->relations.insert(filter->right_binding.table_index);
|
@@ -156,7 +156,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
|
|
156
156
|
vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
|
157
157
|
idx_t child_bindings_it = 0;
|
158
158
|
for (auto &child : op->children) {
|
159
|
-
child_binding_maps.emplace_back(
|
159
|
+
child_binding_maps.emplace_back();
|
160
160
|
JoinOrderOptimizer optimizer(context);
|
161
161
|
child = optimizer.Optimize(std::move(child));
|
162
162
|
// save the relation bindings from the optimized child. These later all get added to the
|
@@ -230,7 +230,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
|
|
230
230
|
auto relation_id = relations.size();
|
231
231
|
// push one child column binding map back.
|
232
232
|
vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
|
233
|
-
child_binding_maps.emplace_back(
|
233
|
+
child_binding_maps.emplace_back();
|
234
234
|
optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(0));
|
235
235
|
// This logical projection may sit on top of a logical comparison join that has been pushed down
|
236
236
|
// we want to copy the binding info of both tables
|
@@ -882,9 +882,11 @@ unique_ptr<LogicalOperator> JoinOrderOptimizer::RewritePlan(unique_ptr<LogicalOp
|
|
882
882
|
|
883
883
|
// first we will extract all relations from the main plan
|
884
884
|
vector<unique_ptr<LogicalOperator>> extracted_relations;
|
885
|
+
extracted_relations.reserve(relations.size());
|
885
886
|
for (auto &relation : relations) {
|
886
887
|
extracted_relations.push_back(ExtractJoinRelation(*relation));
|
887
888
|
}
|
889
|
+
|
888
890
|
// now we generate the actual joins
|
889
891
|
auto join_tree = GenerateJoins(extracted_relations, node);
|
890
892
|
// perform the final pushdown of remaining filters
|
@@ -1012,7 +1014,7 @@ unique_ptr<LogicalOperator> JoinOrderOptimizer::Optimize(unique_ptr<LogicalOpera
|
|
1012
1014
|
for (idx_t i = 0; i < relations.size(); i++) {
|
1013
1015
|
auto &rel = *relations[i];
|
1014
1016
|
auto node = set_manager.GetJoinRelation(i);
|
1015
|
-
nodes_ops.emplace_back(
|
1017
|
+
nodes_ops.emplace_back(make_unique<JoinNode>(node, 0), rel.op);
|
1016
1018
|
}
|
1017
1019
|
|
1018
1020
|
cardinality_estimator.InitCardinalityEstimatorProps(&nodes_ops, &filter_infos);
|
@@ -9,6 +9,14 @@ namespace duckdb {
|
|
9
9
|
|
10
10
|
using Filter = FilterPushdown::Filter;
|
11
11
|
|
12
|
+
static void ExtractFilterBindings(Expression &expr, vector<ColumnBinding> &bindings) {
|
13
|
+
if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
|
14
|
+
auto &colref = (BoundColumnRefExpression &)expr;
|
15
|
+
bindings.push_back(colref.binding);
|
16
|
+
}
|
17
|
+
ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { ExtractFilterBindings(child, bindings); });
|
18
|
+
}
|
19
|
+
|
12
20
|
static unique_ptr<Expression> ReplaceGroupBindings(LogicalAggregate &proj, unique_ptr<Expression> expr) {
|
13
21
|
if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
|
14
22
|
auto &colref = (BoundColumnRefExpression &)*expr;
|
@@ -40,14 +48,34 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownAggregate(unique_ptr<Logical
|
|
40
48
|
// filter on GROUPINGS function: cannot pushdown
|
41
49
|
continue;
|
42
50
|
}
|
43
|
-
//
|
44
|
-
|
51
|
+
// no aggregate! we are filtering on a group
|
52
|
+
// we can only push this down if the filter is in all grouping sets
|
53
|
+
vector<ColumnBinding> bindings;
|
54
|
+
ExtractFilterBindings(*f.filter, bindings);
|
55
|
+
|
56
|
+
bool can_pushdown_filter = true;
|
57
|
+
if (aggr.grouping_sets.empty()) {
|
58
|
+
// empty grouping set - we cannot pushdown the filter
|
59
|
+
can_pushdown_filter = false;
|
60
|
+
}
|
45
61
|
for (auto &grp : aggr.grouping_sets) {
|
46
|
-
if
|
47
|
-
|
62
|
+
// check for each of the grouping sets if they contain all groups
|
63
|
+
if (bindings.empty()) {
|
64
|
+
// we can never push down empty grouping sets
|
65
|
+
can_pushdown_filter = false;
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
for (auto &binding : bindings) {
|
69
|
+
if (grp.find(binding.column_index) == grp.end()) {
|
70
|
+
can_pushdown_filter = false;
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
if (!can_pushdown_filter) {
|
75
|
+
break;
|
48
76
|
}
|
49
77
|
}
|
50
|
-
if (
|
78
|
+
if (!can_pushdown_filter) {
|
51
79
|
continue;
|
52
80
|
}
|
53
81
|
// no aggregate! we can push this down
|
@@ -73,7 +73,10 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
73
73
|
}
|
74
74
|
auto result_value = Value::HUGEINT(outer_value);
|
75
75
|
if (!result_value.DefaultTryCastAs(constant_type)) {
|
76
|
-
// if the cast is not possible then
|
76
|
+
// if the cast is not possible then an equality comparison is not possible
|
77
|
+
if (comparison->type != ExpressionType::COMPARE_EQUAL) {
|
78
|
+
return nullptr;
|
79
|
+
}
|
77
80
|
return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]),
|
78
81
|
Value::BOOLEAN(false));
|
79
82
|
}
|
@@ -86,7 +89,10 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
86
89
|
}
|
87
90
|
auto result_value = Value::HUGEINT(inner_value);
|
88
91
|
if (!result_value.DefaultTryCastAs(constant_type)) {
|
89
|
-
// if the cast is not possible then
|
92
|
+
// if the cast is not possible then an equality comparison is not possible
|
93
|
+
if (comparison->type != ExpressionType::COMPARE_EQUAL) {
|
94
|
+
return nullptr;
|
95
|
+
}
|
90
96
|
return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]),
|
91
97
|
Value::BOOLEAN(false));
|
92
98
|
}
|
@@ -261,7 +261,7 @@ void UnnestRewriter::UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &update
|
|
261
261
|
for (idx_t child_col_idx = 0; child_col_idx < unnest_child_cols.size(); child_col_idx++) {
|
262
262
|
if (delim_columns[delim_col_idx].table_index == unnest_child_cols[child_col_idx].table_index) {
|
263
263
|
ColumnBinding old_binding(overwritten_tbl_idx, DConstants::INVALID_INDEX);
|
264
|
-
updater.replace_bindings.emplace_back(
|
264
|
+
updater.replace_bindings.emplace_back(old_binding, delim_columns[delim_col_idx]);
|
265
265
|
break;
|
266
266
|
}
|
267
267
|
}
|
@@ -301,7 +301,7 @@ void UnnestRewriter::GetLHSExpressions(LogicalOperator &op) {
|
|
301
301
|
}
|
302
302
|
|
303
303
|
for (idx_t i = 0; i < op.types.size(); i++) {
|
304
|
-
lhs_bindings.emplace_back(
|
304
|
+
lhs_bindings.emplace_back(col_bindings[i], op.types[i]);
|
305
305
|
if (set_alias) {
|
306
306
|
auto &proj = (LogicalProjection &)op;
|
307
307
|
lhs_bindings.back().alias = proj.expressions[i]->alias;
|
@@ -45,9 +45,11 @@ bool ConjunctionExpression::Equal(const ConjunctionExpression *a, const Conjunct
|
|
45
45
|
|
46
46
|
unique_ptr<ParsedExpression> ConjunctionExpression::Copy() const {
|
47
47
|
vector<unique_ptr<ParsedExpression>> copy_children;
|
48
|
+
copy_children.reserve(children.size());
|
48
49
|
for (auto &expr : children) {
|
49
50
|
copy_children.push_back(expr->Copy());
|
50
51
|
}
|
52
|
+
|
51
53
|
auto copy = make_unique<ConjunctionExpression>(type, std::move(copy_children));
|
52
54
|
copy->CopyProperties(*this);
|
53
55
|
return std::move(copy);
|
@@ -24,7 +24,7 @@ static ExpressionType WindowToExpressionType(string &fun_name) {
|
|
24
24
|
return ExpressionType::WINDOW_FIRST_VALUE;
|
25
25
|
} else if (fun_name == "last_value" || fun_name == "last") {
|
26
26
|
return ExpressionType::WINDOW_LAST_VALUE;
|
27
|
-
} else if (fun_name == "nth_value"
|
27
|
+
} else if (fun_name == "nth_value") {
|
28
28
|
return ExpressionType::WINDOW_NTH_VALUE;
|
29
29
|
} else if (fun_name == "cume_dist") {
|
30
30
|
return ExpressionType::WINDOW_CUME_DIST;
|
@@ -105,6 +105,16 @@ bool Transformer::ExpressionIsEmptyStar(ParsedExpression &expr) {
|
|
105
105
|
return false;
|
106
106
|
}
|
107
107
|
|
108
|
+
bool Transformer::InWindowDefinition() {
|
109
|
+
if (in_window_definition) {
|
110
|
+
return true;
|
111
|
+
}
|
112
|
+
if (parent) {
|
113
|
+
return parent->InWindowDefinition();
|
114
|
+
}
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
|
108
118
|
unique_ptr<ParsedExpression> Transformer::TransformFuncCall(duckdb_libpgquery::PGFuncCall *root) {
|
109
119
|
auto name = root->funcname;
|
110
120
|
string catalog, schema, function_name;
|
@@ -139,6 +149,10 @@ unique_ptr<ParsedExpression> Transformer::TransformFuncCall(duckdb_libpgquery::P
|
|
139
149
|
|
140
150
|
auto lowercase_name = StringUtil::Lower(function_name);
|
141
151
|
if (root->over) {
|
152
|
+
if (InWindowDefinition()) {
|
153
|
+
throw ParserException("window functions are not allowed in window definitions");
|
154
|
+
}
|
155
|
+
|
142
156
|
const auto win_fun_type = WindowToExpressionType(lowercase_name);
|
143
157
|
if (win_fun_type == ExpressionType::INVALID) {
|
144
158
|
throw InternalException("Unknown/unsupported window function");
|
@@ -218,8 +232,10 @@ unique_ptr<ParsedExpression> Transformer::TransformFuncCall(duckdb_libpgquery::P
|
|
218
232
|
window_ref = it->second;
|
219
233
|
D_ASSERT(window_ref);
|
220
234
|
}
|
235
|
+
in_window_definition = true;
|
221
236
|
TransformWindowDef(window_ref, expr.get());
|
222
237
|
TransformWindowFrame(window_spec, expr.get());
|
238
|
+
in_window_definition = false;
|
223
239
|
expr->query_location = root->location;
|
224
240
|
return std::move(expr);
|
225
241
|
}
|
@@ -52,7 +52,8 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n
|
|
52
52
|
children.push_back(make_pair(entry_name, entry_type));
|
53
53
|
}
|
54
54
|
D_ASSERT(!children.empty());
|
55
|
-
result_type = LogicalType::STRUCT(
|
55
|
+
result_type = LogicalType::STRUCT(children);
|
56
|
+
|
56
57
|
} else if (base_type == LogicalTypeId::MAP) {
|
57
58
|
|
58
59
|
if (!type_name->typmods || type_name->typmods->length != 2) {
|
@@ -207,7 +208,7 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n
|
|
207
208
|
// array bounds: turn the type into a list
|
208
209
|
idx_t extra_stack = 0;
|
209
210
|
for (auto cell = type_name->arrayBounds->head; cell != nullptr; cell = cell->next) {
|
210
|
-
result_type = LogicalType::LIST(
|
211
|
+
result_type = LogicalType::LIST(result_type);
|
211
212
|
StackCheck(extra_stack++);
|
212
213
|
}
|
213
214
|
}
|
@@ -26,8 +26,7 @@ unique_ptr<QueryNode> Transformer::TransformSelectInternal(duckdb_libpgquery::PG
|
|
26
26
|
auto window_def = reinterpret_cast<duckdb_libpgquery::PGWindowDef *>(window_ele->data.ptr_value);
|
27
27
|
D_ASSERT(window_def);
|
28
28
|
D_ASSERT(window_def->name);
|
29
|
-
|
30
|
-
|
29
|
+
string window_name(window_def->name);
|
31
30
|
auto it = window_clauses.find(window_name);
|
32
31
|
if (it != window_clauses.end()) {
|
33
32
|
throw ParserException("window \"%s\" is already defined", window_name);
|
@@ -219,7 +219,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti
|
|
219
219
|
const auto null_order = (order.null_order == OrderByNullType::ORDER_DEFAULT)
|
220
220
|
? config.options.default_null_order
|
221
221
|
: order.null_order;
|
222
|
-
order_bys->orders.emplace_back(
|
222
|
+
order_bys->orders.emplace_back(sense, null_order, std::move(order_expr.expr));
|
223
223
|
}
|
224
224
|
}
|
225
225
|
|
@@ -175,11 +175,12 @@ unique_ptr<ParsedExpression> ExpressionBinder::CreateStructPack(ColumnRefExpress
|
|
175
175
|
}
|
176
176
|
}
|
177
177
|
// We found the table, now create the struct_pack expression
|
178
|
-
vector<unique_ptr<ParsedExpression>>
|
178
|
+
vector<unique_ptr<ParsedExpression>> child_expressions;
|
179
|
+
child_expressions.reserve(binding->names.size());
|
179
180
|
for (const auto &column_name : binding->names) {
|
180
|
-
|
181
|
+
child_expressions.push_back(make_unique<ColumnRefExpression>(column_name, table_name));
|
181
182
|
}
|
182
|
-
return make_unique<FunctionExpression>("struct_pack", std::move(
|
183
|
+
return make_unique<FunctionExpression>("struct_pack", std::move(child_expressions));
|
183
184
|
}
|
184
185
|
|
185
186
|
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) {
|
@@ -426,12 +426,16 @@ unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_
|
|
426
426
|
// after that, we bind to the SELECT list
|
427
427
|
SelectBinder select_binder(*this, context, *result, info, alias_map);
|
428
428
|
vector<LogicalType> internal_sql_types;
|
429
|
+
vector<idx_t> group_by_all_indexes;
|
429
430
|
for (idx_t i = 0; i < statement.select_list.size(); i++) {
|
430
431
|
bool is_window = statement.select_list[i]->IsWindow();
|
431
432
|
idx_t unnest_count = result->unnests.size();
|
432
433
|
LogicalType result_type;
|
433
434
|
auto expr = select_binder.Bind(statement.select_list[i], &result_type);
|
434
|
-
|
435
|
+
bool is_original_column = i < result->column_count;
|
436
|
+
bool can_group_by_all =
|
437
|
+
statement.aggregate_handling == AggregateHandling::FORCE_AGGREGATES && is_original_column;
|
438
|
+
if (can_group_by_all && select_binder.HasBoundColumns()) {
|
435
439
|
if (select_binder.BoundAggregates()) {
|
436
440
|
throw BinderException("Cannot mix aggregates with non-aggregated columns!");
|
437
441
|
}
|
@@ -443,20 +447,25 @@ unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_
|
|
443
447
|
}
|
444
448
|
// we are forcing aggregates, and the node has columns bound
|
445
449
|
// this entry becomes a group
|
446
|
-
|
447
|
-
expr->return_type, ColumnBinding(result->group_index, result->groups.group_expressions.size()));
|
448
|
-
result->groups.group_expressions.push_back(std::move(expr));
|
449
|
-
expr = std::move(group_ref);
|
450
|
+
group_by_all_indexes.push_back(i);
|
450
451
|
}
|
451
452
|
result->select_list.push_back(std::move(expr));
|
452
453
|
if (i < result->column_count) {
|
453
454
|
result->types.push_back(result_type);
|
454
455
|
}
|
455
456
|
internal_sql_types.push_back(result_type);
|
456
|
-
if (
|
457
|
+
if (can_group_by_all) {
|
457
458
|
select_binder.ResetBindings();
|
458
459
|
}
|
459
460
|
}
|
461
|
+
// push the GROUP BY ALL expressions into the group set
|
462
|
+
for (auto &group_by_all_index : group_by_all_indexes) {
|
463
|
+
auto &expr = result->select_list[group_by_all_index];
|
464
|
+
auto group_ref = make_unique<BoundColumnRefExpression>(
|
465
|
+
expr->return_type, ColumnBinding(result->group_index, result->groups.group_expressions.size()));
|
466
|
+
result->groups.group_expressions.push_back(std::move(expr));
|
467
|
+
expr = std::move(group_ref);
|
468
|
+
}
|
460
469
|
result->need_prune = result->select_list.size() > result->column_count;
|
461
470
|
|
462
471
|
// in the normal select binder, we bind columns as if there is no aggregation
|
@@ -467,16 +476,19 @@ unique_ptr<BoundQueryNode> Binder::BindSelectNode(SelectNode &statement, unique_
|
|
467
476
|
!result->groups.grouping_sets.empty()) {
|
468
477
|
if (statement.aggregate_handling == AggregateHandling::NO_AGGREGATES_ALLOWED) {
|
469
478
|
throw BinderException("Aggregates cannot be present in a Project relation!");
|
470
|
-
} else if (
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
479
|
+
} else if (select_binder.HasBoundColumns()) {
|
480
|
+
auto &bound_columns = select_binder.GetBoundColumns();
|
481
|
+
string error;
|
482
|
+
error = "column \"%s\" must appear in the GROUP BY clause or must be part of an aggregate function.";
|
483
|
+
if (statement.aggregate_handling == AggregateHandling::FORCE_AGGREGATES) {
|
484
|
+
error += "\nGROUP BY ALL will only group entries in the SELECT list. Add it to the SELECT list or "
|
485
|
+
"GROUP BY this entry explicitly.";
|
486
|
+
} else {
|
475
487
|
error += "\nEither add it to the GROUP BY list, or use \"ANY_VALUE(%s)\" if the exact value of \"%s\" "
|
476
488
|
"is not important.";
|
477
|
-
throw BinderException(FormatError(bound_columns[0].query_location, error, bound_columns[0].name,
|
478
|
-
bound_columns[0].name, bound_columns[0].name));
|
479
489
|
}
|
490
|
+
throw BinderException(FormatError(bound_columns[0].query_location, error, bound_columns[0].name,
|
491
|
+
bound_columns[0].name, bound_columns[0].name));
|
480
492
|
}
|
481
493
|
}
|
482
494
|
|
@@ -185,7 +185,7 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) {
|
|
185
185
|
vector<string> expected_names;
|
186
186
|
if (!bound_insert.column_index_map.empty()) {
|
187
187
|
expected_names.resize(bound_insert.expected_types.size());
|
188
|
-
for (auto &col : table->GetColumns().
|
188
|
+
for (auto &col : table->GetColumns().Physical()) {
|
189
189
|
auto i = col.Physical();
|
190
190
|
if (bound_insert.column_index_map[i] != DConstants::INVALID_INDEX) {
|
191
191
|
expected_names[bound_insert.column_index_map[i]] = col.Name();
|
@@ -193,7 +193,7 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) {
|
|
193
193
|
}
|
194
194
|
} else {
|
195
195
|
expected_names.reserve(bound_insert.expected_types.size());
|
196
|
-
for (auto &col : table->GetColumns().
|
196
|
+
for (auto &col : table->GetColumns().Physical()) {
|
197
197
|
expected_names.push_back(col.Name());
|
198
198
|
}
|
199
199
|
}
|
@@ -441,8 +441,9 @@ unique_ptr<LogicalOperator> DuckCatalog::BindCreateIndex(Binder &binder, CreateS
|
|
441
441
|
|
442
442
|
auto &get = (LogicalGet &)*plan;
|
443
443
|
// bind the index expressions
|
444
|
-
vector<unique_ptr<Expression>> expressions;
|
445
444
|
IndexBinder index_binder(binder, binder.context);
|
445
|
+
vector<unique_ptr<Expression>> expressions;
|
446
|
+
expressions.reserve(base.expressions.size());
|
446
447
|
for (auto &expr : base.expressions) {
|
447
448
|
expressions.push_back(index_binder.Bind(expr));
|
448
449
|
}
|
@@ -119,9 +119,15 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) {
|
|
119
119
|
fk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE);
|
120
120
|
physical_index_set_t fk_key_set, pk_key_set;
|
121
121
|
for (idx_t i = 0; i < fk.info.pk_keys.size(); i++) {
|
122
|
+
if (pk_key_set.find(fk.info.pk_keys[i]) != pk_key_set.end()) {
|
123
|
+
throw BinderException("Duplicate primary key referenced in FOREIGN KEY constraint");
|
124
|
+
}
|
122
125
|
pk_key_set.insert(fk.info.pk_keys[i]);
|
123
126
|
}
|
124
127
|
for (idx_t i = 0; i < fk.info.fk_keys.size(); i++) {
|
128
|
+
if (fk_key_set.find(fk.info.fk_keys[i]) != fk_key_set.end()) {
|
129
|
+
throw BinderException("Duplicate key specified in FOREIGN KEY constraint");
|
130
|
+
}
|
125
131
|
fk_key_set.insert(fk.info.fk_keys[i]);
|
126
132
|
}
|
127
133
|
info.bound_constraints.push_back(
|
@@ -292,6 +298,7 @@ unique_ptr<BoundCreateTableInfo> Binder::BindCreateTableInfo(unique_ptr<CreateIn
|
|
292
298
|
result->dependencies.AddDependency(type_dependency);
|
293
299
|
}
|
294
300
|
}
|
301
|
+
result->dependencies.VerifyDependencies(schema->catalog, result->Base().table);
|
295
302
|
properties.allow_stream_result = false;
|
296
303
|
return result;
|
297
304
|
}
|
@@ -303,9 +310,10 @@ unique_ptr<BoundCreateTableInfo> Binder::BindCreateTableInfo(unique_ptr<CreateIn
|
|
303
310
|
}
|
304
311
|
|
305
312
|
vector<unique_ptr<Expression>> Binder::BindCreateIndexExpressions(TableCatalogEntry *table, CreateIndexInfo *info) {
|
306
|
-
vector<unique_ptr<Expression>> expressions;
|
307
313
|
|
308
314
|
auto index_binder = IndexBinder(*this, this->context, table, info);
|
315
|
+
vector<unique_ptr<Expression>> expressions;
|
316
|
+
expressions.reserve(info->expressions.size());
|
309
317
|
for (auto &expr : info->expressions) {
|
310
318
|
expressions.push_back(index_binder.Bind(expr));
|
311
319
|
}
|