duckdb 0.7.2-dev865.0 → 0.7.2-dev899.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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/src/catalog/default/default_functions.cpp +3 -0
  3. package/src/duckdb/src/catalog/duck_catalog.cpp +34 -7
  4. package/src/duckdb/src/common/box_renderer.cpp +109 -23
  5. package/src/duckdb/src/function/scalar/struct/struct_extract.cpp +1 -1
  6. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  7. package/src/duckdb/src/include/duckdb/catalog/duck_catalog.hpp +2 -1
  8. package/src/duckdb/src/include/duckdb/common/box_renderer.hpp +8 -2
  9. package/src/duckdb/src/include/duckdb/optimizer/filter_pushdown.hpp +2 -0
  10. package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +4 -2
  11. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +2 -2
  12. package/src/duckdb/src/include/duckdb/planner/binder.hpp +3 -1
  13. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +64 -0
  14. package/src/duckdb/src/include/duckdb/planner/expression_binder/having_binder.hpp +2 -2
  15. package/src/duckdb/src/include/duckdb/planner/expression_binder/qualify_binder.hpp +2 -2
  16. package/src/duckdb/src/include/duckdb/planner/expression_binder/select_binder.hpp +9 -38
  17. package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +1 -1
  18. package/src/duckdb/src/include/duckdb/planner/query_node/bound_select_node.hpp +8 -2
  19. package/src/duckdb/src/optimizer/filter_pushdown.cpp +11 -7
  20. package/src/duckdb/src/optimizer/pushdown/pushdown_left_join.cpp +1 -10
  21. package/src/duckdb/src/optimizer/pushdown/pushdown_mark_join.cpp +1 -1
  22. package/src/duckdb/src/optimizer/pushdown/pushdown_single_join.cpp +1 -1
  23. package/src/duckdb/src/parser/tableref/pivotref.cpp +35 -11
  24. package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +41 -12
  25. package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +19 -3
  26. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +2 -2
  27. package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +1 -8
  28. package/src/duckdb/src/planner/binder/expression/bind_unnest_expression.cpp +163 -24
  29. package/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp +2 -2
  30. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +23 -3
  31. package/src/duckdb/src/planner/binder/query_node/plan_select_node.cpp +9 -3
  32. package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +8 -8
  33. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +146 -0
  34. package/src/duckdb/src/planner/expression_binder/having_binder.cpp +3 -3
  35. package/src/duckdb/src/planner/expression_binder/qualify_binder.cpp +3 -3
  36. package/src/duckdb/src/planner/expression_binder/select_binder.cpp +1 -132
  37. package/src/duckdb/src/planner/expression_binder.cpp +9 -2
  38. package/src/duckdb/src/planner/expression_iterator.cpp +12 -10
  39. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +1 -0
  40. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +11817 -11167
  41. package/src/duckdb/ub_src_planner_expression_binder.cpp +2 -0
