1#include "duckdb/execution/expression_executor.hpp"
2#include "duckdb/planner/expression/bound_function_expression.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7struct 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
18unique_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
27void 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