1 | #include "duckdb/execution/expression_executor.hpp" |
2 | #include "duckdb/planner/expression/bound_function_expression.hpp" |
3 | |
4 | using namespace duckdb; |
5 | using namespace std; |
6 | |
7 | struct FunctionState : public ExpressionState { |
8 | FunctionState(Expression &expr, ExpressionExecutorState &root) : ExpressionState(expr, root) { |
9 | auto &func = (BoundFunctionExpression &)expr; |
10 | for (auto &child : func.children) { |
11 | child_types.push_back(child->return_type); |
12 | } |
13 | } |
14 | |
15 | vector<TypeId> child_types; |
16 | }; |
17 | |
18 | unique_ptr<ExpressionState> ExpressionExecutor::InitializeState(BoundFunctionExpression &expr, |
19 | ExpressionExecutorState &root) { |
20 | auto result = make_unique<FunctionState>(expr, root); |
21 | for (auto &child : expr.children) { |
22 | result->AddChild(child.get()); |
23 | } |
24 | return move(result); |
25 | } |
26 | |
27 | void ExpressionExecutor::Execute(BoundFunctionExpression &expr, ExpressionState *state_, const SelectionVector *sel, |
28 | idx_t count, Vector &result) { |
29 | auto state = (FunctionState *)state_; |
30 | DataChunk arguments; |
31 | arguments.SetCardinality(count); |
32 | if (state->child_types.size() > 0) { |
33 | arguments.Initialize(state->child_types); |
34 | for (idx_t i = 0; i < expr.children.size(); i++) { |
35 | assert(state->child_types[i] == expr.children[i]->return_type); |
36 | Execute(*expr.children[i], state->child_states[i].get(), sel, count, arguments.data[i]); |
37 | #ifdef DEBUG |
38 | if (expr.arguments[i].id == SQLTypeId::VARCHAR) { |
39 | arguments.data[i].UTFVerify(count); |
40 | } |
41 | #endif |
42 | } |
43 | arguments.Verify(); |
44 | } |
45 | expr.function.function(arguments, *state, result); |
46 | if (result.type != expr.return_type) { |
47 | throw TypeMismatchException(expr.return_type, result.type, |
48 | "expected function to return the former " |
49 | "but the function returned the latter" ); |
50 | } |
51 | } |
52 | |