@@ -25,10 +25,10 @@ static void ConstructPivots(PivotRef &ref, idx_t pivot_idx, vector<unique_ptr<Pa
25
25
  for (auto &entry : pivot.entries) {
26
26
  unique_ptr<ParsedExpression> expr = current_expr ? current_expr->Copy() : nullptr;
27
27
  string name = entry.alias;
28
- D_ASSERT(entry.values.size() == pivot.names.size());
28
+ D_ASSERT(entry.values.size() == pivot.pivot_expressions.size());
29
29
  for (idx_t v = 0; v < entry.values.size(); v++) {
30
30
  auto &value = entry.values[v];
31
- auto column_ref = make_unique<ColumnRefExpression>(pivot.names[v]);
31
+ auto column_ref = pivot.pivot_expressions[v]->Copy();
32
32
  auto constant_value = make_unique<ConstantExpression>(value);
33
33
  auto comp_expr = make_unique<ComparisonExpression>(ExpressionType::COMPARE_NOT_DISTINCT_FROM,
34
34
  std::move(column_ref), std::move(constant_value));
@@ -56,7 +56,7 @@ static void ConstructPivots(PivotRef &ref, idx_t pivot_idx, vector<unique_ptr<Pa
56
56
  auto &function = (FunctionExpression &)*copy;
57
57
  // add the filter and alias to the aggregate function
58
58
  function.filter = expr->Copy();
59
- if (ref.aggregates.size() > 1) {
59
+ if (ref.aggregates.size() > 1 || !function.alias.empty()) {
60
60
  // if there are multiple aggregates specified we add the name of the aggregate as well
61
61
  function.alias = name + "_" + function.GetName();
62
62
  } else {
@@ -126,8 +126,8 @@ unique_ptr<SelectNode> Binder::BindPivot(PivotRef &ref, vector<unique_ptr<Parsed
126
126
  }
127
127
  total_pivots *= pivot.entries.size();
128
128
  // add the pivoted column to the columns that have been handled
129
- for (auto &pivot_name : pivot.names) {
130
- handled_columns.insert(pivot_name);
129
+ for (auto &pivot_name : pivot.pivot_expressions) {
130
+ ExtractPivotExpressions(*pivot_name, handled_columns);
131
131
  }
132
132
  value_set_t pivots;
133
133
  for (auto &entry : pivot.entries) {
@@ -143,9 +143,9 @@ unique_ptr<SelectNode> Binder::BindPivot(PivotRef &ref, vector<unique_ptr<Parsed
143
143
  ref, StringUtil::Format("The value \"%s\" was specified multiple times in the IN clause",
144
144
  val.ToString())));
145
145
  }
146
- if (entry.values.size() != pivot.names.size()) {
146
+ if (entry.values.size() != pivot.pivot_expressions.size()) {
147
147
  throw ParserException("PIVOT IN list - inconsistent amount of rows - expected %d but got %d",
148
- pivot.names.size(), entry.values.size());
148
+ pivot.pivot_expressions.size(), entry.values.size());
149
149
  }
150
150
  pivots.insert(val);
151
151
  }
@@ -284,7 +284,7 @@ unique_ptr<SelectNode> Binder::BindUnpivot(Binder &child_binder, PivotRef &ref,
284
284
  vector<unique_ptr<ParsedExpression>> unnest_name_children;
285
285
  unnest_name_children.push_back(std::move(unpivot_name_expr));
286
286
  auto unnest_name_expr = make_unique<FunctionExpression>("unnest", std::move(unnest_name_children));
287
- unnest_name_expr->alias = unpivot.names[0];
287
+ unnest_name_expr->alias = unpivot.unpivot_names[0];
288
288
  select_node->select_list.push_back(std::move(unnest_name_expr));
289
289
 
290
290
  // construct the UNNEST expression for the set of unpivoted columns
@@ -0,0 +1,146 @@
1
+ #include "duckdb/planner/expression_binder/base_select_binder.hpp"
2
+
3
+ #include "duckdb/parser/expression/columnref_expression.hpp"
4
+ #include "duckdb/parser/expression/window_expression.hpp"
5
+ #include "duckdb/parser/parsed_expression_iterator.hpp"
6
+ #include "duckdb/planner/expression/bound_columnref_expression.hpp"
7
+ #include "duckdb/planner/expression/bound_window_expression.hpp"
8
+ #include "duckdb/planner/expression_binder/aggregate_binder.hpp"
9
+ #include "duckdb/planner/query_node/bound_select_node.hpp"
10
+ #include "duckdb/parser/expression/operator_expression.hpp"
11
+ #include "duckdb/common/string_util.hpp"
12
+ #include "duckdb/planner/binder.hpp"
13
+
14
+ namespace duckdb {
15
+
16
+ BaseSelectBinder::BaseSelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node,
17
+ BoundGroupInformation &info, case_insensitive_map_t<idx_t> alias_map)
18
+ : ExpressionBinder(binder, context), inside_window(false), node(node), info(info), alias_map(std::move(alias_map)) {
19
+ }
20
+
21
+ BaseSelectBinder::BaseSelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node,
22
+ BoundGroupInformation &info)
23
+ : BaseSelectBinder(binder, context, node, info, case_insensitive_map_t<idx_t>()) {
24
+ }
25
+
26
+ BindResult BaseSelectBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
27
+ auto &expr = **expr_ptr;
28
+ // check if the expression binds to one of the groups
29
+ auto group_index = TryBindGroup(expr, depth);
30
+ if (group_index != DConstants::INVALID_INDEX) {
31
+ return BindGroup(expr, depth, group_index);
32
+ }
33
+ switch (expr.expression_class) {
34
+ case ExpressionClass::COLUMN_REF:
35
+ return BindColumnRef(expr_ptr, depth);
36
+ case ExpressionClass::DEFAULT:
37
+ return BindResult("SELECT clause cannot contain DEFAULT clause");
38
+ case ExpressionClass::WINDOW:
39
+ return BindWindow((WindowExpression &)expr, depth);
40
+ default:
41
+ return ExpressionBinder::BindExpression(expr_ptr, depth, root_expression);
42
+ }
43
+ }
44
+
45
+ idx_t BaseSelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
46
+ // first check the group alias map, if expr is a ColumnRefExpression
47
+ if (expr.type == ExpressionType::COLUMN_REF) {
48
+ auto &colref = (ColumnRefExpression &)expr;
49
+ if (!colref.IsQualified()) {
50
+ auto alias_entry = info.alias_map.find(colref.column_names[0]);
51
+ if (alias_entry != info.alias_map.end()) {
52
+ // found entry!
53
+ return alias_entry->second;
54
+ }
55
+ }
56
+ }
57
+ // no alias reference found
58
+ // check the list of group columns for a match
59
+ auto entry = info.map.find(&expr);
60
+ if (entry != info.map.end()) {
61
+ return entry->second;
62
+ }
63
+ #ifdef DEBUG
64
+ for (auto entry : info.map) {
65
+ D_ASSERT(!entry.first->Equals(&expr));
66
+ D_ASSERT(!expr.Equals(entry.first));
67
+ }
68
+ #endif
69
+ return DConstants::INVALID_INDEX;
70
+ }
71
+
72
+ BindResult BaseSelectBinder::BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth) {
73
+ // first try to bind the column reference regularly
74
+ auto result = ExpressionBinder::BindExpression(expr_ptr, depth);
75
+ if (!result.HasError()) {
76
+ return result;
77
+ }
78
+ // binding failed
79
+ // check in the alias map
80
+ auto &colref = (ColumnRefExpression &)**expr_ptr;
81
+ if (!colref.IsQualified()) {
82
+ auto alias_entry = alias_map.find(colref.column_names[0]);
83
+ if (alias_entry != alias_map.end()) {
84
+ // found entry!
85
+ auto index = alias_entry->second;
86
+ if (index >= node.select_list.size()) {
87
+ throw BinderException("Column \"%s\" referenced that exists in the SELECT clause - but this column "
88
+ "cannot be referenced before it is defined",
89
+ colref.column_names[0]);
90
+ }
91
+ if (node.select_list[index]->HasSideEffects()) {
92
+ throw BinderException("Alias \"%s\" referenced in a SELECT clause - but the expression has side "
93
+ "effects. This is not yet supported.",
94
+ colref.column_names[0]);
95
+ }
96
+ if (node.select_list[index]->HasSubquery()) {
97
+ throw BinderException("Alias \"%s\" referenced in a SELECT clause - but the expression has a subquery."
98
+ " This is not yet supported.",
99
+ colref.column_names[0]);
100
+ }
101
+ auto result = BindResult(node.select_list[index]->Copy());
102
+ if (result.expression->type == ExpressionType::BOUND_COLUMN_REF) {
103
+ auto &result_expr = (BoundColumnRefExpression &)*result.expression;
104
+ result_expr.depth = depth;
105
+ }
106
+ return result;
107
+ }
108
+ }
109
+ // entry was not found in the alias map: return the original error
110
+ return result;
111
+ }
112
+
113
+ BindResult BaseSelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t depth) {
114
+ if (op.children.empty()) {
115
+ throw InternalException("GROUPING requires at least one child");
116
+ }
117
+ if (node.groups.group_expressions.empty()) {
118
+ return BindResult(binder.FormatError(op, "GROUPING statement cannot be used without groups"));
119
+ }
120
+ if (op.children.size() >= 64) {
121
+ return BindResult(binder.FormatError(op, "GROUPING statement cannot have more than 64 groups"));
122
+ }
123
+ vector<idx_t> group_indexes;
124
+ group_indexes.reserve(op.children.size());
125
+ for (auto &child : op.children) {
126
+ ExpressionBinder::QualifyColumnNames(binder, child);
127
+ auto idx = TryBindGroup(*child, depth);
128
+ if (idx == DConstants::INVALID_INDEX) {
129
+ return BindResult(binder.FormatError(
130
+ op, StringUtil::Format("GROUPING child \"%s\" must be a grouping column", child->GetName())));
131
+ }
132
+ group_indexes.push_back(idx);
133
+ }
134
+ auto col_idx = node.grouping_functions.size();
135
+ node.grouping_functions.push_back(std::move(group_indexes));
136
+ return BindResult(make_unique<BoundColumnRefExpression>(op.GetName(), LogicalType::BIGINT,
137
+ ColumnBinding(node.groupings_index, col_idx), depth));
138
+ }
139
+
140
+ BindResult BaseSelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t group_index) {
141
+ auto &group = node.groups.group_expressions[group_index];
142
+ return BindResult(make_unique<BoundColumnRefExpression>(expr.GetName(), group->return_type,
143
+ ColumnBinding(node.group_index, group_index), depth));
144
+ }
145
+
146
+ } // namespace duckdb
@@ -10,7 +10,7 @@ namespace duckdb {
10
10
 
11
11
  HavingBinder::HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
12
12
  case_insensitive_map_t<idx_t> &alias_map, AggregateHandling aggregate_handling)
