1#include "duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp"
2#include "duckdb/parser/expression/function_expression.hpp"
3#include "duckdb/planner/expression/bound_aggregate_expression.hpp"
4#include "duckdb/planner/expression/bound_columnref_expression.hpp"
5#include "duckdb/planner/expression_binder/aggregate_binder.hpp"
6#include "duckdb/planner/expression_binder/select_binder.hpp"
7#include "duckdb/planner/query_node/bound_select_node.hpp"
8
9using namespace duckdb;
10using namespace std;
11
12BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFunctionCatalogEntry *func, idx_t depth) {
13 // first bind the child of the aggregate expression (if any)
14 this->bound_aggregate = true;
15
16 AggregateBinder aggregate_binder(binder, context);
17 string error;
18 for (idx_t i = 0; i < aggr.children.size(); i++) {
19 aggregate_binder.BindChild(aggr.children[i], 0, error);
20 }
21 if (!error.empty()) {
22 // failed to bind child
23 if (aggregate_binder.BoundColumns()) {
24 for (idx_t i = 0; i < aggr.children.size(); i++) {
25 // however, we bound columns!
26 // that means this aggregation belongs to this node
27 // check if we have to resolve any errors by binding with parent binders
28 bool success = aggregate_binder.BindCorrelatedColumns(aggr.children[i]);
29 // if there is still an error after this, we could not successfully bind the aggregate
30 if (!success) {
31 throw BinderException(error);
32 }
33 auto &bound_expr = (BoundExpression &)*aggr.children[i];
34 ExtractCorrelatedExpressions(binder, *bound_expr.expr);
35 }
36 } else {
37 // we didn't bind columns, try again in children
38 return BindResult(error);
39 }
40 }
41 // all children bound successfully
42 // extract the children and types
43 vector<SQLType> types;
44 vector<SQLType> arguments;
45 vector<unique_ptr<Expression>> children;
46 for (idx_t i = 0; i < aggr.children.size(); i++) {
47 auto &child = (BoundExpression &)*aggr.children[i];
48 types.push_back(child.sql_type);
49 arguments.push_back(child.sql_type);
50 children.push_back(move(child.expr));
51 }
52
53 // bind the aggregate
54 idx_t best_function = Function::BindFunction(func->name, func->functions, types);
55 // found a matching function!
56 auto &bound_function = func->functions[best_function];
57 // check if we need to add casts to the children
58 bound_function.CastToFunctionArguments(children, types);
59
60 // create the aggregate
61 auto aggregate = make_unique<BoundAggregateExpression>(GetInternalType(bound_function.return_type), bound_function,
62 aggr.distinct);
63 aggregate->children = move(children);
64 aggregate->arguments = arguments;
65
66 auto return_type = bound_function.return_type;
67
68 if (bound_function.bind) {
69 aggregate->bind_info = bound_function.bind(*aggregate, context, return_type);
70 }
71
72 // check for all the aggregates if this aggregate already exists
73 idx_t aggr_index;
74 auto entry = node.aggregate_map.find(aggregate.get());
75 if (entry == node.aggregate_map.end()) {
76 // new aggregate: insert into aggregate list
77 aggr_index = node.aggregates.size();
78 node.aggregate_map.insert(make_pair(aggregate.get(), aggr_index));
79 node.aggregates.push_back(move(aggregate));
80 } else {
81 // duplicate aggregate: simplify refer to this aggregate
82 aggr_index = entry->second;
83 }
84
85 // now create a column reference referring to the aggregate
86 auto colref = make_unique<BoundColumnRefExpression>(
87 aggr.alias.empty() ? node.aggregates[aggr_index]->ToString() : aggr.alias,
88 node.aggregates[aggr_index]->return_type, ColumnBinding(node.aggregate_index, aggr_index), depth);
89 // move the aggregate expression into the set of bound aggregates
90 return BindResult(move(colref), return_type);
91}
92