13
- : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map),
13
+ : BaseSelectBinder(binder, context, node, info), column_alias_binder(node, alias_map),
14
14
  aggregate_handling(aggregate_handling) {
15
15
  target_type = LogicalType(LogicalTypeId::BOOLEAN);
16
16
  }
@@ -28,7 +28,7 @@ BindResult HavingBinder::BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, i
28
28
  if (depth > 0) {
29
29
  throw BinderException("Having clause cannot reference column in correlated subquery and group by all");
30
30
  }
31
- auto expr = duckdb::SelectBinder::BindExpression(expr_ptr, depth);
31
+ auto expr = duckdb::BaseSelectBinder::BindExpression(expr_ptr, depth);
32
32
  if (expr.HasError()) {
33
33
  return expr;
34
34
  }
@@ -54,7 +54,7 @@ BindResult HavingBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr,
54
54
  case ExpressionClass::COLUMN_REF:
55
55
  return BindColumnRef(expr_ptr, depth, root_expression);
56
56
  default:
57
- return duckdb::SelectBinder::BindExpression(expr_ptr, depth);
57
+ return duckdb::BaseSelectBinder::BindExpression(expr_ptr, depth);
58
58
  }
59
59
  }
60
60
 
@@ -10,13 +10,13 @@ namespace duckdb {
10
10
 
11
11
  QualifyBinder::QualifyBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
12
12
  case_insensitive_map_t<idx_t> &alias_map)
13
- : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) {
13
+ : BaseSelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) {
14
14
  target_type = LogicalType(LogicalTypeId::BOOLEAN);
15
15
  }
16
16
 
17
17
  BindResult QualifyBinder::BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
18
18
  auto &expr = (ColumnRefExpression &)**expr_ptr;
19
- auto result = duckdb::SelectBinder::BindExpression(expr_ptr, depth);
19
+ auto result = duckdb::BaseSelectBinder::BindExpression(expr_ptr, depth);
20
20
  if (!result.HasError()) {
21
21
  return result;
22
22
  }
@@ -43,7 +43,7 @@ BindResult QualifyBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr,
43
43
  case ExpressionClass::COLUMN_REF:
44
44
  return BindColumnRef(expr_ptr, depth, root_expression);
45
45
  default:
46
- return duckdb::SelectBinder::BindExpression(expr_ptr, depth);
46
+ return duckdb::BaseSelectBinder::BindExpression(expr_ptr, depth);
47
47
  }
48
48
  }
49
49
 
@@ -1,145 +1,14 @@
1
1
  #include "duckdb/planner/expression_binder/select_binder.hpp"
2
2
 
3
- #include "duckdb/parser/expression/columnref_expression.hpp"
4
- #include "duckdb/parser/expression/window_expression.hpp"
5
- #include "duckdb/parser/parsed_expression_iterator.hpp"
6
- #include "duckdb/planner/expression/bound_columnref_expression.hpp"
7
- #include "duckdb/planner/expression/bound_window_expression.hpp"
8
- #include "duckdb/planner/expression_binder/aggregate_binder.hpp"
9
- #include "duckdb/planner/query_node/bound_select_node.hpp"
10
- #include "duckdb/parser/expression/operator_expression.hpp"
11
- #include "duckdb/common/string_util.hpp"
12
- #include "duckdb/planner/binder.hpp"
13
-
14
3
  namespace duckdb {
15
4
 
16
5
  SelectBinder::SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info,
17
6
  case_insensitive_map_t<idx_t> alias_map)
18
- : ExpressionBinder(binder, context), inside_window(false), node(node), info(info), alias_map(std::move(alias_map)) {
7
+ : BaseSelectBinder(binder, context, node, info, std::move(alias_map)) {
19
8
  }
20
9
 
21
10
  SelectBinder::SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info)
22
11
  : SelectBinder(binder, context, node, info, case_insensitive_map_t<idx_t>()) {
23
12
  }
24
13
 
25
- BindResult SelectBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
26
- auto &expr = **expr_ptr;
27
- // check if the expression binds to one of the groups
28
- auto group_index = TryBindGroup(expr, depth);
29
- if (group_index != DConstants::INVALID_INDEX) {
30
- return BindGroup(expr, depth, group_index);
31
- }
32
- switch (expr.expression_class) {
33
- case ExpressionClass::COLUMN_REF:
34
- return BindColumnRef(expr_ptr, depth);
35
- case ExpressionClass::DEFAULT:
36
- return BindResult("SELECT clause cannot contain DEFAULT clause");
37
- case ExpressionClass::WINDOW:
38
- return BindWindow((WindowExpression &)expr, depth);
39
- default:
40
- return ExpressionBinder::BindExpression(expr_ptr, depth);
41
- }
42
- }
43
-
44
- idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
45
- // first check the group alias map, if expr is a ColumnRefExpression
46
- if (expr.type == ExpressionType::COLUMN_REF) {
47
- auto &colref = (ColumnRefExpression &)expr;
48
- if (!colref.IsQualified()) {
49
- auto alias_entry = info.alias_map.find(colref.column_names[0]);
50
- if (alias_entry != info.alias_map.end()) {
51
- // found entry!
52
- return alias_entry->second;
53
- }
54
- }
55
- }
56
- // no alias reference found
57
- // check the list of group columns for a match
58
- auto entry = info.map.find(&expr);
59
- if (entry != info.map.end()) {
60
- return entry->second;
61
- }
62
- #ifdef DEBUG
63
- for (auto entry : info.map) {
64
- D_ASSERT(!entry.first->Equals(&expr));
65
- D_ASSERT(!expr.Equals(entry.first));
66
- }
67
- #endif
68
- return DConstants::INVALID_INDEX;
69
- }
70
-
71
- BindResult SelectBinder::BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth) {
72
- // first try to bind the column reference regularly
73
- auto result = ExpressionBinder::BindExpression(expr_ptr, depth);
74
- if (!result.HasError()) {
75
- return result;
76
- }
77
- // binding failed
78
- // check in the alias map
79
- auto &colref = (ColumnRefExpression &)**expr_ptr;
80
- if (!colref.IsQualified()) {
81
- auto alias_entry = alias_map.find(colref.column_names[0]);
82
- if (alias_entry != alias_map.end()) {
83
- // found entry!
84
- auto index = alias_entry->second;
85
- if (index >= node.select_list.size()) {
86
- throw BinderException("Column \"%s\" referenced that exists in the SELECT clause - but this column "
87
- "cannot be referenced before it is defined",
88
- colref.column_names[0]);
89
- }
90
- if (node.select_list[index]->HasSideEffects()) {
91
- throw BinderException("Alias \"%s\" referenced in a SELECT clause - but the expression has side "
92
- "effects. This is not yet supported.",
93
- colref.column_names[0]);
94
- }
95
- if (node.select_list[index]->HasSubquery()) {
96
- throw BinderException("Alias \"%s\" referenced in a SELECT clause - but the expression has a subquery."
97
- " This is not yet supported.",
98
- colref.column_names[0]);
99
- }
100
- auto result = BindResult(node.select_list[index]->Copy());
101
- if (result.expression->type == ExpressionType::BOUND_COLUMN_REF) {
102
- auto &result_expr = (BoundColumnRefExpression &)*result.expression;
103
- result_expr.depth = depth;
104
- }
105
- return result;
106
- }
107
- }
108
- // entry was not found in the alias map: return the original error
109
- return result;
110
- }
111
-
112
- BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t depth) {
113
- if (op.children.empty()) {
114
- throw InternalException("GROUPING requires at least one child");
115
- }
116
- if (node.groups.group_expressions.empty()) {
117
- return BindResult(binder.FormatError(op, "GROUPING statement cannot be used without groups"));
118
- }
119
- if (op.children.size() >= 64) {
120
- return BindResult(binder.FormatError(op, "GROUPING statement cannot have more than 64 groups"));
121
- }
122
- vector<idx_t> group_indexes;
123
- group_indexes.reserve(op.children.size());
124
- for (auto &child : op.children) {
125
- ExpressionBinder::QualifyColumnNames(binder, child);
126
- auto idx = TryBindGroup(*child, depth);
127
- if (idx == DConstants::INVALID_INDEX) {
128
- return BindResult(binder.FormatError(
129
- op, StringUtil::Format("GROUPING child \"%s\" must be a grouping column", child->GetName())));
130
- }
131
- group_indexes.push_back(idx);
132
- }
133
- auto col_idx = node.grouping_functions.size();
134
- node.grouping_functions.push_back(std::move(group_indexes));
135
- return BindResult(make_unique<BoundColumnRefExpression>(op.GetName(), LogicalType::BIGINT,
136
- ColumnBinding(node.groupings_index, col_idx), depth));
137
- }
138
-
139
- BindResult SelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t group_index) {
140
- auto &group = node.groups.group_expressions[group_index];
141
- return BindResult(make_unique<BoundColumnRefExpression>(expr.GetName(), group->return_type,
142
- ColumnBinding(node.group_index, group_index), depth));
143
- }
144
-
145
14
  } // namespace duckdb
@@ -1,6 +1,7 @@
1
1
  #include "duckdb/planner/expression_binder.hpp"
2
2
 
3
3
  #include "duckdb/parser/expression/columnref_expression.hpp"
4
+ #include "duckdb/parser/expression/function_expression.hpp"
4
5
  #include "duckdb/parser/expression/positional_reference_expression.hpp"
5
6
  #include "duckdb/parser/expression/subquery_expression.hpp"
6
7
  #include "duckdb/parser/parsed_expression_iterator.hpp"
@@ -52,9 +53,15 @@ BindResult ExpressionBinder::BindExpression(unique_ptr<ParsedExpression> *expr,
52
53
  return BindExpression((ConjunctionExpression &)expr_ref, depth);
53
54
  case ExpressionClass::CONSTANT:
54
55
  return BindExpression((ConstantExpression &)expr_ref, depth);
55
- case ExpressionClass::FUNCTION:
56
+ case ExpressionClass::FUNCTION: {
57
+ auto &function = (FunctionExpression &)expr_ref;
58
+ if (function.function_name == "unnest" || function.function_name == "unlist") {
59
+ // special case, not in catalog
60
+ return BindUnnest(function, depth, root_expression);
61
+ }
56
62
  // binding function expression has extra parameter needed for macro's
57
- return BindExpression((FunctionExpression &)expr_ref, depth, expr);
63
+ return BindExpression(function, depth, expr);
64
+ }
58
65
  case ExpressionClass::LAMBDA:
59
66
  return BindExpression((LambdaExpression &)expr_ref, depth, false, LogicalTypeId::INVALID);
60
67
  case ExpressionClass::OPERATOR:
@@ -200,22 +200,24 @@ void ExpressionIterator::EnumerateQueryNodeChildren(BoundQueryNode &node,
200
200
  }
201
201
  case QueryNodeType::SELECT_NODE: {
202
202
  auto &bound_select = (BoundSelectNode &)node;
203
- for (idx_t i = 0; i < bound_select.select_list.size(); i++) {
204
- EnumerateExpression(bound_select.select_list[i], callback);
203
+ for (auto &expr : bound_select.select_list) {
204
+ EnumerateExpression(expr, callback);
205
205
  }
206
206
  EnumerateExpression(bound_select.where_clause, callback);
207
- for (idx_t i = 0; i < bound_select.groups.group_expressions.size(); i++) {
208
- EnumerateExpression(bound_select.groups.group_expressions[i], callback);
207
+ for (auto &expr : bound_select.groups.group_expressions) {
208
+ EnumerateExpression(expr, callback);
209
209
  }
210
210
  EnumerateExpression(bound_select.having, callback);
211
- for (idx_t i = 0; i < bound_select.aggregates.size(); i++) {
212
- EnumerateExpression(bound_select.aggregates[i], callback);
211
+ for (auto &expr : bound_select.aggregates) {
212
+ EnumerateExpression(expr, callback);
213
213
  }
214
- for (idx_t i = 0; i < bound_select.unnests.size(); i++) {
215
- EnumerateExpression(bound_select.unnests[i], callback);
214
+ for (auto &entry : bound_select.unnests) {
215
+ for (auto &expr : entry.second.expressions) {
216
+ EnumerateExpression(expr, callback);
217
+ }
216
218
  }
217
- for (idx_t i = 0; i < bound_select.windows.size(); i++) {
218
- EnumerateExpression(bound_select.windows[i], callback);
219
+ for (auto &expr : bound_select.windows) {
220
+ EnumerateExpression(expr, callback);
219
221
  }
220
222
  if (bound_select.from_table) {
221
223
  EnumerateTableRefChildren(*bound_select.from_table, callback);
@@ -1169,6 +1169,7 @@ typedef struct PGUpdateStmt {
1169
1169
  typedef struct PGPivot {
1170
1170
  PGNodeTag type;
1171
1171
  PGList *pivot_columns; /* The column names to pivot on */
1172
+ PGList *unpivot_columns;/* The column names to unpivot */
1172
1173
  PGList *pivot_value; /* The set of pivot values */
1173
1174
  char *pivot_enum; /* The enum to fetch the unique values from */
1174
1175
  } PGPivot;